diff options
| author | 2015-04-07 18:14:05 -0700 | |
|---|---|---|
| committer | 2015-04-07 20:13:27 -0700 | |
| commit | c03de09173f98506e73e7cf7df21fe11795d4b24 (patch) | |
| tree | 52f975303151eb1319acdb7a6a03c3d0042d0c2a /cmds/installd/utils.cpp | |
| parent | 00afb8177fdbf144c75c00e9eacc915589807d35 (diff) | |
Plumb through volume UUID when building paths.
Since app data paths can live on expanded storage devices, accept the
target volume UUID when building paths. The null UUID indicates the
default internal storage.
To improve readability, start using std::string in several places,
which throws when allocations fail. For now, perform last-second
sanity checks on incoming path arguments, but we'll eventually want
to check arguments as they come through installd.cpp, instead of
crashing the entire daemon.
Also remove "lib" symlink code from install() and make_user_data(),
since we're no longer supporting /data/app-lib. The framework
already uses linklib() to create the right symlink for the selected
ISA-specific library dir.
Bug: 19993667
Change-Id: Ib9343575ffb62bf3981e19375de8f3822fc31e28
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 df2bbced8c..763cb4283d 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 */ |