Loading cmds/installd/commands.cpp +25 −0 Original line number Original line Diff line number Diff line Loading @@ -1778,6 +1778,31 @@ int rm_package_dir(const char* apk_path) return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */); return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */); } } int link_file(const char* relative_path, const char* from_base, const char* to_base) { char from_path[PKG_PATH_MAX]; char to_path[PKG_PATH_MAX]; snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path); snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path); if (validate_apk_path_subdirs(from_path)) { ALOGE("invalid app data sub-path '%s' (bad prefix)\n", from_path); return -1; } if (validate_apk_path_subdirs(to_path)) { ALOGE("invalid app data sub-path '%s' (bad prefix)\n", to_path); return -1; } const int ret = link(from_path, to_path); if (ret < 0) { ALOGE("link(%s, %s) failed : %s", from_path, to_path, strerror(errno)); return -1; } return 0; } int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set) { const char *instruction_set) { char *file_name_start; char *file_name_start; Loading cmds/installd/installd.cpp +8 −1 Original line number Original line Diff line number Diff line Loading @@ -179,6 +179,12 @@ static int do_rm_package_dir(char **arg, char reply[REPLY_MAX] __unused) return rm_package_dir(arg[0]); return rm_package_dir(arg[0]); } } static int do_link_file(char **arg, char reply[REPLY_MAX] __unused) { /* relative_path, from_base, to_base */ return link_file(arg[0], arg[1], arg[2]); } struct cmdinfo { struct cmdinfo { const char *name; const char *name; unsigned numargs; unsigned numargs; Loading Loading @@ -210,6 +216,7 @@ struct cmdinfo cmds[] = { { "restorecondata", 4, do_restorecon_data }, { "restorecondata", 4, do_restorecon_data }, { "createoatdir", 2, do_create_oat_dir }, { "createoatdir", 2, do_create_oat_dir }, { "rmpackagedir", 1, do_rm_package_dir }, { "rmpackagedir", 1, do_rm_package_dir }, { "linkfile", 3, do_link_file } }; }; static int readx(int s, void *_buf, int count) static int readx(int s, void *_buf, int count) Loading cmds/installd/installd.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -203,6 +203,7 @@ int get_path_from_string(dir_rec_t* rec, const char* path); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int validate_apk_path(const char *path); int validate_apk_path(const char *path); int validate_apk_path_subdirs(const char *path); int append_and_increment(char** dst, const char* src, size_t* dst_size); int append_and_increment(char** dst, const char* src, size_t* dst_size); Loading Loading @@ -254,3 +255,4 @@ int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const const char *instruction_set); const char *instruction_set); int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set); const char *instruction_set); int link_file(const char *relative_path, const char *from_base, const char *to_base); cmds/installd/utils.cpp +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1043,15 +1043,13 @@ int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { } } /** /** * Check whether path points to a valid path for an APK file. Only one level of * Check whether path points to a valid path for an APK file. The path must * subdirectory names is allowed. Returns -1 when an invalid path is encountered * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within * and 0 when a valid path is encountered. * that path. Returns -1 when an invalid path is encountered and 0 when a valid path * is encountered. */ */ int validate_apk_path(const char *path) static int validate_apk_path_internal(const char *path, int maxSubdirs) { { const dir_rec_t* dir = NULL; const dir_rec_t* dir = NULL; int maxSubdirs = 1; if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { dir = &android_app_dir; dir = &android_app_dir; } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { Loading @@ -1060,7 +1058,9 @@ int validate_apk_path(const char *path) dir = &android_asec_dir; dir = &android_asec_dir; } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { dir = &android_mnt_expand_dir; dir = &android_mnt_expand_dir; if (maxSubdirs < 2) { maxSubdirs = 2; maxSubdirs = 2; } } else { } else { return -1; return -1; } } Loading @@ -1068,6 +1068,14 @@ int validate_apk_path(const char *path) return validate_path(dir, path, maxSubdirs); return validate_path(dir, path, maxSubdirs); } } int validate_apk_path(const char* path) { return validate_apk_path_internal(path, 1 /* maxSubdirs */); } int validate_apk_path_subdirs(const char* path) { return validate_apk_path_internal(path, 3 /* maxSubdirs */); } int append_and_increment(char** dst, const char* src, size_t* dst_size) { int append_and_increment(char** dst, const char* src, size_t* dst_size) { ssize_t ret = strlcpy(*dst, src, *dst_size); ssize_t ret = strlcpy(*dst, src, *dst_size); if (ret < 0 || (size_t) ret >= *dst_size) { if (ret < 0 || (size_t) ret >= *dst_size) { Loading Loading
cmds/installd/commands.cpp +25 −0 Original line number Original line Diff line number Diff line Loading @@ -1778,6 +1778,31 @@ int rm_package_dir(const char* apk_path) return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */); return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */); } } int link_file(const char* relative_path, const char* from_base, const char* to_base) { char from_path[PKG_PATH_MAX]; char to_path[PKG_PATH_MAX]; snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path); snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path); if (validate_apk_path_subdirs(from_path)) { ALOGE("invalid app data sub-path '%s' (bad prefix)\n", from_path); return -1; } if (validate_apk_path_subdirs(to_path)) { ALOGE("invalid app data sub-path '%s' (bad prefix)\n", to_path); return -1; } const int ret = link(from_path, to_path); if (ret < 0) { ALOGE("link(%s, %s) failed : %s", from_path, to_path, strerror(errno)); return -1; } return 0; } int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set) { const char *instruction_set) { char *file_name_start; char *file_name_start; Loading
cmds/installd/installd.cpp +8 −1 Original line number Original line Diff line number Diff line Loading @@ -179,6 +179,12 @@ static int do_rm_package_dir(char **arg, char reply[REPLY_MAX] __unused) return rm_package_dir(arg[0]); return rm_package_dir(arg[0]); } } static int do_link_file(char **arg, char reply[REPLY_MAX] __unused) { /* relative_path, from_base, to_base */ return link_file(arg[0], arg[1], arg[2]); } struct cmdinfo { struct cmdinfo { const char *name; const char *name; unsigned numargs; unsigned numargs; Loading Loading @@ -210,6 +216,7 @@ struct cmdinfo cmds[] = { { "restorecondata", 4, do_restorecon_data }, { "restorecondata", 4, do_restorecon_data }, { "createoatdir", 2, do_create_oat_dir }, { "createoatdir", 2, do_create_oat_dir }, { "rmpackagedir", 1, do_rm_package_dir }, { "rmpackagedir", 1, do_rm_package_dir }, { "linkfile", 3, do_link_file } }; }; static int readx(int s, void *_buf, int count) static int readx(int s, void *_buf, int count) Loading
cmds/installd/installd.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -203,6 +203,7 @@ int get_path_from_string(dir_rec_t* rec, const char* path); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int validate_apk_path(const char *path); int validate_apk_path(const char *path); int validate_apk_path_subdirs(const char *path); int append_and_increment(char** dst, const char* src, size_t* dst_size); int append_and_increment(char** dst, const char* src, size_t* dst_size); Loading Loading @@ -254,3 +255,4 @@ int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const const char *instruction_set); const char *instruction_set); int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set); const char *instruction_set); int link_file(const char *relative_path, const char *from_base, const char *to_base);
cmds/installd/utils.cpp +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1043,15 +1043,13 @@ int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { } } /** /** * Check whether path points to a valid path for an APK file. Only one level of * Check whether path points to a valid path for an APK file. The path must * subdirectory names is allowed. Returns -1 when an invalid path is encountered * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within * and 0 when a valid path is encountered. * that path. Returns -1 when an invalid path is encountered and 0 when a valid path * is encountered. */ */ int validate_apk_path(const char *path) static int validate_apk_path_internal(const char *path, int maxSubdirs) { { const dir_rec_t* dir = NULL; const dir_rec_t* dir = NULL; int maxSubdirs = 1; if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { dir = &android_app_dir; dir = &android_app_dir; } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { Loading @@ -1060,7 +1058,9 @@ int validate_apk_path(const char *path) dir = &android_asec_dir; dir = &android_asec_dir; } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { dir = &android_mnt_expand_dir; dir = &android_mnt_expand_dir; if (maxSubdirs < 2) { maxSubdirs = 2; maxSubdirs = 2; } } else { } else { return -1; return -1; } } Loading @@ -1068,6 +1068,14 @@ int validate_apk_path(const char *path) return validate_path(dir, path, maxSubdirs); return validate_path(dir, path, maxSubdirs); } } int validate_apk_path(const char* path) { return validate_apk_path_internal(path, 1 /* maxSubdirs */); } int validate_apk_path_subdirs(const char* path) { return validate_apk_path_internal(path, 3 /* maxSubdirs */); } int append_and_increment(char** dst, const char* src, size_t* dst_size) { int append_and_increment(char** dst, const char* src, size_t* dst_size) { ssize_t ret = strlcpy(*dst, src, *dst_size); ssize_t ret = strlcpy(*dst, src, *dst_size); if (ret < 0 || (size_t) ret >= *dst_size) { if (ret < 0 || (size_t) ret >= *dst_size) { Loading