From 4a57c8f4f278ba8a1cbff0d372a91d663b6383f4 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 27 Feb 2024 19:37:41 -0800 Subject: [PATCH] adb: Do not use fs_config unless we are root (try 3). This enables fs_config for /data when pushing files as root. Also, without this, adb push to /tmp fails as the shell user. When pushing to a directory that does not have an explicit fs_config, such as /data/local/tmp or /tmp, use the original file mode. Because adb copies u permissions into g and o (and in general because the umask on the host may have made these files world writable), this requires adding more fs_config entries to cover directories that may contain dex files i.e. /{odm,product,system,system_ext,vendor}/{framework,app,priv-app} to avoid hitting a SecurityException caused by writable dex files, e.g. 04-01 21:22:16.980 10110 4815 4815 E AndroidRuntime: FATAL EXCEPTION: main 04-01 21:22:16.980 10110 4815 4815 E AndroidRuntime: Process: android.test.app.system_priv, PID: 4815 04-01 21:22:16.980 10110 4815 4815 E AndroidRuntime: java.lang.SecurityException: Writable dex file '/system/priv-app/loadlibrarytest_system_priv_app/loadlibrarytest_system_priv_app.apk' is not allowed. 04-01 21:22:16.980 10110 4815 4815 E AndroidRuntime: at dalvik.system.DexFile.openDexFileNative(Native Method) 04-01 21:22:16.980 10110 4815 4815 E AndroidRuntime: at dalvik.system.DexFile.openDexFile(DexFile.java:406) Bug: 171233429 Bug: 311263616 Change-Id: I18f70095c793d08a25ff59e1851f6dc7648ce4dc --- .../arm64/source-based/libcutils.so.lsdump | 64 +++++++++++++++++++ .../source-based/libcutils.so.lsdump | 64 +++++++++++++++++++ libcutils/fs_config.cpp | 60 +++++++++++++---- libcutils/include/private/fs_config.h | 33 +++++++--- 4 files changed, 197 insertions(+), 24 deletions(-) diff --git a/libcutils/abi-dumps/arm64/source-based/libcutils.so.lsdump b/libcutils/abi-dumps/arm64/source-based/libcutils.so.lsdump index 333e61c18..67c7514a6 100644 --- a/libcutils/abi-dumps/arm64/source-based/libcutils.so.lsdump +++ b/libcutils/abi-dumps/arm64/source-based/libcutils.so.lsdump @@ -289,6 +289,9 @@ { "name" : "fs_write_atomic_int" }, + { + "name" : "get_fs_config" + }, { "name" : "hashmapCreate" }, @@ -1273,6 +1276,27 @@ "return_type" : "_ZTIi", "source_file" : "system/core/libcutils/include/cutils/fs.h" }, + { + "function_name" : "get_fs_config", + "linker_set_key" : "get_fs_config", + "parameters" : + [ + { + "referenced_type" : "_ZTIPKc" + }, + { + "referenced_type" : "_ZTIb" + }, + { + "referenced_type" : "_ZTIPKc" + }, + { + "referenced_type" : "_ZTIP9fs_config" + } + ], + "return_type" : "_ZTIb", + "source_file" : "system/core/libcutils/include/private/fs_config.h" + }, { "function_name" : "hashmapCreate", "linker_set_key" : "hashmapCreate", @@ -2390,6 +2414,15 @@ "size" : 8, "source_file" : "system/core/libcutils/include/cutils/hashmap.h" }, + { + "alignment" : 8, + "linker_set_key" : "_ZTIP9fs_config", + "name" : "fs_config *", + "referenced_type" : "_ZTI9fs_config", + "self_type" : "_ZTIP9fs_config", + "size" : 8, + "source_file" : "system/core/libcutils/include/private/fs_config.h" + }, { "alignment" : 8, "linker_set_key" : "_ZTIP9str_parms", @@ -2684,6 +2717,37 @@ "self_type" : "_ZTI5cnode", "size" : 40, "source_file" : "system/core/libcutils/include/cutils/config_utils.h" + }, + { + "alignment" : 8, + "fields" : + [ + { + "field_name" : "uid", + "referenced_type" : "_ZTIj" + }, + { + "field_name" : "gid", + "field_offset" : 32, + "referenced_type" : "_ZTIj" + }, + { + "field_name" : "mode", + "field_offset" : 64, + "referenced_type" : "_ZTIj" + }, + { + "field_name" : "capabilities", + "field_offset" : 128, + "referenced_type" : "_ZTIm" + } + ], + "linker_set_key" : "_ZTI9fs_config", + "name" : "fs_config", + "referenced_type" : "_ZTI9fs_config", + "self_type" : "_ZTI9fs_config", + "size" : 24, + "source_file" : "system/core/libcutils/include/private/fs_config.h" } ], "rvalue_reference_types" : [] diff --git a/libcutils/abi-dumps/arm_arm64/source-based/libcutils.so.lsdump b/libcutils/abi-dumps/arm_arm64/source-based/libcutils.so.lsdump index f612fb942..f75240c04 100644 --- a/libcutils/abi-dumps/arm_arm64/source-based/libcutils.so.lsdump +++ b/libcutils/abi-dumps/arm_arm64/source-based/libcutils.so.lsdump @@ -299,6 +299,9 @@ { "name" : "fs_write_atomic_int" }, + { + "name" : "get_fs_config" + }, { "name" : "hashmapCreate" }, @@ -1283,6 +1286,27 @@ "return_type" : "_ZTIi", "source_file" : "system/core/libcutils/include/cutils/fs.h" }, + { + "function_name" : "get_fs_config", + "linker_set_key" : "get_fs_config", + "parameters" : + [ + { + "referenced_type" : "_ZTIPKc" + }, + { + "referenced_type" : "_ZTIb" + }, + { + "referenced_type" : "_ZTIPKc" + }, + { + "referenced_type" : "_ZTIP9fs_config" + } + ], + "return_type" : "_ZTIb", + "source_file" : "system/core/libcutils/include/private/fs_config.h" + }, { "function_name" : "hashmapCreate", "linker_set_key" : "hashmapCreate", @@ -2400,6 +2424,15 @@ "size" : 4, "source_file" : "system/core/libcutils/include/cutils/hashmap.h" }, + { + "alignment" : 4, + "linker_set_key" : "_ZTIP9fs_config", + "name" : "fs_config *", + "referenced_type" : "_ZTI9fs_config", + "self_type" : "_ZTIP9fs_config", + "size" : 4, + "source_file" : "system/core/libcutils/include/private/fs_config.h" + }, { "alignment" : 4, "linker_set_key" : "_ZTIP9str_parms", @@ -2694,6 +2727,37 @@ "self_type" : "_ZTI5cnode", "size" : 20, "source_file" : "system/core/libcutils/include/cutils/config_utils.h" + }, + { + "alignment" : 8, + "fields" : + [ + { + "field_name" : "uid", + "referenced_type" : "_ZTIj" + }, + { + "field_name" : "gid", + "field_offset" : 32, + "referenced_type" : "_ZTIj" + }, + { + "field_name" : "mode", + "field_offset" : 64, + "referenced_type" : "_ZTIt" + }, + { + "field_name" : "capabilities", + "field_offset" : 128, + "referenced_type" : "_ZTIy" + } + ], + "linker_set_key" : "_ZTI9fs_config", + "name" : "fs_config", + "referenced_type" : "_ZTI9fs_config", + "self_type" : "_ZTI9fs_config", + "size" : 24, + "source_file" : "system/core/libcutils/include/private/fs_config.h" } ], "rvalue_reference_types" : [] diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp index 919be2ff2..5efe2098b 100644 --- a/libcutils/fs_config.cpp +++ b/libcutils/fs_config.cpp @@ -91,7 +91,7 @@ static const struct fs_path_config android_dirs[] = { { 00751, AID_ROOT, AID_SHELL, 0, "vendor/bin" }, { 00751, AID_ROOT, AID_SHELL, 0, "vendor/apex/*/bin" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor" }, - { 00755, AID_ROOT, AID_ROOT, 0, 0 }, + {}, // clang-format on }; #ifndef __ANDROID_VNDK__ @@ -218,17 +218,32 @@ static const struct fs_path_config android_files[] = { { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, { 00750, AID_ROOT, AID_SHELL, 0, "init*" }, { 00755, AID_ROOT, AID_SHELL, 0, "odm/bin/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "odm/framework/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "odm/app/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "odm/priv-app/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "product/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "product/apex/*bin/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "product/framework/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "product/app/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "product/priv-app/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system/framework/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system/app/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system/priv-app/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/apex/*/bin/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system_ext/framework/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system_ext/app/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "system_ext/priv-app/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/apex/*bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" }, - { 00644, AID_ROOT, AID_ROOT, 0, 0 }, + { 00644, AID_ROOT, AID_ROOT, 0, "vendor/framework/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "vendor/app/*" }, + { 00644, AID_ROOT, AID_ROOT, 0, "vendor/priv-app/*" }, + {}, // clang-format on }; #ifndef __ANDROID_VNDK__ @@ -318,8 +333,8 @@ static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* auto __for_testing_only__fs_config_cmp = fs_config_cmp; #endif -void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, - unsigned* mode, uint64_t* capabilities) { +bool get_fs_config(const char* path, bool dir, const char* target_out_path, + struct fs_config* fs_conf) { const struct fs_path_config* pc; size_t which, plen; @@ -362,11 +377,11 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned* if (fs_config_cmp(dir, prefix, len, path, plen)) { free(prefix); close(fd); - *uid = header.uid; - *gid = header.gid; - *mode = (*mode & (~07777)) | header.mode; - *capabilities = header.capabilities; - return; + fs_conf->uid = header.uid; + fs_conf->gid = header.gid; + fs_conf->mode = header.mode; + fs_conf->capabilities = header.capabilities; + return true; } free(prefix); } @@ -375,11 +390,28 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned* for (pc = dir ? android_dirs : android_files; pc->prefix; pc++) { if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) { - break; + fs_conf->uid = pc->uid; + fs_conf->gid = pc->gid; + fs_conf->mode = pc->mode; + fs_conf->capabilities = pc->capabilities; + return true; } } - *uid = pc->uid; - *gid = pc->gid; - *mode = (*mode & (~07777)) | pc->mode; - *capabilities = pc->capabilities; + return false; +} + +void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, + unsigned* mode, uint64_t* capabilities) { + struct fs_config conf; + if (get_fs_config(path, dir, target_out_path, &conf)) { + *uid = conf.uid; + *gid = conf.gid; + *mode = (*mode & S_IFMT) | conf.mode; + *capabilities = conf.capabilities; + } else { + *uid = AID_ROOT; + *gid = AID_ROOT; + *mode = (*mode & S_IFMT) | (dir ? 0755 : 0644); + *capabilities = 0; + } } diff --git a/libcutils/include/private/fs_config.h b/libcutils/include/private/fs_config.h index 45f46e549..9a727bc58 100644 --- a/libcutils/include/private/fs_config.h +++ b/libcutils/include/private/fs_config.h @@ -21,8 +21,11 @@ #pragma once +#include +#include #include #include +#include #include @@ -30,17 +33,27 @@ __BEGIN_DECLS -/* - * Used in: - * build/tools/fs_config/fs_config.c - * build/tools/fs_get_stats/fs_get_stats.c - * system/extras/ext4_utils/make_ext4fs_main.c - * external/squashfs-tools/squashfs-tools/android.c - * system/core/cpio/mkbootfs.c - * system/core/adb/file_sync_service.cpp - * system/extras/ext4_utils/canned_fs_config.c - */ +/* This API is deprecated. New users should call get_fs_config. */ void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities); +struct fs_config { + uid_t uid; + gid_t gid; + mode_t mode; + uint64_t capabilities; +}; + +/* + * If a file system configuration was found for the specified path, store it to *conf. + * Returns whether a file system configuration was found. + * + * dir: Whether path refers to a directory. + * target_out_path: Path to the base directory to read the file system configuration from, or a null + * pointer to use the root directory as the base. Host code should pass $ANDROID_PRODUCT_OUT or + * equivalent, and device code should pass a null pointer. + */ +bool get_fs_config(const char* path, bool dir, const char* target_out_path, + struct fs_config* conf); + __END_DECLS