diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c index edf1feeac..7a2301d0c 100644 --- a/libcutils/fs_config.c +++ b/libcutils/fs_config.c @@ -72,35 +72,35 @@ static inline uint64_t get8LE(const uint8_t* src) { static const struct fs_path_config android_dirs[] = { /* clang-format off */ - { 00770, AID_SYSTEM, AID_CACHE, 0, "cache" }, - { 00500, AID_ROOT, AID_ROOT, 0, "config" }, - { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" }, - { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" }, - { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral" }, - { 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" }, - { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" }, - { 00771, AID_SHELL, AID_SHELL, 0, "data/local/tmp" }, - { 00771, AID_SHELL, AID_SHELL, 0, "data/local" }, - { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" }, - { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" }, + { 00770, AID_SYSTEM, AID_CACHE, 0, "cache" }, + { 00500, AID_ROOT, AID_ROOT, 0, "config" }, + { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" }, + { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" }, + { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral" }, + { 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" }, + { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" }, + { 00771, AID_SHELL, AID_SHELL, 0, "data/local/tmp" }, + { 00771, AID_SHELL, AID_SHELL, 0, "data/local" }, + { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" }, { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" }, - { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" }, - { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" }, - { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" }, - { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" }, - { 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" }, - { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" }, - { 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" }, - { 00755, AID_ROOT, AID_ROOT, 0, "root" }, - { 00750, AID_ROOT, AID_SHELL, 0, "sbin" }, - { 00751, AID_ROOT, AID_SDCARD_R, 0, "storage" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/bin" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin" }, - { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" }, - { 00755, AID_ROOT, AID_SHELL, 0, "vendor" }, - { 00777, AID_ROOT, AID_ROOT, 0, "sdcard" }, - { 00755, AID_ROOT, AID_ROOT, 0, 0 }, + { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" }, + { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" }, + { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" }, + { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" }, + { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" }, + { 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" }, + { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" }, + { 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" }, + { 00755, AID_ROOT, AID_ROOT, 0, "root" }, + { 00750, AID_ROOT, AID_SHELL, 0, "sbin" }, + { 00777, AID_ROOT, AID_ROOT, 0, "sdcard" }, + { 00751, AID_ROOT, AID_SDCARD_R, 0, "storage" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/bin" }, + { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin" }, + { 00755, AID_ROOT, AID_SHELL, 0, "vendor" }, + { 00755, AID_ROOT, AID_ROOT, 0, 0 }, /* clang-format on */ }; @@ -110,36 +110,65 @@ static const struct fs_path_config android_dirs[] = { ** way up to the root. Prefixes ending in * denotes wildcard ** and will allow partial matches. */ -static const char conf_dir[] = "/system/etc/fs_config_dirs"; -static const char conf_file[] = "/system/etc/fs_config_files"; +static const char sys_conf_dir[] = "/system/etc/fs_config_dirs"; +static const char sys_conf_file[] = "/system/etc/fs_config_files"; +/* No restrictions are placed on the vendor file-system config files, + * although the developer is advised to restrict the scope to the /vendor + * file-system since the intent is to provide support for customized + * portions of a separate vendor.img. Has to remain open so that + * customization can also land on /system/vendor. We expect build-time + * checking or filtering when constructing /vendor/etc/fs_config_* files. + */ +static const char ven_conf_dir[] = "/vendor/etc/fs_config_dirs"; +static const char ven_conf_file[] = "/vendor/etc/fs_config_files"; +static const char* conf[][2] = { + {sys_conf_file, sys_conf_dir}, {ven_conf_file, ven_conf_dir}, +}; static const struct fs_path_config android_files[] = { /* clang-format off */ + { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" }, + { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" }, + { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" }, + { 00644, AID_APP, AID_APP, 0, "data/data/*" }, + { 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" }, + { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest/tests.txt" }, + { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" }, + { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" }, + { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" }, + { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, + { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, + { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" }, + { 00750, AID_ROOT, AID_SHELL, 0, "sbin/fs_mgr" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump32" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump64" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/debuggerd" }, + { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" }, + { 00700, AID_ROOT, AID_ROOT, 0, "system/bin/secilc" }, + { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" }, + { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" }, + { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_dir + 1 }, + { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_file + 1 }, { 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" }, { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" }, { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.ril" }, { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" }, { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" }, { 00440, AID_ROOT, AID_ROOT, 0, "system/etc/recovery.img" }, - { 00444, AID_ROOT, AID_ROOT, 0, conf_dir + 1 }, - { 00444, AID_ROOT, AID_ROOT, 0, conf_file + 1 }, - { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" }, - { 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" }, - { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" }, - { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" }, - { 00644, AID_APP, AID_APP, 0, "data/data/*" }, - { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest/tests.txt" }, - { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" }, - { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" }, - { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" }, + { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" }, + { 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" }, + { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_dir + 1 }, + { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_file + 1 }, /* the following two files are INTENTIONALLY set-uid, but they * are NOT included on user builds. */ - { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" }, { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" }, + { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" }, /* the following files have enhanced capabilities and ARE included * in user builds. */ + { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND), + "system/bin/inputflinger" }, { 00550, AID_LOGD, AID_LOGD, CAP_MASK_LONG(CAP_SYSLOG) | CAP_MASK_LONG(CAP_AUDIT_CONTROL) | CAP_MASK_LONG(CAP_SETGID), @@ -147,26 +176,25 @@ static const struct fs_path_config android_files[] = { { 00750, AID_ROOT, AID_SHELL, CAP_MASK_LONG(CAP_SETUID) | CAP_MASK_LONG(CAP_SETGID), "system/bin/run-as" }, - { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND), - "system/bin/inputflinger" }, /* Support FIFO scheduling mode in SurfaceFlinger. */ - { 00755, AID_SYSTEM, AID_GRAPHICS, CAP_MASK_LONG(CAP_SYS_NICE), "system/bin/surfaceflinger" }, + { 00755, AID_SYSTEM, AID_GRAPHICS, CAP_MASK_LONG(CAP_SYS_NICE), + "system/bin/surfaceflinger" }, /* Support hostapd administering a network interface. */ { 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/hostapd" }, + /* Support Bluetooth legacy hal accessing /sys/class/rfkill */ + { 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN), + "vendor/bin/hw/android.hardware.bluetooth@1.0-service" }, + /* Support wifi_hal_legacy administering a network interface. */ { 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "vendor/bin/hw/android.hardware.wifi@1.0-service" }, - /* Support Bluetooth legacy hal accessing /sys/class/rfkill */ - { 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN), - "vendor/bin/hw/android.hardware.bluetooth@1.0-service" }, - /* A non-privileged zygote that spawns * isolated processes for web rendering. */ { 0750, AID_ROOT, AID_ROOT, CAP_MASK_LONG(CAP_SETUID) | @@ -178,36 +206,24 @@ static const struct fs_path_config android_files[] = { CAP_MASK_LONG(CAP_SETPCAP), "system/bin/webview_zygote64" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump32" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump64" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/debuggerd" }, - { 00700, AID_ROOT, AID_ROOT, 0, "system/bin/secilc" }, - { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" }, - { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" }, + /* generic defaults */ + { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" }, + { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, + { 00750, AID_ROOT, AID_SHELL, 0, "init*" }, + { 00750, AID_ROOT, AID_SHELL, 0, "sbin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" }, { 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" }, { 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" }, - { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor/xbin/*" }, + { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" }, - { 00750, AID_ROOT, AID_SHELL, 0, "sbin/*" }, - { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" }, - { 00750, AID_ROOT, AID_SHELL, 0, "init*" }, - { 00750, AID_ROOT, AID_SHELL, 0, "sbin/fs_mgr" }, - { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, - { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" }, - { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" }, - { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, - { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, - { 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" }, - { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" }, { 00644, AID_ROOT, AID_ROOT, 0, 0 }, /* clang-format on */ }; -static int fs_config_open(int dir, const char* target_out_path) { +static int fs_config_open(int dir, int which, const char* target_out_path) { int fd = -1; if (target_out_path && *target_out_path) { @@ -221,13 +237,13 @@ static int fs_config_open(int dir, const char* target_out_path) { if (target_out_path[target_out_path_len] == '/') { skip_len++; } - if (asprintf(&name, "%s%s", target_out_path, (dir ? conf_dir : conf_file) + skip_len) != -1) { + if (asprintf(&name, "%s%s", target_out_path, conf[which][dir] + skip_len) != -1) { fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY)); free(name); } } if (fd < 0) { - fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY | O_BINARY)); + fd = TEMP_FAILURE_RETRY(open(conf[which][dir], O_RDONLY | O_BINARY)); } return fd; } @@ -252,8 +268,7 @@ static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) { const struct fs_path_config* pc; - size_t plen; - int fd; + size_t which, plen; if (path[0] == '/') { path++; @@ -261,32 +276,34 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned* plen = strlen(path); - fd = fs_config_open(dir, target_out_path); - if (fd >= 0) { + for (which = 0; which < (sizeof(conf) / sizeof(conf[0])); ++which) { struct fs_path_config_from_file header; + int fd = fs_config_open(dir, which, target_out_path); + if (fd < 0) continue; + while (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) == sizeof(header)) { char* prefix; uint16_t host_len = get2LE((const uint8_t*)&header.len); ssize_t len, remainder = host_len - sizeof(header); if (remainder <= 0) { - ALOGE("%s len is corrupted", dir ? conf_dir : conf_file); + ALOGE("%s len is corrupted", conf[which][dir]); break; } prefix = calloc(1, remainder); if (!prefix) { - ALOGE("%s out of memory", dir ? conf_dir : conf_file); + ALOGE("%s out of memory", conf[which][dir]); break; } if (TEMP_FAILURE_RETRY(read(fd, prefix, remainder)) != remainder) { free(prefix); - ALOGE("%s prefix is truncated", dir ? conf_dir : conf_file); + ALOGE("%s prefix is truncated", conf[which][dir]); break; } len = strnlen(prefix, remainder); if (len >= remainder) { /* missing a terminating null */ free(prefix); - ALOGE("%s is corrupted", dir ? conf_dir : conf_file); + ALOGE("%s is corrupted", conf[which][dir]); break; } if (fs_config_cmp(dir, prefix, len, path, plen)) {