From 6e9cb8fd79ef5d933194eed02baf3af6394c500f Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 5 Apr 2017 12:15:49 -0700 Subject: [PATCH] libcutils: fs_config: target_out_path assumed /system breaking partitions Strip off trailing / then /system and then add back the appropriate config directory. This fixes an issue with reading vendor, oem or odm partitions. Test: manual build successfully interprets all etc/fs_config_* files. Test: manual incremental build successfully interprets all etc/fs_config_* files. Bug: 36071012 Change-Id: Iba363f0731bb8d15e595bb45c56db97722edabc2 --- libcutils/fs_config.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c index daa9ff545..5fc2386b7 100644 --- a/libcutils/fs_config.c +++ b/libcutils/fs_config.c @@ -227,21 +227,24 @@ static const struct fs_path_config android_files[] = { /* clang-format on */ }; +static size_t strip(const char* path, size_t len, const char suffix[]) { + if (len < strlen(suffix)) return len; + if (strncmp(path + len - strlen(suffix), suffix, strlen(suffix))) return len; + return len - strlen(suffix); +} + static int fs_config_open(int dir, int which, const char* target_out_path) { int fd = -1; 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 */ + * system partition but as we cannot guarantee it ends with '/system' + * or with or without a trailing slash, need to strip them carefully. */ char* name = NULL; - int target_out_path_len = strlen(target_out_path); - int skip_len = strlen("/system"); - - if (target_out_path[target_out_path_len] == '/') { - skip_len++; - } - if (asprintf(&name, "%s%s", target_out_path, conf[which][dir] + skip_len) != -1) { + size_t len = strlen(target_out_path); + len = strip(target_out_path, len, "/"); + len = strip(target_out_path, len, "/system"); + if (asprintf(&name, "%.*s%s", (int)len, target_out_path, conf[which][dir]) != -1) { fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY)); free(name); }