diff options
Diffstat (limited to 'cmds/installd/utils.cpp')
-rw-r--r-- | cmds/installd/utils.cpp | 119 |
1 files changed, 53 insertions, 66 deletions
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index df2bbce..763cb42 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -16,86 +16,69 @@ #include "installd.h" -#define CACHE_NOISY(x) //x - -int create_pkg_path_in_dir(char path[PKG_PATH_MAX], - const dir_rec_t* dir, - const char* pkgname, - const char* postfix) -{ - const size_t postfix_len = strlen(postfix); - - const size_t pkgname_len = strlen(pkgname); - if (pkgname_len > PKG_NAME_MAX) { - return -1; - } - - if (is_valid_package_name(pkgname) < 0) { - return -1; - } +#include <base/stringprintf.h> +#include <base/logging.h> - if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) { - return -1; - } - - char *dst = path; - size_t dst_size = PKG_PATH_MAX; +#define CACHE_NOISY(x) //x - if (append_and_increment(&dst, dir->path, &dst_size) < 0 - || append_and_increment(&dst, pkgname, &dst_size) < 0 - || append_and_increment(&dst, postfix, &dst_size) < 0) { - ALOGE("Error building APK path"); - return -1; - } - - return 0; -} +using android::base::StringPrintf; /** - * Create the package path name for a given package name with a postfix for - * a certain userid. Returns 0 on success, and -1 on failure. + * Check that given string is valid filename, and that it attempts no + * parent or child directory traversal. */ -int create_pkg_path(char path[PKG_PATH_MAX], - const char *pkgname, - const char *postfix, - userid_t userid) -{ - size_t userid_len; - const char* userid_prefix; - if (userid == 0) { - userid_prefix = PRIMARY_USER_PREFIX; - userid_len = 0; +static bool is_valid_filename(const std::string& name) { + if (name.empty() || (name == ".") || (name == "..") + || (name.find('/') != std::string::npos)) { + return false; } else { - userid_prefix = SECONDARY_USER_PREFIX; - userid_len = snprintf(NULL, 0, "%d", userid); + return true; } +} - const size_t prefix_len = android_data_dir.len + strlen(userid_prefix) - + userid_len + 1 /*slash*/; - char prefix[prefix_len + 1]; +/** + * Create the path name where package data should be stored for the given + * volume UUID, package name, and user ID. An empty UUID is assumed to be + * internal storage. + */ +std::string create_package_data_path(const char* volume_uuid, + const char* package_name, userid_t user) { + CHECK(is_valid_filename(package_name)); + CHECK(is_valid_package_name(package_name) == 0); + + if (volume_uuid == nullptr) { + if (user == 0) { + // /data/data/com.example + return StringPrintf("%sdata/%s", android_data_dir.path, package_name); + } else { + // /data/user/0/com.example + return StringPrintf("%suser/%u/%s", android_data_dir.path, user, package_name); + } + } else { + CHECK(is_valid_filename(volume_uuid)); - char *dst = prefix; - size_t dst_size = sizeof(prefix); + // /mnt/expand/uuid/user/0/com.example + return StringPrintf("%s%s/user/%u/%s", android_mnt_expand_dir.path, + volume_uuid, user, package_name); + } +} - if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 - || append_and_increment(&dst, userid_prefix, &dst_size) < 0) { - ALOGE("Error building prefix for APK path"); +int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, + const char *postfix, userid_t userid) { + if (is_valid_package_name(pkgname) != 0) { + path[0] = '\0'; return -1; } - if (userid != 0) { - int ret = snprintf(dst, dst_size, "%d/", userid); - if (ret < 0 || (size_t) ret != userid_len + 1) { - ALOGW("Error appending UID to APK path"); - return -1; - } + std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix); + const char* tmp = _tmp.c_str(); + if (strlen(tmp) >= PKG_PATH_MAX) { + path[0] = '\0'; + return -1; + } else { + strcpy(path, tmp); + return 0; } - - dir_rec_t dir; - dir.path = prefix; - dir.len = prefix_len; - - return create_pkg_path_in_dir(path, &dir, pkgname, postfix); } /** @@ -182,6 +165,10 @@ int is_valid_package_name(const char* pkgname) { const char *x = pkgname; int alpha = -1; + if (strlen(pkgname) > PKG_NAME_MAX) { + return -1; + } + while (*x) { if (isalnum(*x) || (*x == '_')) { /* alphanumeric or underscore are fine */ |