Loading cmds/installd/commands.cpp +137 −76 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const c return -1; } std::string _pkgdir(create_package_data_path(uuid, pkgname, 0)); std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (mkdir(pkgdir, 0751) < 0) { Loading Loading @@ -80,7 +80,7 @@ int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const c int uninstall(const char *uuid, const char *pkgname, userid_t userid) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); remove_profile_file(pkgname); Loading Loading @@ -115,7 +115,7 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid) return -1; } std::string _pkgdir(create_package_data_path(uuid, pkgname, 0)); std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (stat(pkgdir, &s) < 0) return -1; Loading @@ -141,7 +141,7 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid) int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); return delete_dir_contents(pkgdir, 0, NULL); Loading @@ -149,7 +149,7 @@ int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (mkdir(pkgdir, 0751) < 0) { Loading Loading @@ -177,15 +177,48 @@ int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t us return 0; } int move_user_data(const char *from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo) { int move_complete_app(const char *from_uuid, const char *to_uuid, const char *package_name, const char *data_app_name, appid_t appid, const char* seinfo) { std::vector<userid_t> users = get_known_users(from_uuid); // Copy package private data for all known users // Copy app { std::string from(create_data_app_package_path(from_uuid, data_app_name)); std::string to(create_data_app_package_path(to_uuid, data_app_name)); std::string to_parent(create_data_app_path(to_uuid)); char *argv[] = { (char*) kCpPath, (char*) "-F", /* delete any existing destination file first (--remove-destination) */ (char*) "-p", /* preserve timestamps, ownership, and permissions */ (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */ (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_parent.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true); if (rc != 0) { LOG(ERROR) << "Failed copying " << from << " to " << to << ": status " << rc; goto fail; } if (selinux_android_restorecon(to.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) { LOG(ERROR) << "Failed to restorecon " << to; goto fail; } } // Copy private data for all known users for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to_user(create_data_user_path(to_uuid, user)); std::string from(create_data_user_package_path(from_uuid, user, package_name)); std::string to(create_data_user_package_path(to_uuid, user, package_name)); std::string to_parent(create_data_user_path(to_uuid, user)); // Data source may not exist for all users; that's okay if (access(from.c_str(), F_OK) != 0) { Loading Loading @@ -213,7 +246,7 @@ int move_user_data(const char *from_uuid, const char *to_uuid, (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_user.c_str() (char*) to_parent.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; Loading @@ -231,9 +264,15 @@ int move_user_data(const char *from_uuid, const char *to_uuid, } } // Copy successful, so delete old data // Delete old app and data { std::string from(create_data_app_package_path(from_uuid, data_app_name)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } } for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string from(create_data_user_package_path(from_uuid, user, package_name)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } Loading @@ -242,8 +281,14 @@ int move_user_data(const char *from_uuid, const char *to_uuid, fail: // Nuke everything we might have already copied { std::string to(create_data_app_package_path(to_uuid, data_app_name)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } for (auto user : users) { std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to(create_data_user_package_path(to_uuid, user, package_name)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } Loading Loading @@ -289,7 +334,7 @@ int delete_user(const char *uuid, userid_t userid) int delete_cache(const char *uuid, const char *pkgname, userid_t userid) { std::string _cachedir( create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX); create_data_user_package_path(uuid, userid, pkgname) + CACHE_DIR_POSTFIX); const char* cachedir = _cachedir.c_str(); /* delete contents, not the directory, no exceptions */ Loading @@ -299,7 +344,7 @@ int delete_cache(const char *uuid, const char *pkgname, userid_t userid) int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid) { std::string _codecachedir( create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX); create_data_user_package_path(uuid, userid, pkgname) + CACHE_DIR_POSTFIX); const char* codecachedir = _codecachedir.c_str(); struct stat s; Loading Loading @@ -454,7 +499,7 @@ int rm_dex(const char *path, const char *instruction_set) } } int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, int get_size(const char *uuid, const char *pkgname, int userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int64_t* _asecsize) Loading @@ -471,21 +516,29 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char int64_t asecsize = 0; /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ * on the /system partition and its not on the sdcard. */ if (validate_system_app_path(apkpath) && strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); if (S_ISDIR(s.st_mode)) { d = opendir(apkpath); if (d != NULL) { dfd = dirfd(d); codesize += calculate_dir_size(dfd); closedir(d); } } /* count the forward locked apk as code if it is given */ } } /* count the forward locked apk as code if it is given */ if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') { if (stat(fwdlock_apkpath, &s) == 0) { codesize += stat_size(&s); } } /* count the cached dexfile as code */ if (!create_cache_path(path, apkpath, instruction_set)) { if (stat(path, &s) == 0) { Loading @@ -503,20 +556,28 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char } } /* compute asec size if it is given */ /* compute asec size if it is given */ if (asecpath != NULL && asecpath[0] != '!') { if (stat(asecpath, &s) == 0) { asecsize += stat_size(&s); } } std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::vector<userid_t> users; if (userid == -1) { users = get_known_users(uuid); } else { users.push_back(userid); } for (auto user : users) { std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname)); const char* pkgdir = _pkgdir.c_str(); d = opendir(pkgdir); if (d == NULL) { goto done; PLOG(WARNING) << "Failed to open " << pkgdir; continue; } dfd = dirfd(d); Loading Loading @@ -564,7 +625,7 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char } } closedir(d); done: } *_codesize = codesize; *_datasize = datasize; *_cachesize = cachesize; Loading Loading @@ -1448,7 +1509,7 @@ int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int u struct stat s, libStat; int rc = 0; std::string _pkgdir(create_package_data_path(uuid, pkgname, userId)); std::string _pkgdir(create_data_user_package_path(uuid, userId, pkgname)); std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX); const char* pkgdir = _pkgdir.c_str(); Loading Loading @@ -1639,7 +1700,7 @@ int restorecon_data(const char* uuid, const char* pkgName, // Special case for owner on internal storage if (uuid == nullptr) { std::string path(create_package_data_path(nullptr, pkgName, 0)); std::string path(create_data_user_package_path(nullptr, 0, pkgName)); if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, flags) < 0) { PLOG(ERROR) << "restorecon failed for " << path; Loading cmds/installd/installd.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -124,10 +124,10 @@ static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused) return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ } static int do_mv_user_data(char **arg, char reply[REPLY_MAX] __unused) static int do_mv_complete_app(char **arg, char reply[REPLY_MAX] __unused) { // from_uuid, to_uuid, pkgname, appid, seinfo return move_user_data(parse_null(arg[0]), parse_null(arg[1]), arg[2], atoi(arg[3]), arg[4]); // from_uuid, to_uuid, package_name, data_app_name, appid, seinfo return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]); } static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) Loading Loading @@ -200,7 +200,7 @@ struct cmdinfo cmds[] = { { "rmcodecache", 3, do_rm_code_cache }, { "getsize", 8, do_get_size }, { "rmuserdata", 3, do_rm_user_data }, { "mvuserdata", 5, do_mv_user_data }, { "mvcompleteapp", 6, do_mv_complete_app }, { "movefiles", 0, do_movefiles }, { "linklib", 4, do_linklib }, { "mkuserdata", 5, do_mk_user_data }, Loading cmds/installd/installd.h +15 −9 Original line number Diff line number Diff line Loading @@ -142,10 +142,6 @@ typedef struct { /* util.c */ // TODO: rename to create_data_user_package_path std::string create_package_data_path(const char* volume_uuid, const char* package_name, userid_t user); int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, Loading @@ -153,8 +149,15 @@ int create_pkg_path(char path[PKG_PATH_MAX], std::string create_data_path(const char* volume_uuid); std::string create_data_app_path(const char* volume_uuid); std::string create_data_app_package_path(const char* volume_uuid, const char* package_name); std::string create_data_user_path(const char* volume_uuid, userid_t userid); std::string create_data_user_package_path(const char* volume_uuid, userid_t user, const char* package_name); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::vector<userid_t> get_known_users(const char* volume_uuid); Loading Loading @@ -221,8 +224,9 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int move_user_data(const char* from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo); int move_complete_app(const char* from_uuid, const char *to_uuid, const char *package_name, const char *data_app_name, appid_t appid, const char* seinfo); int make_user_config(userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); Loading @@ -230,9 +234,11 @@ int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid); int move_dex(const char *src, const char *dst, const char *instruction_set); int rm_dex(const char *path, const char *instruction_set); int protect(char *pkgname, gid_t gid); int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int get_size(const char *uuid, const char *pkgname, int userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int free_cache(const char *uuid, int64_t free_size); int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName, const char *instruction_set, int dexopt_needed, bool vm_safe_mode, Loading cmds/installd/tests/installd_utils_test.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -455,6 +455,13 @@ TEST_F(UtilsTest, CreateDataPath) { create_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b")); } TEST_F(UtilsTest, CreateDataAppPath) { EXPECT_EQ("/data/app", create_data_app_path(nullptr)); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app", create_data_app_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b")); } TEST_F(UtilsTest, CreateDataUserPath) { EXPECT_EQ("/data/data", create_data_user_path(nullptr, 0)); EXPECT_EQ("/data/user/10", create_data_user_path(nullptr, 10)); Loading @@ -475,14 +482,21 @@ TEST_F(UtilsTest, CreateDataMediaPath) { create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10)); } TEST_F(UtilsTest, CreatePackageDataPath) { EXPECT_EQ("/data/data/com.example", create_package_data_path(nullptr, "com.example", 0)); EXPECT_EQ("/data/user/10/com.example", create_package_data_path(nullptr, "com.example", 10)); TEST_F(UtilsTest, CreateDataAppPackagePath) { EXPECT_EQ("/data/app/com.example", create_data_app_package_path(nullptr, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app/com.example", create_data_app_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example")); } TEST_F(UtilsTest, CreateDataUserPackagePath) { EXPECT_EQ("/data/data/com.example", create_data_user_package_path(nullptr, 0, "com.example")); EXPECT_EQ("/data/user/10/com.example", create_data_user_package_path(nullptr, 10, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example", create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 0)); create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example", create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 10)); create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example")); } } cmds/installd/utils.cpp +26 −4 Original line number Diff line number Diff line Loading @@ -36,17 +36,32 @@ static bool is_valid_filename(const std::string& name) { } } /** * Create the path name where package app contents should be stored for * the given volume UUID and package name. An empty UUID is assumed to * be internal storage. */ std::string create_data_app_package_path(const char* volume_uuid, const char* package_name) { CHECK(is_valid_filename(package_name)); CHECK(is_valid_package_name(package_name) == 0); return StringPrintf("%s/%s", create_data_app_path(volume_uuid).c_str(), package_name); } /** * 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) { std::string create_data_user_package_path(const char* volume_uuid, userid_t user, const char* package_name) { CHECK(is_valid_filename(package_name)); CHECK(is_valid_package_name(package_name) == 0); return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name); return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name); } int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, Loading @@ -56,7 +71,7 @@ int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, return -1; } std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix); std::string _tmp(create_data_user_package_path(nullptr, userid, pkgname) + postfix); const char* tmp = _tmp.c_str(); if (strlen(tmp) >= PKG_PATH_MAX) { path[0] = '\0'; Loading @@ -76,6 +91,13 @@ std::string create_data_path(const char* volume_uuid) { } } /** * Create the path name for app data. */ std::string create_data_app_path(const char* volume_uuid) { return StringPrintf("%s/app", create_data_path(volume_uuid).c_str()); } /** * Create the path name for user data for a certain userid. */ Loading Loading
cmds/installd/commands.cpp +137 −76 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const c return -1; } std::string _pkgdir(create_package_data_path(uuid, pkgname, 0)); std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (mkdir(pkgdir, 0751) < 0) { Loading Loading @@ -80,7 +80,7 @@ int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const c int uninstall(const char *uuid, const char *pkgname, userid_t userid) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); remove_profile_file(pkgname); Loading Loading @@ -115,7 +115,7 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid) return -1; } std::string _pkgdir(create_package_data_path(uuid, pkgname, 0)); std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (stat(pkgdir, &s) < 0) return -1; Loading @@ -141,7 +141,7 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid) int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); return delete_dir_contents(pkgdir, 0, NULL); Loading @@ -149,7 +149,7 @@ int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo) { std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname)); const char* pkgdir = _pkgdir.c_str(); if (mkdir(pkgdir, 0751) < 0) { Loading Loading @@ -177,15 +177,48 @@ int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t us return 0; } int move_user_data(const char *from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo) { int move_complete_app(const char *from_uuid, const char *to_uuid, const char *package_name, const char *data_app_name, appid_t appid, const char* seinfo) { std::vector<userid_t> users = get_known_users(from_uuid); // Copy package private data for all known users // Copy app { std::string from(create_data_app_package_path(from_uuid, data_app_name)); std::string to(create_data_app_package_path(to_uuid, data_app_name)); std::string to_parent(create_data_app_path(to_uuid)); char *argv[] = { (char*) kCpPath, (char*) "-F", /* delete any existing destination file first (--remove-destination) */ (char*) "-p", /* preserve timestamps, ownership, and permissions */ (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */ (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_parent.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true); if (rc != 0) { LOG(ERROR) << "Failed copying " << from << " to " << to << ": status " << rc; goto fail; } if (selinux_android_restorecon(to.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) { LOG(ERROR) << "Failed to restorecon " << to; goto fail; } } // Copy private data for all known users for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to_user(create_data_user_path(to_uuid, user)); std::string from(create_data_user_package_path(from_uuid, user, package_name)); std::string to(create_data_user_package_path(to_uuid, user, package_name)); std::string to_parent(create_data_user_path(to_uuid, user)); // Data source may not exist for all users; that's okay if (access(from.c_str(), F_OK) != 0) { Loading Loading @@ -213,7 +246,7 @@ int move_user_data(const char *from_uuid, const char *to_uuid, (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_user.c_str() (char*) to_parent.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; Loading @@ -231,9 +264,15 @@ int move_user_data(const char *from_uuid, const char *to_uuid, } } // Copy successful, so delete old data // Delete old app and data { std::string from(create_data_app_package_path(from_uuid, data_app_name)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } } for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string from(create_data_user_package_path(from_uuid, user, package_name)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } Loading @@ -242,8 +281,14 @@ int move_user_data(const char *from_uuid, const char *to_uuid, fail: // Nuke everything we might have already copied { std::string to(create_data_app_package_path(to_uuid, data_app_name)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } for (auto user : users) { std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to(create_data_user_package_path(to_uuid, user, package_name)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } Loading Loading @@ -289,7 +334,7 @@ int delete_user(const char *uuid, userid_t userid) int delete_cache(const char *uuid, const char *pkgname, userid_t userid) { std::string _cachedir( create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX); create_data_user_package_path(uuid, userid, pkgname) + CACHE_DIR_POSTFIX); const char* cachedir = _cachedir.c_str(); /* delete contents, not the directory, no exceptions */ Loading @@ -299,7 +344,7 @@ int delete_cache(const char *uuid, const char *pkgname, userid_t userid) int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid) { std::string _codecachedir( create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX); create_data_user_package_path(uuid, userid, pkgname) + CACHE_DIR_POSTFIX); const char* codecachedir = _codecachedir.c_str(); struct stat s; Loading Loading @@ -454,7 +499,7 @@ int rm_dex(const char *path, const char *instruction_set) } } int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, int get_size(const char *uuid, const char *pkgname, int userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int64_t* _asecsize) Loading @@ -471,21 +516,29 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char int64_t asecsize = 0; /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ * on the /system partition and its not on the sdcard. */ if (validate_system_app_path(apkpath) && strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); if (S_ISDIR(s.st_mode)) { d = opendir(apkpath); if (d != NULL) { dfd = dirfd(d); codesize += calculate_dir_size(dfd); closedir(d); } } /* count the forward locked apk as code if it is given */ } } /* count the forward locked apk as code if it is given */ if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') { if (stat(fwdlock_apkpath, &s) == 0) { codesize += stat_size(&s); } } /* count the cached dexfile as code */ if (!create_cache_path(path, apkpath, instruction_set)) { if (stat(path, &s) == 0) { Loading @@ -503,20 +556,28 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char } } /* compute asec size if it is given */ /* compute asec size if it is given */ if (asecpath != NULL && asecpath[0] != '!') { if (stat(asecpath, &s) == 0) { asecsize += stat_size(&s); } } std::string _pkgdir(create_package_data_path(uuid, pkgname, userid)); std::vector<userid_t> users; if (userid == -1) { users = get_known_users(uuid); } else { users.push_back(userid); } for (auto user : users) { std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname)); const char* pkgdir = _pkgdir.c_str(); d = opendir(pkgdir); if (d == NULL) { goto done; PLOG(WARNING) << "Failed to open " << pkgdir; continue; } dfd = dirfd(d); Loading Loading @@ -564,7 +625,7 @@ int get_size(const char *uuid, const char *pkgname, userid_t userid, const char } } closedir(d); done: } *_codesize = codesize; *_datasize = datasize; *_cachesize = cachesize; Loading Loading @@ -1448,7 +1509,7 @@ int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int u struct stat s, libStat; int rc = 0; std::string _pkgdir(create_package_data_path(uuid, pkgname, userId)); std::string _pkgdir(create_data_user_package_path(uuid, userId, pkgname)); std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX); const char* pkgdir = _pkgdir.c_str(); Loading Loading @@ -1639,7 +1700,7 @@ int restorecon_data(const char* uuid, const char* pkgName, // Special case for owner on internal storage if (uuid == nullptr) { std::string path(create_package_data_path(nullptr, pkgName, 0)); std::string path(create_data_user_package_path(nullptr, 0, pkgName)); if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, flags) < 0) { PLOG(ERROR) << "restorecon failed for " << path; Loading
cmds/installd/installd.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -124,10 +124,10 @@ static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused) return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ } static int do_mv_user_data(char **arg, char reply[REPLY_MAX] __unused) static int do_mv_complete_app(char **arg, char reply[REPLY_MAX] __unused) { // from_uuid, to_uuid, pkgname, appid, seinfo return move_user_data(parse_null(arg[0]), parse_null(arg[1]), arg[2], atoi(arg[3]), arg[4]); // from_uuid, to_uuid, package_name, data_app_name, appid, seinfo return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]); } static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) Loading Loading @@ -200,7 +200,7 @@ struct cmdinfo cmds[] = { { "rmcodecache", 3, do_rm_code_cache }, { "getsize", 8, do_get_size }, { "rmuserdata", 3, do_rm_user_data }, { "mvuserdata", 5, do_mv_user_data }, { "mvcompleteapp", 6, do_mv_complete_app }, { "movefiles", 0, do_movefiles }, { "linklib", 4, do_linklib }, { "mkuserdata", 5, do_mk_user_data }, Loading
cmds/installd/installd.h +15 −9 Original line number Diff line number Diff line Loading @@ -142,10 +142,6 @@ typedef struct { /* util.c */ // TODO: rename to create_data_user_package_path std::string create_package_data_path(const char* volume_uuid, const char* package_name, userid_t user); int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, Loading @@ -153,8 +149,15 @@ int create_pkg_path(char path[PKG_PATH_MAX], std::string create_data_path(const char* volume_uuid); std::string create_data_app_path(const char* volume_uuid); std::string create_data_app_package_path(const char* volume_uuid, const char* package_name); std::string create_data_user_path(const char* volume_uuid, userid_t userid); std::string create_data_user_package_path(const char* volume_uuid, userid_t user, const char* package_name); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::vector<userid_t> get_known_users(const char* volume_uuid); Loading Loading @@ -221,8 +224,9 @@ int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int move_user_data(const char* from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo); int move_complete_app(const char* from_uuid, const char *to_uuid, const char *package_name, const char *data_app_name, appid_t appid, const char* seinfo); int make_user_config(userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); Loading @@ -230,9 +234,11 @@ int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid); int move_dex(const char *src, const char *dst, const char *instruction_set); int rm_dex(const char *path, const char *instruction_set); int protect(char *pkgname, gid_t gid); int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int get_size(const char *uuid, const char *pkgname, int userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int free_cache(const char *uuid, int64_t free_size); int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName, const char *instruction_set, int dexopt_needed, bool vm_safe_mode, Loading
cmds/installd/tests/installd_utils_test.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -455,6 +455,13 @@ TEST_F(UtilsTest, CreateDataPath) { create_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b")); } TEST_F(UtilsTest, CreateDataAppPath) { EXPECT_EQ("/data/app", create_data_app_path(nullptr)); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app", create_data_app_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b")); } TEST_F(UtilsTest, CreateDataUserPath) { EXPECT_EQ("/data/data", create_data_user_path(nullptr, 0)); EXPECT_EQ("/data/user/10", create_data_user_path(nullptr, 10)); Loading @@ -475,14 +482,21 @@ TEST_F(UtilsTest, CreateDataMediaPath) { create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10)); } TEST_F(UtilsTest, CreatePackageDataPath) { EXPECT_EQ("/data/data/com.example", create_package_data_path(nullptr, "com.example", 0)); EXPECT_EQ("/data/user/10/com.example", create_package_data_path(nullptr, "com.example", 10)); TEST_F(UtilsTest, CreateDataAppPackagePath) { EXPECT_EQ("/data/app/com.example", create_data_app_package_path(nullptr, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app/com.example", create_data_app_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example")); } TEST_F(UtilsTest, CreateDataUserPackagePath) { EXPECT_EQ("/data/data/com.example", create_data_user_package_path(nullptr, 0, "com.example")); EXPECT_EQ("/data/user/10/com.example", create_data_user_package_path(nullptr, 10, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example", create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 0)); create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0, "com.example")); EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example", create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 10)); create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example")); } }
cmds/installd/utils.cpp +26 −4 Original line number Diff line number Diff line Loading @@ -36,17 +36,32 @@ static bool is_valid_filename(const std::string& name) { } } /** * Create the path name where package app contents should be stored for * the given volume UUID and package name. An empty UUID is assumed to * be internal storage. */ std::string create_data_app_package_path(const char* volume_uuid, const char* package_name) { CHECK(is_valid_filename(package_name)); CHECK(is_valid_package_name(package_name) == 0); return StringPrintf("%s/%s", create_data_app_path(volume_uuid).c_str(), package_name); } /** * 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) { std::string create_data_user_package_path(const char* volume_uuid, userid_t user, const char* package_name) { CHECK(is_valid_filename(package_name)); CHECK(is_valid_package_name(package_name) == 0); return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name); return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name); } int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, Loading @@ -56,7 +71,7 @@ int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, return -1; } std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix); std::string _tmp(create_data_user_package_path(nullptr, userid, pkgname) + postfix); const char* tmp = _tmp.c_str(); if (strlen(tmp) >= PKG_PATH_MAX) { path[0] = '\0'; Loading @@ -76,6 +91,13 @@ std::string create_data_path(const char* volume_uuid) { } } /** * Create the path name for app data. */ std::string create_data_app_path(const char* volume_uuid) { return StringPrintf("%s/app", create_data_path(volume_uuid).c_str()); } /** * Create the path name for user data for a certain userid. */ Loading