From 3fd58ae7e57344ff4c1671c1f12dbc7094171538 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Wed, 3 Jun 2015 12:33:07 +0100 Subject: [PATCH 1/2] fs_mgr: Use ro.boot.veritymode If verity state is managed by bootloader, it will pass the verity mode to the kernel in the androidboot.veritymode command line parameter. Init copies the value to the ro.boot.veritymode property. Check for ro.boot.veritymode in fs_mgr and use the value to set dm-verity mode. If this property is not set, store verity state in metadata as before, if a storage location is specified in fstab. Bug: 21605676 Change-Id: Ife3c978c133248432c302583d3b70e179605fe42 (cherry picked from commit ac5c1224cfc959b96f7a34068a807db9aaab9358) --- fs_mgr/fs_mgr_verity.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c index cc8c57e40..2d1abbea5 100644 --- a/fs_mgr/fs_mgr_verity.c +++ b/fs_mgr/fs_mgr_verity.c @@ -767,8 +767,24 @@ static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset) static int load_verity_state(struct fstab_rec *fstab, int *mode) { - off64_t offset = 0; + char propbuf[PROPERTY_VALUE_MAX]; int match = 0; + off64_t offset = 0; + + /* use the kernel parameter if set */ + property_get("ro.boot.veritymode", propbuf, ""); + + if (*propbuf != '\0') { + if (!strcmp(propbuf, "enforcing")) { + *mode = VERITY_MODE_DEFAULT; + return 0; + } else if (!strcmp(propbuf, "logging")) { + *mode = VERITY_MODE_LOGGING; + return 0; + } else { + INFO("Unknown value %s for veritymode; ignoring", propbuf); + } + } if (get_verity_state_offset(fstab, &offset) < 0) { /* fall back to stateless behavior */ @@ -855,6 +871,13 @@ int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) struct dm_ioctl *io = (struct dm_ioctl *) buffer; struct fstab *fstab = NULL; + /* check if we need to store the state */ + property_get("ro.boot.veritymode", propbuf, ""); + + if (*propbuf != '\0') { + return 0; /* state is kept by the bootloader */ + } + fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC)); if (fd == -1) { From df33ffadd29ed02d87e87515626b673eac67f735 Mon Sep 17 00:00:00 2001 From: Thierry Strudel Date: Thu, 9 Jul 2015 09:50:31 -0700 Subject: [PATCH 2/2] fs_config: replace getenv('OUT') by new fs_config parameter Using a getenv('OUT') in such a deep down function is a wrong design choice. Replacing with explicit parameter that may be NULL in case device specific files can be accessed from /. Since TARGET_COPY_OUT_SYSTEM may be defined to something different than system we also ensure that we use a path relative to TARGET_OUT to compute path to fs_config_* files. Bug: 21989305 Bug: 22048934 Change-Id: Id91bc183b29beac7379d1117ad83bd3346e6897b Signed-off-by: Thierry Strudel --- adb/file_sync_service.cpp | 4 ++-- cpio/mkbootfs.c | 10 +++++++++- fs_mgr/fs_mgr_format.c | 2 +- include/private/android_filesystem_config.h | 4 ++-- libcutils/fs_config.c | 19 +++++++++++++------ 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp index e8e9a0f4d..5d17335d6 100644 --- a/adb/file_sync_service.cpp +++ b/adb/file_sync_service.cpp @@ -57,7 +57,7 @@ static int mkdirs(char *name) if(x == 0) return 0; *x = 0; if (should_use_fs_config(name)) { - fs_config(name, 1, &uid, &gid, &mode, &cap); + fs_config(name, 1, NULL, &uid, &gid, &mode, &cap); } ret = adb_mkdir(name, mode); if((ret < 0) && (errno != EEXIST)) { @@ -366,7 +366,7 @@ static int do_send(int s, char *path, char *buffer) tmp++; } if (should_use_fs_config(path)) { - fs_config(tmp, 0, &uid, &gid, &mode, &cap); + fs_config(tmp, 0, NULL, &uid, &gid, &mode, &cap); } return handle_send_file(s, path, uid, gid, mode, buffer, do_unlink); } diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c index 7175749b1..0e3532304 100644 --- a/cpio/mkbootfs.c +++ b/cpio/mkbootfs.c @@ -41,6 +41,7 @@ struct fs_config_entry { }; static struct fs_config_entry* canned_config = NULL; +static char *target_out_path = NULL; /* Each line in the canned file should be a path plus three ints (uid, * gid, mode). */ @@ -79,7 +80,8 @@ static void fix_stat(const char *path, struct stat *s) } else { // Use the compiled-in fs_config() function. unsigned st_mode = s->st_mode; - fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &st_mode, &capabilities); + fs_config(path, S_ISDIR(s->st_mode), target_out_path, + &s->st_uid, &s->st_gid, &st_mode, &capabilities); s->st_mode = (typeof(s->st_mode)) st_mode; } } @@ -328,6 +330,12 @@ int main(int argc, char *argv[]) argc--; argv++; + if (argc > 1 && strcmp(argv[0], "-d") == 0) { + target_out_path = argv[1]; + argc -= 2; + argv += 2; + } + if (argc > 1 && strcmp(argv[0], "-f") == 0) { read_canned_config(argv[1]); argc -= 2; diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c index 95c6a747e..c73045d44 100644 --- a/fs_mgr/fs_mgr_format.c +++ b/fs_mgr/fs_mgr_format.c @@ -52,7 +52,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point) info.len = ((off64_t)nr_sec * 512); /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */ - rc = make_ext4fs_internal(fd, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); + rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); if (rc) { ERROR("make_ext4fs returned %d.\n", rc); } diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h index 02fe2b5fb..2ed27dcac 100644 --- a/include/private/android_filesystem_config.h +++ b/include/private/android_filesystem_config.h @@ -206,13 +206,13 @@ __BEGIN_DECLS * Used in: * build/tools/fs_config/fs_config.c * build/tools/fs_get_stats/fs_get_stats.c - * external/genext2fs/genext2fs.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 */ -void fs_config(const char *path, int dir, +void fs_config(const char *path, int dir, const char *target_out_path, unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities); ssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc); diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c index 9f8023e4f..9a1ad1925 100644 --- a/libcutils/fs_config.c +++ b/libcutils/fs_config.c @@ -149,14 +149,21 @@ static const struct fs_path_config android_files[] = { { 00644, AID_ROOT, AID_ROOT, 0, 0 }, }; -static int fs_config_open(int dir) +static int fs_config_open(int dir, const char *target_out_path) { int fd = -1; - const char *out = getenv("OUT"); - if (out && *out) { + if (target_out_path && *target_out_path) { + /* target_out_path is the path to the directory holding content of system partition + but as we cannot guaranty it ends with '/system' we need this below skip_len logic */ char *name = NULL; - asprintf(&name, "%s%s", out, dir ? conf_dir : conf_file); + int target_out_path_len = strlen(target_out_path); + int skip_len = strlen("/system"); + + if (target_out_path[target_out_path_len] == '/') { + skip_len++; + } + asprintf(&name, "%s%s", target_out_path, (dir ? conf_dir : conf_file) + skip_len); if (name) { fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY)); free(name); @@ -187,7 +194,7 @@ static bool fs_config_cmp(bool dir, const char *prefix, size_t len, return !strncmp(prefix, path, len); } -void fs_config(const char *path, int dir, +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; @@ -199,7 +206,7 @@ void fs_config(const char *path, int dir, plen = strlen(path); - fd = fs_config_open(dir); + fd = fs_config_open(dir, target_out_path); if (fd >= 0) { struct fs_path_config_from_file header;