diff options
author | 2017-09-21 14:51:09 -0600 | |
---|---|---|
committer | 2017-10-31 14:51:58 -0700 | |
commit | c1149c9797e42f10c82cdcc8d1e69861e0114c02 (patch) | |
tree | 88dbad350a989002ee872c13c47b7876e5d73eba | |
parent | e2cff6afae7c6777dfbd0714ec805cb6dd20cf90 (diff) |
Enable clang-tidy for sensitive domain.
Since installd has broad access to lots of sensitive data, enable
as many security-related tidy checks as possible to help avoid bugs.
This change provides a default implementation of create_cache_path(),
calculate_odex_file_path(), and calculate_oat_file_path(), along
with tests to verify behavior against old code.
Replace "dir_rec_t" with std::string, since that's really what it's
been all along. Increase paranoia of path checking to reject any
paths containing "..", regardless of where it occurs in path string.
Stricter checking of instruction set values.
Remove now-unused char* manipulation utility methods; people should
be using std::string instead.
(cherry picked from commit 1b9d9a6006f4159e2cc2c41330f316b1fdc53fe1)
Test: adb shell /data/nativetest/installd_cache_test/installd_cache_test
Test: adb shell /data/nativetest/installd_service_test/installd_service_test
Test: adb shell /data/nativetest/installd_utils_test/installd_utils_test
Bug: 36655947
Merged-In: Ib706f0b8c1878be64710c00f56dccdfbe215570f
Change-Id: Ib706f0b8c1878be64710c00f56dccdfbe215570f
-rw-r--r-- | cmds/installd/Android.bp | 12 | ||||
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 2 | ||||
-rw-r--r-- | cmds/installd/dexopt.cpp | 120 | ||||
-rw-r--r-- | cmds/installd/dexopt.h | 11 | ||||
-rw-r--r-- | cmds/installd/globals.cpp | 134 | ||||
-rw-r--r-- | cmds/installd/globals.h | 39 | ||||
-rw-r--r-- | cmds/installd/installd.cpp | 138 | ||||
-rw-r--r-- | cmds/installd/otapreopt.cpp | 4 | ||||
-rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 52 | ||||
-rw-r--r-- | cmds/installd/tests/installd_utils_test.cpp | 212 | ||||
-rw-r--r-- | cmds/installd/utils.cpp | 242 | ||||
-rw-r--r-- | cmds/installd/utils.h | 23 |
12 files changed, 288 insertions, 701 deletions
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp index 33db6db60c..56470d6764 100644 --- a/cmds/installd/Android.bp +++ b/cmds/installd/Android.bp @@ -4,6 +4,7 @@ cc_defaults { cflags: [ "-Wall", "-Werror", + "-Wextra", ], srcs: [ "CacheItem.cpp", @@ -25,6 +26,17 @@ cc_defaults { ], clang: true, + + tidy: true, + tidy_checks: [ + "-*", + "clang-analyzer-security*", + "cert-*", + "-cert-err58-cpp", + ], + tidy_flags: [ + "-warnings-as-errors=clang-analyzer-security*,cert-*" + ], } // diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 7a397d1389..4246536580 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -1869,7 +1869,7 @@ binder::Status InstalldNativeService::markBootComplete(const std::string& instru char boot_marker_path[PKG_PATH_MAX]; sprintf(boot_marker_path, "%s/%s/%s/.booting", - android_data_dir.path, + android_data_dir.c_str(), DALVIK_CACHE, instruction_set); diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index 6f7ab6b52f..6a7d84580d 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -41,6 +41,7 @@ #include <system/thread_defs.h> #include "dexopt.h" +#include "globals.h" #include "installd_deps.h" #include "otapreopt_utils.h" #include "utils.h" @@ -156,7 +157,7 @@ static int split_count(const char *str) int count = 0; char buf[kPropertyValueMax]; - strncpy(buf, str, sizeof(buf)); + strlcpy(buf, str, sizeof(buf)); char *pBuf = buf; while(strtok_r(pBuf, " ", &ctx) != NULL) { @@ -333,7 +334,8 @@ static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vd bool have_dex2oat_compiler_filter_flag = false; if (skip_compilation) { - strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=extract"); + strlcpy(dex2oat_compiler_filter_arg, "--compiler-filter=extract", + sizeof(dex2oat_compiler_filter_arg)); have_dex2oat_compiler_filter_flag = true; have_dex2oat_relocation_skip_flag = true; } else if (compiler_filter != nullptr) { @@ -955,14 +957,6 @@ static std::string create_vdex_filename(const std::string& oat_path) { return replace_file_extension(oat_path, ".vdex"); } -static bool add_extension_to_file_name(char* file_name, const char* extension) { - if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) { - return false; - } - strcat(file_name, extension); - return true; -} - static int open_output_file(const char* file_name, bool recreate, int permissions) { int flags = O_RDWR | O_CREAT; if (recreate) { @@ -1198,21 +1192,16 @@ unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) { if (!ShouldUseSwapFileForDexopt()) { return invalid_unique_fd(); } - // Make sure there really is enough space. - char swap_file_name[PKG_PATH_MAX]; - strcpy(swap_file_name, out_oat_path); - if (!add_extension_to_file_name(swap_file_name, ".swap")) { - return invalid_unique_fd(); - } + auto swap_file_name = std::string(out_oat_path) + ".swap"; unique_fd swap_fd(open_output_file( - swap_file_name, /*recreate*/true, /*permissions*/0600)); + swap_file_name.c_str(), /*recreate*/true, /*permissions*/0600)); if (swap_fd.get() < 0) { // Could not create swap file. Optimistically go on and hope that we can compile // without it. - ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name); + ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name.c_str()); } else { // Immediately unlink. We don't really want to hit flash. - if (unlink(swap_file_name) < 0) { + if (unlink(swap_file_name.c_str()) < 0) { PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name; } } @@ -2040,5 +2029,98 @@ bool delete_odex(const char* apk_path, const char* instruction_set, const char* return return_value_oat && return_value_art && return_value_vdex; } +static bool is_absolute_path(const std::string& path) { + if (path.find('/') != 0 || path.find("..") != std::string::npos) { + LOG(ERROR) << "Invalid absolute path " << path; + return false; + } else { + return true; + } +} + +static bool is_valid_instruction_set(const std::string& instruction_set) { + // TODO: add explicit whitelisting of instruction sets + if (instruction_set.find('/') != std::string::npos) { + LOG(ERROR) << "Invalid instruction set " << instruction_set; + return false; + } else { + return true; + } +} + +bool calculate_oat_file_path_default(char path[PKG_PATH_MAX], const char *oat_dir, + const char *apk_path, const char *instruction_set) { + std::string oat_dir_ = oat_dir; + std::string apk_path_ = apk_path; + std::string instruction_set_ = instruction_set; + + if (!is_absolute_path(oat_dir_)) return false; + if (!is_absolute_path(apk_path_)) return false; + if (!is_valid_instruction_set(instruction_set_)) return false; + + std::string::size_type end = apk_path_.rfind('.'); + std::string::size_type start = apk_path_.rfind('/', end); + if (end == std::string::npos || start == std::string::npos) { + LOG(ERROR) << "Invalid apk_path " << apk_path_; + return false; + } + + std::string res_ = oat_dir_ + '/' + instruction_set + '/' + + apk_path_.substr(start + 1, end - start - 1) + ".odex"; + const char* res = res_.c_str(); + if (strlen(res) >= PKG_PATH_MAX) { + LOG(ERROR) << "Result too large"; + return false; + } else { + strlcpy(path, res, PKG_PATH_MAX); + return true; + } +} + +bool calculate_odex_file_path_default(char path[PKG_PATH_MAX], const char *apk_path, + const char *instruction_set) { + std::string apk_path_ = apk_path; + std::string instruction_set_ = instruction_set; + + if (!is_absolute_path(apk_path_)) return false; + if (!is_valid_instruction_set(instruction_set_)) return false; + + std::string::size_type end = apk_path_.rfind('.'); + std::string::size_type start = apk_path_.rfind('/', end); + if (end == std::string::npos || start == std::string::npos) { + LOG(ERROR) << "Invalid apk_path " << apk_path_; + return false; + } + + std::string oat_dir = apk_path_.substr(0, start + 1) + "oat"; + return calculate_oat_file_path_default(path, oat_dir.c_str(), apk_path, instruction_set); +} + +bool create_cache_path_default(char path[PKG_PATH_MAX], const char *src, + const char *instruction_set) { + std::string src_ = src; + std::string instruction_set_ = instruction_set; + + if (!is_absolute_path(src_)) return false; + if (!is_valid_instruction_set(instruction_set_)) return false; + + for (auto it = src_.begin() + 1; it < src_.end(); ++it) { + if (*it == '/') { + *it = '@'; + } + } + + std::string res_ = android_data_dir + DALVIK_CACHE + '/' + instruction_set_ + src_ + + DALVIK_CACHE_POSTFIX; + const char* res = res_.c_str(); + if (strlen(res) >= PKG_PATH_MAX) { + LOG(ERROR) << "Result too large"; + return false; + } else { + strlcpy(path, res, PKG_PATH_MAX); + return true; + } +} + } // namespace installd } // namespace android diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index 23446da43c..1f41e67e26 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -17,6 +17,8 @@ #ifndef DEXOPT_H_ #define DEXOPT_H_ +#include "installd_constants.h" + #include <sys/types.h> #include <cutils/multiuser.h> @@ -66,6 +68,15 @@ int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *ins const char* volume_uuid, const char* class_loader_context, const char* se_info, bool downgrade); +bool calculate_oat_file_path_default(char path[PKG_PATH_MAX], const char *oat_dir, + const char *apk_path, const char *instruction_set); + +bool calculate_odex_file_path_default(char path[PKG_PATH_MAX], const char *apk_path, + const char *instruction_set); + +bool create_cache_path_default(char path[PKG_PATH_MAX], const char *src, + const char *instruction_set); + } // namespace installd } // namespace android diff --git a/cmds/installd/globals.cpp b/cmds/installd/globals.cpp index edcdb6a1e2..b3a6dafa9a 100644 --- a/cmds/installd/globals.cpp +++ b/cmds/installd/globals.cpp @@ -16,15 +16,15 @@ #define LOG_TAG "installd" -#include <stdlib.h> -#include <string.h> - -#include <log/log.h> // TODO: Move everything to base::logging. - #include <globals.h> #include <installd_constants.h> #include <utils.h> +#include <android-base/logging.h> + +#include <stdlib.h> +#include <string.h> + namespace android { namespace installd { @@ -44,106 +44,78 @@ static constexpr const char* PROFILES_SUBDIR = "misc/profiles"; // sub-directory static constexpr const char* PRIVATE_APP_SUBDIR = "app-private/"; // sub-directory under // ANDROID_DATA -/* Directory records that are used in execution of commands. */ -dir_rec_t android_app_dir; -dir_rec_t android_app_ephemeral_dir; -dir_rec_t android_app_lib_dir; -dir_rec_t android_app_private_dir; -dir_rec_t android_asec_dir; -dir_rec_t android_data_dir; -dir_rec_t android_media_dir; -dir_rec_t android_mnt_expand_dir; -dir_rec_t android_profiles_dir; - -dir_rec_array_t android_system_dirs; - -/** - * Initialize all the global variables that are used elsewhere. Returns 0 upon - * success and -1 on error. - */ -void free_globals() { - size_t i; - - for (i = 0; i < android_system_dirs.count; i++) { - if (android_system_dirs.dirs[i].path != NULL) { - free(android_system_dirs.dirs[i].path); - } +std::string android_app_dir; +std::string android_app_ephemeral_dir; +std::string android_app_lib_dir; +std::string android_app_private_dir; +std::string android_asec_dir; +std::string android_data_dir; +std::string android_media_dir; +std::string android_mnt_expand_dir; +std::string android_profiles_dir; +std::string android_root_dir; + +std::vector<std::string> android_system_dirs; + +bool init_globals_from_data_and_root() { + const char* data_path = getenv("ANDROID_DATA"); + if (data_path == nullptr) { + LOG(ERROR) << "Could not find ANDROID_DATA"; + return false; + } + const char* root_path = getenv("ANDROID_ROOT"); + if (root_path == nullptr) { + LOG(ERROR) << "Could not find ANDROID_ROOT"; + return false; } + return init_globals_from_data_and_root(data_path, root_path); +} - free(android_system_dirs.dirs); +static std::string ensure_trailing_slash(const std::string& path) { + if (path.rfind('/') != path.size() - 1) { + return path + '/'; + } else { + return path; + } } bool init_globals_from_data_and_root(const char* data, const char* root) { // Get the android data directory. - if (get_path_from_string(&android_data_dir, data) < 0) { - return false; - } + android_data_dir = ensure_trailing_slash(data); + + // Get the android root directory. + android_root_dir = ensure_trailing_slash(root); // Get the android app directory. - if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { - return false; - } + android_app_dir = android_data_dir + APP_SUBDIR; // Get the android protected app directory. - if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { - return false; - } + android_app_private_dir = android_data_dir + PRIVATE_APP_SUBDIR; // Get the android ephemeral app directory. - if (copy_and_append(&android_app_ephemeral_dir, &android_data_dir, EPHEMERAL_APP_SUBDIR) < 0) { - return false; - } + android_app_ephemeral_dir = android_data_dir + EPHEMERAL_APP_SUBDIR; // Get the android app native library directory. - if (copy_and_append(&android_app_lib_dir, &android_data_dir, APP_LIB_SUBDIR) < 0) { - return false; - } + android_app_lib_dir = android_data_dir + APP_LIB_SUBDIR; // Get the sd-card ASEC mount point. - if (get_path_from_env(&android_asec_dir, ASEC_MOUNTPOINT_ENV_NAME) < 0) { - return false; - } + android_asec_dir = ensure_trailing_slash(getenv(ASEC_MOUNTPOINT_ENV_NAME)); // Get the android media directory. - if (copy_and_append(&android_media_dir, &android_data_dir, MEDIA_SUBDIR) < 0) { - return false; - } + android_media_dir = android_data_dir + MEDIA_SUBDIR; // Get the android external app directory. - if (get_path_from_string(&android_mnt_expand_dir, "/mnt/expand/") < 0) { - return false; - } + android_mnt_expand_dir = "/mnt/expand/"; // Get the android profiles directory. - if (copy_and_append(&android_profiles_dir, &android_data_dir, PROFILES_SUBDIR) < 0) { - return false; - } + android_profiles_dir = android_data_dir + PROFILES_SUBDIR; // Take note of the system and vendor directories. - android_system_dirs.count = 4; - - android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t)); - if (android_system_dirs.dirs == NULL) { - ALOGE("Couldn't allocate array for dirs; aborting\n"); - return false; - } - - dir_rec_t android_root_dir; - if (get_path_from_string(&android_root_dir, root) < 0) { - return false; - } - - android_system_dirs.dirs[0].path = build_string2(android_root_dir.path, APP_SUBDIR); - android_system_dirs.dirs[0].len = strlen(android_system_dirs.dirs[0].path); - - android_system_dirs.dirs[1].path = build_string2(android_root_dir.path, PRIV_APP_SUBDIR); - android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); - - android_system_dirs.dirs[2].path = strdup("/vendor/app/"); - android_system_dirs.dirs[2].len = strlen(android_system_dirs.dirs[2].path); - - android_system_dirs.dirs[3].path = strdup("/oem/app/"); - android_system_dirs.dirs[3].len = strlen(android_system_dirs.dirs[3].path); + android_system_dirs.clear(); + android_system_dirs.push_back(android_root_dir + APP_SUBDIR); + android_system_dirs.push_back(android_root_dir + PRIV_APP_SUBDIR); + android_system_dirs.push_back("/vendor/app/"); + android_system_dirs.push_back("/oem/app/"); return true; } diff --git a/cmds/installd/globals.h b/cmds/installd/globals.h index c90beec49c..633e33bb7e 100644 --- a/cmds/installd/globals.h +++ b/cmds/installd/globals.h @@ -19,40 +19,29 @@ #define GLOBALS_H_ #include <inttypes.h> +#include <string> +#include <vector> namespace android { namespace installd { -/* constants */ - // Name of the environment variable that contains the asec mountpoint. static constexpr const char* ASEC_MOUNTPOINT_ENV_NAME = "ASEC_MOUNTPOINT"; -/* data structures */ - -struct dir_rec_t { - char* path; - size_t len; -}; - -struct dir_rec_array_t { - size_t count; - dir_rec_t* dirs; -}; - -extern dir_rec_t android_app_dir; -extern dir_rec_t android_app_ephemeral_dir; -extern dir_rec_t android_app_lib_dir; -extern dir_rec_t android_app_private_dir; -extern dir_rec_t android_asec_dir; -extern dir_rec_t android_data_dir; -extern dir_rec_t android_media_dir; -extern dir_rec_t android_mnt_expand_dir; -extern dir_rec_t android_profiles_dir; +extern std::string android_app_dir; +extern std::string android_app_ephemeral_dir; +extern std::string android_app_lib_dir; +extern std::string android_app_private_dir; +extern std::string android_asec_dir; +extern std::string android_data_dir; +extern std::string android_media_dir; +extern std::string android_mnt_expand_dir; +extern std::string android_profiles_dir; +extern std::string android_root_dir; -extern dir_rec_array_t android_system_dirs; +extern std::vector<std::string> android_system_dirs; -void free_globals(); +bool init_globals_from_data_and_root(); bool init_globals_from_data_and_root(const char* data, const char* root); } // namespace installd diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index 35936a23af..95ed2fff35 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -30,6 +30,7 @@ #include <private/android_filesystem_config.h> #include "InstalldNativeService.h" +#include "dexopt.h" #include "globals.h" #include "installd_constants.h" #include "installd_deps.h" // Need to fill in requirements of commands. @@ -50,133 +51,22 @@ int get_property(const char *key, char *value, const char *default_value) { return property_get(key, value, default_value); } -// Compute the output path of -bool calculate_oat_file_path(char path[PKG_PATH_MAX], - const char *oat_dir, - const char *apk_path, - const char *instruction_set) { - const char *file_name_start; - const char *file_name_end; - - file_name_start = strrchr(apk_path, '/'); - if (file_name_start == NULL) { - SLOGE("apk_path '%s' has no '/'s in it\n", apk_path); - return false; - } - file_name_end = strrchr(apk_path, '.'); - if (file_name_end < file_name_start) { - SLOGE("apk_path '%s' has no extension\n", apk_path); - return false; - } - - // Calculate file_name - int file_name_len = file_name_end - file_name_start - 1; - char file_name[file_name_len + 1]; - memcpy(file_name, file_name_start + 1, file_name_len); - file_name[file_name_len] = '\0'; - - // <apk_parent_dir>/oat/<isa>/<file_name>.odex - snprintf(path, PKG_PATH_MAX, "%s/%s/%s.odex", oat_dir, instruction_set, file_name); - return true; +bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, + const char *instruction_set) { + return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set); } -/* - * Computes the odex file for the given apk_path and instruction_set. - * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex - * - * Returns false if it failed to determine the odex file path. - */ -bool calculate_odex_file_path(char path[PKG_PATH_MAX], - const char *apk_path, - const char *instruction_set) { - if (strlen(apk_path) + strlen("oat/") + strlen(instruction_set) - + strlen("/") + strlen("odex") + 1 > PKG_PATH_MAX) { - SLOGE("apk_path '%s' may be too long to form odex file path.\n", apk_path); - return false; - } - - strcpy(path, apk_path); - char *end = strrchr(path, '/'); - if (end == NULL) { - SLOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); - return false; - } - const char *apk_end = apk_path + (end - path); // strrchr(apk_path, '/'); - - strcpy(end + 1, "oat/"); // path = /system/framework/oat/\0 - strcat(path, instruction_set); // path = /system/framework/oat/<isa>\0 - strcat(path, apk_end); // path = /system/framework/oat/<isa>/whatever.jar\0 - end = strrchr(path, '.'); - if (end == NULL) { - SLOGE("apk_path '%s' has no extension.\n", apk_path); - return false; - } - strcpy(end + 1, "odex"); - return true; +bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, + const char *instruction_set) { + return calculate_odex_file_path_default(path, apk_path, instruction_set); } -bool create_cache_path(char path[PKG_PATH_MAX], - const char *src, - const char *instruction_set) { - /* demand that we are an absolute path */ - if ((src == nullptr) || (src[0] != '/') || strstr(src,"..")) { - return false; - } - - size_t srclen = strlen(src); - - if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? - return false; - } - - size_t dstlen = - android_data_dir.len + - strlen(DALVIK_CACHE) + - 1 + - strlen(instruction_set) + - srclen + - strlen(DALVIK_CACHE_POSTFIX) + 2; - - if (dstlen > PKG_PATH_MAX) { - return false; - } - - sprintf(path,"%s%s/%s/%s", - android_data_dir.path, - DALVIK_CACHE, - instruction_set, - src + 1 /* skip the leading / */); - - char* tmp = - path + - android_data_dir.len + - strlen(DALVIK_CACHE) + - 1 + - strlen(instruction_set) + 1; - - for(; *tmp; tmp++) { - if (*tmp == '/') { - *tmp = '@'; - } - } - - strcat(path, DALVIK_CACHE_POSTFIX); - return true; +bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) { + return create_cache_path_default(path, src, instruction_set); } static bool initialize_globals() { - const char* data_path = getenv("ANDROID_DATA"); - if (data_path == nullptr) { - SLOGE("Could not find ANDROID_DATA"); - return false; - } - const char* root_path = getenv("ANDROID_ROOT"); - if (root_path == nullptr) { - SLOGE("Could not find ANDROID_ROOT"); - return false; - } - - return init_globals_from_data_and_root(data_path, root_path); + return init_globals_from_data_and_root(); } static int initialize_directories() { @@ -184,7 +74,7 @@ static int initialize_directories() { // Read current filesystem layout version to handle upgrade paths char version_path[PATH_MAX]; - snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); + snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.c_str()); int oldVersion; if (fs_read_atomic_int(version_path, &oldVersion) == -1) { @@ -206,7 +96,7 @@ static int initialize_directories() { SLOGD("Upgrading to /data/misc/user directories"); char misc_dir[PATH_MAX]; - snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); + snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.c_str()); char keychain_added_dir[PATH_MAX]; snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); @@ -227,7 +117,7 @@ static int initialize_directories() { if ((name[1] == '.') && (name[2] == 0)) continue; } - uint32_t user_id = atoi(name); + uint32_t user_id = std::stoi(name); // /data/misc/user/<user_id> if (ensure_config_user_dirs(user_id) == -1) { @@ -281,7 +171,7 @@ fail: return res; } -static int log_callback(int type, const char *fmt, ...) { +static int log_callback(int type, const char *fmt, ...) { // NOLINT va_list ap; int priority; diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp index 09e1a00d10..a58ba4117b 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -146,12 +146,12 @@ class OTAPreoptService { return 0; } // Copy in the default value. - strncpy(value, default_value, kPropertyValueMax - 1); + strlcpy(value, default_value, kPropertyValueMax - 1); value[kPropertyValueMax - 1] = 0; return strlen(default_value);// TODO: Need to truncate? } size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); - strncpy(value, prop_value->data(), size); + strlcpy(value, prop_value->data(), size); value[size] = 0; return static_cast<int>(size); } diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp index 34818f65aa..ca812bdeeb 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -25,6 +25,7 @@ #include <gtest/gtest.h> #include "InstalldNativeService.h" +#include "dexopt.h" #include "globals.h" #include "utils.h" @@ -41,25 +42,18 @@ int get_property(const char *key, char *value, const char *default_value) { return property_get(key, value, default_value); } -bool calculate_oat_file_path(char path[PKG_PATH_MAX] ATTRIBUTE_UNUSED, - const char *oat_dir ATTRIBUTE_UNUSED, - const char *apk_path ATTRIBUTE_UNUSED, - const char *instruction_set ATTRIBUTE_UNUSED) { - return false; +bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, + const char *instruction_set) { + return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set); } -bool calculate_odex_file_path(char path[PKG_PATH_MAX] ATTRIBUTE_UNUSED, - const char *apk_path ATTRIBUTE_UNUSED, - const char *instruction_set ATTRIBUTE_UNUSED) { - return false; +bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, + const char *instruction_set) { + return calculate_odex_file_path_default(path, apk_path, instruction_set); } -bool create_cache_path(char path[PKG_PATH_MAX], - const char *src, - const char *instruction_set) { - // Not really a valid path but it's good enough for testing. - sprintf(path,"/data/dalvik-cache/%s/%s", instruction_set, src); - return true; +bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) { + return create_cache_path_default(path, src, instruction_set); } static void mkdir(const char* path, uid_t owner, gid_t group, mode_t mode) { @@ -102,6 +96,8 @@ protected: testUuid = std::make_unique<std::string>(); *testUuid = std::string(kTestUuid); system("mkdir -p /data/local/tmp/user/0"); + + init_globals_from_data_and_root(); } virtual void TearDown() { @@ -153,12 +149,28 @@ TEST_F(ServiceTest, FixupAppData_Moved) { EXPECT_EQ(10000, stat_gid("com.example/bar/file")); } -TEST_F(ServiceTest, RmDexNoDalvikCache) { - LOG(INFO) << "RmDexNoDalvikCache"; +TEST_F(ServiceTest, CalculateOat) { + char buf[PKG_PATH_MAX]; + + EXPECT_TRUE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file.apk", "isa")); + EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf)); + + EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file", "isa")); + EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "file", "isa")); +} + +TEST_F(ServiceTest, CalculateOdex) { + char buf[PKG_PATH_MAX]; + + EXPECT_TRUE(calculate_odex_file_path(buf, "/path/to/file.apk", "isa")); + EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf)); +} + +TEST_F(ServiceTest, CalculateCache) { + char buf[PKG_PATH_MAX]; - // Try to remove a non existing dalvik cache dex. The call should be - // successful because there's nothing to remove. - EXPECT_TRUE(service->rmdex("com.example", "arm").isOk()); + EXPECT_TRUE(create_cache_path(buf, "/path/to/file.apk", "isa")); + EXPECT_EQ("/data/dalvik-cache/isa/path@to@file.apk@classes.dex", std::string(buf)); } } // namespace installd diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp index 46ed85fd59..09dd25ae16 100644 --- a/cmds/installd/tests/installd_utils_test.cpp +++ b/cmds/installd/tests/installd_utils_test.cpp @@ -17,6 +17,7 @@ #include <stdlib.h> #include <string.h> +#include <android-base/logging.h> #include <gtest/gtest.h> #include "InstalldNativeService.h" @@ -27,6 +28,7 @@ #define LOG_TAG "utils_test" #define TEST_DATA_DIR "/data/" +#define TEST_ROOT_DIR "/system/" #define TEST_APP_DIR "/data/app/" #define TEST_APP_PRIVATE_DIR "/data/app-private/" #define TEST_APP_EPHEMERAL_DIR "/data/app-ephemeral/" @@ -44,39 +46,13 @@ namespace installd { class UtilsTest : public testing::Test { protected: virtual void SetUp() { - android_app_dir.path = (char*) TEST_APP_DIR; - android_app_dir.len = strlen(TEST_APP_DIR); + setenv("ANDROID_LOG_TAGS", "*:v", 1); + android::base::InitLogging(nullptr); - android_app_private_dir.path = (char*) TEST_APP_PRIVATE_DIR; - android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR); - - android_app_ephemeral_dir.path = (char*) TEST_APP_EPHEMERAL_DIR; - android_app_ephemeral_dir.len = strlen(TEST_APP_EPHEMERAL_DIR); - - android_data_dir.path = (char*) TEST_DATA_DIR; - android_data_dir.len = strlen(TEST_DATA_DIR); - - android_asec_dir.path = (char*) TEST_ASEC_DIR; - android_asec_dir.len = strlen(TEST_ASEC_DIR); - - android_mnt_expand_dir.path = (char*) TEST_EXPAND_DIR; - android_mnt_expand_dir.len = strlen(TEST_EXPAND_DIR); - - android_system_dirs.count = 2; - - android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t)); - android_system_dirs.dirs[0].path = (char*) TEST_SYSTEM_DIR1; - android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1); - - android_system_dirs.dirs[1].path = (char*) TEST_SYSTEM_DIR2; - android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2); - - android_profiles_dir.path = (char*) TEST_PROFILE_DIR; - android_profiles_dir.len = strlen(TEST_PROFILE_DIR); + init_globals_from_data_and_root(TEST_DATA_DIR, TEST_ROOT_DIR); } virtual void TearDown() { - free(android_system_dirs.dirs); } std::string create_too_long_path(const std::string& seed) { @@ -276,184 +252,6 @@ TEST_F(UtilsTest, CheckSystemApp_Subdir) { << badapp2 << " should be rejected not a system path"; } -TEST_F(UtilsTest, GetPathFromString_NullPathFail) { - dir_rec_t test1; - EXPECT_EQ(-1, get_path_from_string(&test1, (const char *) NULL)) - << "Should not allow NULL as a path."; -} - -TEST_F(UtilsTest, GetPathFromString_EmptyPathFail) { - dir_rec_t test1; - EXPECT_EQ(-1, get_path_from_string(&test1, "")) - << "Should not allow empty paths."; -} - -TEST_F(UtilsTest, GetPathFromString_RelativePathFail) { - dir_rec_t test1; - EXPECT_EQ(-1, get_path_from_string(&test1, "mnt/asec")) - << "Should not allow relative paths."; -} - -TEST_F(UtilsTest, GetPathFromString_NonCanonical) { - dir_rec_t test1; - - EXPECT_EQ(0, get_path_from_string(&test1, "/mnt/asec")) - << "Should be able to canonicalize directory /mnt/asec"; - EXPECT_STREQ("/mnt/asec/", test1.path) - << "/mnt/asec should be canonicalized to /mnt/asec/"; - EXPECT_EQ(10, (ssize_t) test1.len) - << "path len should be equal to the length of /mnt/asec/ (10)"; - free(test1.path); -} - -TEST_F(UtilsTest, GetPathFromString_CanonicalPath) { - dir_rec_t test3; - EXPECT_EQ(0, get_path_from_string(&test3, "/data/app/")) - << "Should be able to canonicalize directory /data/app/"; - EXPECT_STREQ("/data/app/", test3.path) - << "/data/app/ should be canonicalized to /data/app/"; - EXPECT_EQ(10, (ssize_t) test3.len) - << "path len should be equal to the length of /data/app/ (10)"; - free(test3.path); -} - -TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) { - char path[PKG_PATH_MAX]; - - // Create long packagename of "aaaaa..." - size_t pkgnameSize = PKG_NAME_MAX; - char pkgname[pkgnameSize + 1]; - memset(pkgname, 'a', pkgnameSize); - pkgname[1] = '.'; - pkgname[pkgnameSize] = '\0'; - - EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0)) - << "Should successfully be able to create package name."; - - std::string prefix = std::string(TEST_DATA_DIR) + PRIMARY_USER_PREFIX; - size_t offset = prefix.length(); - - EXPECT_STREQ(pkgname, path + offset) - << "Package path should be a really long string of a's"; -} - -TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) { - char path[PKG_PATH_MAX]; - - // Create long packagename of "aaaaa..." - size_t postfixSize = PKG_PATH_MAX; - char postfix[postfixSize + 1]; - memset(postfix, 'a', postfixSize); - postfix[postfixSize] = '\0'; - - EXPECT_EQ(-1, create_pkg_path(path, "com.example.package", postfix, 0)) - << "Should return error because postfix is too long."; -} - -TEST_F(UtilsTest, CreatePkgPath_PrimaryUser) { - char path[PKG_PATH_MAX]; - - EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 0)) - << "Should return error because postfix is too long."; - - std::string p = std::string(TEST_DATA_DIR) - + PRIMARY_USER_PREFIX - + "com.example.package"; - EXPECT_STREQ(p.c_str(), path) - << "Package path should be in /data/data/"; -} - -TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) { - char path[PKG_PATH_MAX]; - - EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 1)) - << "Should successfully create package path."; - - std::string p = std::string(TEST_DATA_DIR) - + SECONDARY_USER_PREFIX - + "1/com.example.package"; - EXPECT_STREQ(p.c_str(), path) - << "Package path should be in /data/user/"; -} - -TEST_F(UtilsTest, CreateMovePath_Primary) { - char path[PKG_PATH_MAX]; - - EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0)) - << "Should be able to create move path for primary user"; - - EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path) - << "Primary user package directory should be created correctly"; -} - - -TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) { - char path[PKG_PATH_MAX]; - std::string really_long_app_name = create_too_long_path("com.example"); - EXPECT_EQ(-1, create_move_path(path, really_long_app_name.c_str(), "shared_prefs", 0)) - << "Should fail to create move path for primary user"; -} - -TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) { - char path[PKG_PATH_MAX]; - std::string really_long_leaf_name = create_too_long_path("leaf_"); - EXPECT_EQ(-1, create_move_path(path, "com.android.test", really_long_leaf_name.c_str(), 0)) - << "Should fail to create move path for primary user"; -} - -TEST_F(UtilsTest, CopyAndAppend_Normal) { - //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix) - dir_rec_t dst; - dir_rec_t src; - - src.path = (char*) "/data/"; - src.len = strlen(src.path); - - EXPECT_EQ(0, copy_and_append(&dst, &src, "app/")) - << "Should return error because postfix is too long."; - - EXPECT_STREQ("/data/app/", dst.path) - << "Appended path should be correct"; - - EXPECT_EQ(10, (ssize_t) dst.len) - << "Appended path should be length of '/data/app/' (10)"; -} - -TEST_F(UtilsTest, AppendAndIncrement_Normal) { - size_t dst_size = 10; - char dst[dst_size]; - char *dstp = dst; - const char* src = "FOO"; - - EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) - << "String should append successfully"; - - EXPECT_STREQ("FOO", dst) - << "String should append correctly"; - - EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) - << "String should append successfully again"; - - EXPECT_STREQ("FOOFOO", dst) - << "String should append correctly again"; -} - -TEST_F(UtilsTest, AppendAndIncrement_TooBig) { - size_t dst_size = 5; - char dst[dst_size]; - char *dstp = dst; - const char* src = "FOO"; - - EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) - << "String should append successfully"; - - EXPECT_STREQ("FOO", dst) - << "String should append correctly"; - - EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size)) - << "String should fail because it's too large to fit"; -} - TEST_F(UtilsTest, CreateDataPath) { EXPECT_EQ("/data", create_data_path(nullptr)); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b", diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index 7a562ca69d..c21fae5e83 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -129,24 +129,6 @@ std::string create_data_user_de_package_path(const char* volume_uuid, create_data_user_de_path(volume_uuid, user).c_str(), package_name); } -int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, - const char *postfix, userid_t userid) { - if (!is_valid_package_name(pkgname)) { - path[0] = '\0'; - return -1; - } - - std::string _tmp(create_data_user_ce_package_path(nullptr, userid, pkgname) + postfix); - const char* tmp = _tmp.c_str(); - if (strlen(tmp) >= PKG_PATH_MAX) { - path[0] = '\0'; - return -1; - } else { - strcpy(path, tmp); - return 0; - } -} - std::string create_data_path(const char* volume_uuid) { if (volume_uuid == nullptr) { return "/data"; @@ -213,7 +195,7 @@ std::string create_data_misc_legacy_path(userid_t userid) { } std::string create_primary_cur_profile_dir_path(userid_t userid) { - return StringPrintf("%s/cur/%u", android_profiles_dir.path, userid); + return StringPrintf("%s/cur/%u", android_profiles_dir.c_str(), userid); } std::string create_primary_current_profile_package_dir_path(userid_t user, @@ -224,12 +206,12 @@ std::string create_primary_current_profile_package_dir_path(userid_t user, } std::string create_primary_ref_profile_dir_path() { - return StringPrintf("%s/ref", android_profiles_dir.path); + return StringPrintf("%s/ref", android_profiles_dir.c_str()); } std::string create_primary_reference_profile_package_dir_path(const std::string& package_name) { check_package_name(package_name.c_str()); - return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name.c_str()); + return StringPrintf("%s/ref/%s", android_profiles_dir.c_str(), package_name.c_str()); } std::string create_data_dalvik_cache_path() { @@ -378,20 +360,6 @@ int calculate_tree_size(const std::string& path, int64_t* size, return 0; } -int create_move_path(char path[PKG_PATH_MAX], - const char* pkgname, - const char* leaf, - userid_t userid ATTRIBUTE_UNUSED) -{ - if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) - >= PKG_PATH_MAX) { - return -1; - } - - sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); - return 0; -} - /** * Checks whether the package name is valid. Returns -1 on error and * 0 on success. @@ -767,22 +735,33 @@ void remove_path_xattr(const std::string& path, const char* inode_xattr) { * The path is allowed to have at most one subdirectory and no indirections * to top level directories (i.e. have ".."). */ -static int validate_path(const dir_rec_t* dir, const char* path, int maxSubdirs) { - size_t dir_len = dir->len; - const char* subdir = strchr(path + dir_len, '/'); - - // Only allow the path to have at most one subdirectory. - if (subdir != NULL) { - ++subdir; - if ((--maxSubdirs == 0) && strchr(subdir, '/') != NULL) { - ALOGE("invalid apk path '%s' (subdir?)\n", path); - return -1; - } +static int validate_path(const std::string& dir, const std::string& path, int maxSubdirs) { + // Argument sanity checking + if (dir.find('/') != 0 || dir.rfind('/') != dir.size() - 1 + || dir.find("..") != std::string::npos) { + LOG(ERROR) << "Invalid directory " << dir; + return -1; + } + if (path.find("..") != std::string::npos) { + LOG(ERROR) << "Invalid path " << path; + return -1; } - // Directories can't have a period directly after the directory markers to prevent "..". - if ((path[dir_len] == '.') || ((subdir != NULL) && (*subdir == '.'))) { - ALOGE("invalid apk path '%s' (trickery)\n", path); + if (path.compare(0, dir.size(), dir) != 0) { + // Common case, path isn't under directory + return -1; + } + + // Count number of subdirectories + auto pos = path.find('/', dir.size()); + int count = 0; + while (pos != std::string::npos) { + pos = path.find('/', pos + 1); + count++; + } + + if (count > maxSubdirs) { + LOG(ERROR) << "Invalid path depth " << path << " when tested against " << dir; return -1; } @@ -794,15 +773,12 @@ static int validate_path(const dir_rec_t* dir, const char* path, int maxSubdirs) * if it is a system app or -1 if it is not. */ int validate_system_app_path(const char* path) { - size_t i; - - for (i = 0; i < android_system_dirs.count; i++) { - const size_t dir_len = android_system_dirs.dirs[i].len; - if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) { - return validate_path(android_system_dirs.dirs + i, path, 1); + std::string path_ = path; + for (const auto& dir : android_system_dirs) { + if (validate_path(dir, path, 1) == 0) { + return 0; } } - return -1; } @@ -840,116 +816,26 @@ bool validate_secondary_dex_path(const std::string& pkgname, const std::string& } /** - * Get the contents of a environment variable that contains a path. Caller - * owns the string that is inserted into the directory record. Returns - * 0 on success and -1 on error. - */ -int get_path_from_env(dir_rec_t* rec, const char* var) { - const char* path = getenv(var); - int ret = get_path_from_string(rec, path); - if (ret < 0) { - ALOGW("Problem finding value for environment variable %s\n", var); - } - return ret; -} - -/** - * Puts the string into the record as a directory. Appends '/' to the end - * of all paths. Caller owns the string that is inserted into the directory - * record. A null value will result in an error. - * - * Returns 0 on success and -1 on error. - */ -int get_path_from_string(dir_rec_t* rec, const char* path) { - if (path == NULL) { - return -1; - } else { - const size_t path_len = strlen(path); - if (path_len <= 0) { - return -1; - } - - // Make sure path is absolute. - if (path[0] != '/') { - return -1; - } - - if (path[path_len - 1] == '/') { - // Path ends with a forward slash. Make our own copy. - - rec->path = strdup(path); - if (rec->path == NULL) { - return -1; - } - - rec->len = path_len; - } else { - // Path does not end with a slash. Generate a new string. - char *dst; - - // Add space for slash and terminating null. - size_t dst_size = path_len + 2; - - rec->path = (char*) malloc(dst_size); - if (rec->path == NULL) { - return -1; - } - - dst = rec->path; - - if (append_and_increment(&dst, path, &dst_size) < 0 - || append_and_increment(&dst, "/", &dst_size)) { - ALOGE("Error canonicalizing path"); - return -1; - } - - rec->len = dst - rec->path; - } - } - return 0; -} - -int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { - dst->len = src->len + strlen(suffix); - const size_t dstSize = dst->len + 1; - dst->path = (char*) malloc(dstSize); - - if (dst->path == NULL - || snprintf(dst->path, dstSize, "%s%s", src->path, suffix) - != (ssize_t) dst->len) { - ALOGE("Could not allocate memory to hold appended path; aborting\n"); - return -1; - } - - return 0; -} - -/** * Check whether path points to a valid path for an APK file. The path must * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within * that path. Returns -1 when an invalid path is encountered and 0 when a valid path * is encountered. */ static int validate_apk_path_internal(const char *path, int maxSubdirs) { - const dir_rec_t* dir = NULL; - if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { - dir = &android_app_dir; - } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { - dir = &android_app_private_dir; - } else if (!strncmp(path, android_app_ephemeral_dir.path, android_app_ephemeral_dir.len)) { - dir = &android_app_ephemeral_dir; - } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) { - dir = &android_asec_dir; - } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { - dir = &android_mnt_expand_dir; - if (maxSubdirs < 2) { - maxSubdirs = 2; - } + std::string path_ = path; + if (validate_path(android_app_dir, path_, maxSubdirs) == 0) { + return 0; + } else if (validate_path(android_app_private_dir, path_, maxSubdirs) == 0) { + return 0; + } else if (validate_path(android_app_ephemeral_dir, path_, maxSubdirs) == 0) { + return 0; + } else if (validate_path(android_asec_dir, path_, maxSubdirs) == 0) { + return 0; + } else if (validate_path(android_mnt_expand_dir, path_, std::max(maxSubdirs, 2)) == 0) { + return 0; } else { return -1; } - - return validate_path(dir, path, maxSubdirs); } int validate_apk_path(const char* path) { @@ -960,48 +846,6 @@ 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) { - ssize_t ret = strlcpy(*dst, src, *dst_size); - if (ret < 0 || (size_t) ret >= *dst_size) { - return -1; - } - *dst += ret; - *dst_size -= ret; - return 0; -} - -char *build_string2(const char *s1, const char *s2) { - if (s1 == NULL || s2 == NULL) return NULL; - - int len_s1 = strlen(s1); - int len_s2 = strlen(s2); - int len = len_s1 + len_s2 + 1; - char *result = (char *) malloc(len); - if (result == NULL) return NULL; - - strcpy(result, s1); - strcpy(result + len_s1, s2); - - return result; -} - -char *build_string3(const char *s1, const char *s2, const char *s3) { - if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL; - - int len_s1 = strlen(s1); - int len_s2 = strlen(s2); - int len_s3 = strlen(s3); - int len = len_s1 + len_s2 + len_s3 + 1; - char *result = (char *) malloc(len); - if (result == NULL) return NULL; - - strcpy(result, s1); - strcpy(result + len_s1, s2); - strcpy(result + len_s1 + len_s2, s3); - - return result; -} - int ensure_config_user_dirs(userid_t userid) { // writable by system, readable by any app within the same user const int uid = multiuser_get_uid(userid, AID_SYSTEM); diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h index a1d8443d7d..3e04af9178 100644 --- a/cmds/installd/utils.h +++ b/cmds/installd/utils.h @@ -41,18 +41,11 @@ namespace android { namespace installd { -struct dir_rec_t; - constexpr const char* kXattrInodeCache = "user.inode_cache"; constexpr const char* kXattrInodeCodeCache = "user.inode_code_cache"; constexpr const char* kXattrCacheGroup = "user.cache_group"; constexpr const char* kXattrCacheTombstone = "user.cache_tombstone"; -int create_pkg_path(char path[PKG_PATH_MAX], - const char *pkgname, - const char *postfix, - userid_t userid); - std::string create_data_path(const char* volume_uuid); std::string create_data_app_path(const char* volume_uuid); @@ -96,11 +89,6 @@ int calculate_tree_size(const std::string& path, int64_t* size, int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid); -int create_move_path(char path[PKG_PATH_MAX], - const char* pkgname, - const char* leaf, - userid_t userid); - bool is_valid_filename(const std::string& name); bool is_valid_package_name(const std::string& packageName); @@ -128,20 +116,9 @@ int validate_system_app_path(const char* path); bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path, const char* volume_uuid, int uid, int storage_flag, bool validate_package_path = true); -int get_path_from_env(dir_rec_t* rec, const char* var); - -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 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); - -char *build_string2(const char *s1, const char *s2); -char *build_string3(const char *s1, const char *s2, const char *s3); - int ensure_config_user_dirs(userid_t userid); int wait_child(pid_t pid); |