diff options
Diffstat (limited to 'cmds/installd')
-rw-r--r-- | cmds/installd/commands.c | 134 | ||||
-rw-r--r-- | cmds/installd/installd.c | 13 | ||||
-rw-r--r-- | cmds/installd/installd.h | 25 | ||||
-rw-r--r-- | cmds/installd/tests/installd_utils_test.cpp | 4 | ||||
-rw-r--r-- | cmds/installd/utils.c | 69 |
5 files changed, 137 insertions, 108 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index 8e14a2c..e9d6b15 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -108,11 +108,11 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) return 0; } -int uninstall(const char *pkgname, uid_t persona) +int uninstall(const char *pkgname, userid_t userid) { char pkgdir[PKG_PATH_MAX]; - if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) return -1; /* delete contents AND directory, no exceptions */ @@ -173,18 +173,18 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid) return 0; } -int delete_user_data(const char *pkgname, uid_t persona) +int delete_user_data(const char *pkgname, userid_t userid) { char pkgdir[PKG_PATH_MAX]; - if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) return -1; /* delete contents, excluding "lib", but not the directory itself */ return delete_dir_contents(pkgdir, 0, "lib"); } -int make_user_data(const char *pkgname, uid_t uid, uid_t persona) +int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo) { char pkgdir[PKG_PATH_MAX]; char applibdir[PKG_PATH_MAX]; @@ -192,10 +192,10 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona) struct stat libStat; // Create the data dir for the package - if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) { + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) { return -1; } - if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) { + if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) { ALOGE("cannot create package lib symlink origin path\n"); return -1; } @@ -245,7 +245,7 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona) return -1; } - if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) { + if (selinux_android_setfilecon2(pkgdir, pkgname, seinfo, uid) < 0) { ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); unlink(libsymlink); unlink(pkgdir); @@ -262,10 +262,10 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona) return 0; } -int delete_persona(uid_t persona) +int delete_user(userid_t userid) { char data_path[PKG_PATH_MAX]; - if (create_persona_path(data_path, persona)) { + if (create_user_path(data_path, userid)) { return -1; } if (delete_dir_contents(data_path, 1, NULL)) { @@ -273,7 +273,7 @@ int delete_persona(uid_t persona) } char media_path[PATH_MAX]; - if (create_persona_media_path(media_path, (userid_t) persona) == -1) { + if (create_user_media_path(media_path, userid) == -1) { return -1; } if (delete_dir_contents(media_path, 1, NULL) == -1) { @@ -283,11 +283,11 @@ int delete_persona(uid_t persona) return 0; } -int delete_cache(const char *pkgname, uid_t persona) +int delete_cache(const char *pkgname, userid_t userid) { char cachedir[PKG_PATH_MAX]; - if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, persona)) + if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid)) return -1; /* delete contents, not the directory, no exceptions */ @@ -319,7 +319,7 @@ int free_cache(int64_t free_size) cache = start_cache_collection(); // Collect cache files for primary user. - if (create_persona_path(tmpdir, 0) == 0) { + if (create_user_path(tmpdir, 0) == 0) { //ALOGI("adding cache files from %s\n", tmpdir); add_cache_files(cache, tmpdir, "cache"); } @@ -420,7 +420,7 @@ int rm_dex(const char *path) } } -int get_size(const char *pkgname, int persona, const char *apkpath, +int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int64_t* _asecsize) @@ -477,7 +477,7 @@ int get_size(const char *pkgname, int persona, const char *apkpath, } } - if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, persona)) { + if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) { goto done; } @@ -540,7 +540,6 @@ done: } -/* a simpler version of dexOptGenerateCacheFileName() */ int create_cache_path(char path[PKG_PATH_MAX], const char *src) { char *tmp; @@ -580,7 +579,7 @@ int create_cache_path(char path[PKG_PATH_MAX], const char *src) } static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name, - const char* dexopt_flags) + const char* output_file_name, const char* dexopt_flags) { static const char* DEX_OPT_BIN = "/system/bin/dexopt"; static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig @@ -590,11 +589,35 @@ static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name, sprintf(zip_num, "%d", zip_fd); sprintf(odex_num, "%d", odex_fd); + ALOGV("Running %s in=%s out=%s\n", DEX_OPT_BIN, input_file_name, output_file_name); execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name, dexopt_flags, (char*) NULL); ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno)); } +static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, + const char* output_file_name, const char* dexopt_flags) +{ + static const char* DEX2OAT_BIN = "/system/bin/dex2oat"; + static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig + char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN]; + char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX]; + char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN]; + char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX]; + + sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd); + sprintf(zip_location_arg, "--zip-location=%s", input_file_name); + sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd); + sprintf(oat_location_arg, "--oat-location=%s", output_file_name); + + ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name); + execl(DEX2OAT_BIN, DEX2OAT_BIN, + zip_fd_arg, zip_location_arg, + oat_fd_arg, oat_location_arg, + (char*) NULL); + ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno)); +} + static int wait_dexopt(pid_t pid, const char* apk_path) { int status; @@ -631,31 +654,32 @@ int dexopt(const char *apk_path, uid_t uid, int is_public) { struct utimbuf ut; struct stat apk_stat, dex_stat; - char dex_path[PKG_PATH_MAX]; + char out_path[PKG_PATH_MAX]; char dexopt_flags[PROPERTY_VALUE_MAX]; + char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX]; char *end; - int res, zip_fd=-1, odex_fd=-1; + int res, zip_fd=-1, out_fd=-1; - /* Before anything else: is there a .odex file? If so, we have - * pre-optimized the apk and there is nothing to do here. - */ if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { return -1; } /* platform-specific flags affecting optimization and verification */ property_get("dalvik.vm.dexopt-flags", dexopt_flags, ""); + ALOGV("dalvik.vm.dexopt_flags=%s\n", dexopt_flags); - strcpy(dex_path, apk_path); - end = strrchr(dex_path, '.'); - if (end != NULL) { - strcpy(end, ".odex"); - if (stat(dex_path, &dex_stat) == 0) { - return 0; - } + /* The command to run depend ones the value of persist.sys.dalvik.vm.lib */ + property_get("persist.sys.dalvik.vm.lib", persist_sys_dalvik_vm_lib, "libdvm.so"); + + /* Before anything else: is there a .odex file? If so, we have + * precompiled the apk and there is nothing to do here. + */ + sprintf(out_path, "%s%s", apk_path, ".odex"); + if (stat(out_path, &dex_stat) == 0) { + return 0; } - if (create_cache_path(dex_path, apk_path)) { + if (create_cache_path(out_path, apk_path)) { return -1; } @@ -664,24 +688,24 @@ int dexopt(const char *apk_path, uid_t uid, int is_public) zip_fd = open(apk_path, O_RDONLY, 0); if (zip_fd < 0) { - ALOGE("dexopt cannot open '%s' for input\n", apk_path); + ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path); return -1; } - unlink(dex_path); - odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644); - if (odex_fd < 0) { - ALOGE("dexopt cannot open '%s' for output\n", dex_path); + unlink(out_path); + out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644); + if (out_fd < 0) { + ALOGE("installd cannot open '%s' for output during dexopt\n", out_path); goto fail; } - if (fchmod(odex_fd, + if (fchmod(out_fd, S_IRUSR|S_IWUSR|S_IRGRP | (is_public ? S_IROTH : 0)) < 0) { - ALOGE("dexopt cannot chmod '%s'\n", dex_path); + ALOGE("installd cannot chmod '%s' during dexopt\n", out_path); goto fail; } - if (fchown(odex_fd, AID_SYSTEM, uid) < 0) { - ALOGE("dexopt cannot chown '%s'\n", dex_path); + if (fchown(out_fd, AID_SYSTEM, uid) < 0) { + ALOGE("installd cannot chown '%s' during dexopt\n", out_path); goto fail; } @@ -692,11 +716,11 @@ int dexopt(const char *apk_path, uid_t uid, int is_public) if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { - ALOGE("setgid(%d) failed during dexopt\n", uid); + ALOGE("setgid(%d) failed in installd during dexopt\n", uid); exit(64); } if (setuid(uid) != 0) { - ALOGE("setuid(%d) during dexopt\n", uid); + ALOGE("setuid(%d) failed in installd during dexopt\n", uid); exit(65); } // drop capabilities @@ -709,33 +733,39 @@ int dexopt(const char *apk_path, uid_t uid, int is_public) ALOGE("capset failed: %s\n", strerror(errno)); exit(66); } - if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) { - ALOGE("flock(%s) failed: %s\n", dex_path, strerror(errno)); + if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { + ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); exit(67); } - run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags); + if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) { + run_dexopt(zip_fd, out_fd, apk_path, out_path, dexopt_flags); + } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) { + run_dex2oat(zip_fd, out_fd, apk_path, out_path, dexopt_flags); + } else { + exit(69); /* Unexpected persist.sys.dalvik.vm.lib value */ + } exit(68); /* only get here on exec failure */ } else { res = wait_dexopt(pid, apk_path); if (res != 0) { - ALOGE("dexopt failed on '%s' res = %d\n", dex_path, res); + ALOGE("dexopt in='%s' out='%s' res=%d\n", apk_path, out_path, res); goto fail; } } ut.actime = apk_stat.st_atime; ut.modtime = apk_stat.st_mtime; - utime(dex_path, &ut); - - close(odex_fd); + utime(out_path, &ut); + + close(out_fd); close(zip_fd); return 0; fail: - if (odex_fd >= 0) { - close(odex_fd); - unlink(dex_path); + if (out_fd >= 0) { + close(out_fd); + unlink(out_path); } if (zip_fd >= 0) { close(zip_fd); diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index 83b2b4e..f52cee0 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -85,7 +85,7 @@ static int do_get_size(char **arg, char reply[REPLY_MAX]) int64_t asecsize = 0; int res = 0; - /* pkgdir, persona, apkpath */ + /* pkgdir, userid, apkpath */ res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5], &codesize, &datasize, &cachesize, &asecsize); @@ -105,12 +105,13 @@ static int do_rm_user_data(char **arg, char reply[REPLY_MAX]) static int do_mk_user_data(char **arg, char reply[REPLY_MAX]) { - return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, userid */ + return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]); + /* pkgname, uid, userid, seinfo */ } static int do_rm_user(char **arg, char reply[REPLY_MAX]) { - return delete_persona(atoi(arg[0])); /* userid */ + return delete_user(atoi(arg[0])); /* userid */ } static int do_movefiles(char **arg, char reply[REPLY_MAX]) @@ -144,7 +145,7 @@ struct cmdinfo cmds[] = { { "rmuserdata", 2, do_rm_user_data }, { "movefiles", 0, do_movefiles }, { "linklib", 3, do_linklib }, - { "mkuserdata", 3, do_mk_user_data }, + { "mkuserdata", 4, do_mk_user_data }, { "rmuser", 1, do_rm_user }, }; @@ -200,7 +201,7 @@ static int execute(int s, char cmd[BUFFER_MAX]) unsigned short count; int ret = -1; -// ALOGI("execute('%s')\n", cmd); + // ALOGI("execute('%s')\n", cmd); /* default reply is "" */ reply[0] = 0; @@ -242,7 +243,7 @@ done: if (n > BUFFER_MAX) n = BUFFER_MAX; count = n; -// ALOGI("reply: '%s'\n", cmd); + // ALOGI("reply: '%s'\n", cmd); if (writex(s, &count, sizeof(count))) return -1; if (writex(s, cmd, count)) return -1; return 0; diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index fbfc876..9ca2f86 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -78,9 +78,6 @@ #define PKG_NAME_MAX 128 /* largest allowed package name */ #define PKG_PATH_MAX 256 /* max size of any path we use */ -#define PER_USER_RANGE ((uid_t)100000) /* range of uids per user - uid = persona * PER_USER_RANGE + appid */ - /* data structures */ typedef struct { @@ -138,17 +135,17 @@ int create_pkg_path_in_dir(char path[PKG_PATH_MAX], int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, - uid_t persona); + userid_t userid); -int create_persona_path(char path[PKG_PATH_MAX], - uid_t persona); +int create_user_path(char path[PKG_PATH_MAX], + userid_t userid); -int create_persona_media_path(char path[PKG_PATH_MAX], userid_t userid); +int create_user_media_path(char path[PKG_PATH_MAX], userid_t userid); int create_move_path(char path[PKG_PATH_MAX], const char* pkgname, const char* leaf, - uid_t persona); + userid_t userid); int is_valid_package_name(const char* pkgname); @@ -193,17 +190,17 @@ int ensure_media_user_dirs(userid_t userid); /* commands.c */ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo); -int uninstall(const char *pkgname, uid_t persona); +int uninstall(const char *pkgname, userid_t userid); int renamepkg(const char *oldpkgname, const char *newpkgname); int fix_uid(const char *pkgname, uid_t uid, gid_t gid); -int delete_user_data(const char *pkgname, uid_t persona); -int make_user_data(const char *pkgname, uid_t uid, uid_t persona); -int delete_persona(uid_t persona); -int delete_cache(const char *pkgname, uid_t persona); +int delete_user_data(const char *pkgname, userid_t userid); +int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); +int delete_user(userid_t userid); +int delete_cache(const char *pkgname, userid_t userid); int move_dex(const char *src, const char *dst); int rm_dex(const char *path); int protect(char *pkgname, gid_t gid); -int get_size(const char *pkgname, int persona, const char *apkpath, const char *libdirpath, +int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int free_cache(int64_t free_size); diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp index 7cb9b37..0b182af 100644 --- a/cmds/installd/tests/installd_utils_test.cpp +++ b/cmds/installd/tests/installd_utils_test.cpp @@ -340,7 +340,7 @@ TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) { TEST_F(UtilsTest, CreatePersonaPath_Primary) { char path[PKG_PATH_MAX]; - EXPECT_EQ(0, create_persona_path(path, 0)) + EXPECT_EQ(0, create_user_path(path, 0)) << "Should successfully build primary user path."; EXPECT_STREQ("/data/data/", path) @@ -350,7 +350,7 @@ TEST_F(UtilsTest, CreatePersonaPath_Primary) { TEST_F(UtilsTest, CreatePersonaPath_Secondary) { char path[PKG_PATH_MAX]; - EXPECT_EQ(0, create_persona_path(path, 1)) + EXPECT_EQ(0, create_user_path(path, 1)) << "Should successfully build primary user path."; EXPECT_STREQ("/data/user/1/", path) diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c index 625a35e..ef634c6 100644 --- a/cmds/installd/utils.c +++ b/cmds/installd/utils.c @@ -53,38 +53,39 @@ int create_pkg_path_in_dir(char path[PKG_PATH_MAX], /** * Create the package path name for a given package name with a postfix for - * a certain persona. Returns 0 on success, and -1 on failure. + * a certain userid. Returns 0 on success, and -1 on failure. */ int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, - uid_t persona) + userid_t userid) { - size_t uid_len; - char* persona_prefix; - if (persona == 0) { - persona_prefix = PRIMARY_USER_PREFIX; - uid_len = 0; + size_t userid_len; + char* userid_prefix; + if (userid == 0) { + userid_prefix = PRIMARY_USER_PREFIX; + userid_len = 0; } else { - persona_prefix = SECONDARY_USER_PREFIX; - uid_len = snprintf(NULL, 0, "%d", persona); + userid_prefix = SECONDARY_USER_PREFIX; + userid_len = snprintf(NULL, 0, "%d", userid); } - const size_t prefix_len = android_data_dir.len + strlen(persona_prefix) + uid_len + 1 /*slash*/; + const size_t prefix_len = android_data_dir.len + strlen(userid_prefix) + + userid_len + 1 /*slash*/; char prefix[prefix_len + 1]; char *dst = prefix; size_t dst_size = sizeof(prefix); if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 - || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { + || append_and_increment(&dst, userid_prefix, &dst_size) < 0) { ALOGE("Error building prefix for APK path"); return -1; } - if (persona != 0) { - int ret = snprintf(dst, dst_size, "%d/", persona); - if (ret < 0 || (size_t) ret != uid_len + 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; } @@ -98,39 +99,39 @@ int create_pkg_path(char path[PKG_PATH_MAX], } /** - * Create the path name for user data for a certain persona. + * Create the path name for user data for a certain userid. * Returns 0 on success, and -1 on failure. */ -int create_persona_path(char path[PKG_PATH_MAX], - uid_t persona) +int create_user_path(char path[PKG_PATH_MAX], + userid_t userid) { - size_t uid_len; - char* persona_prefix; - if (persona == 0) { - persona_prefix = PRIMARY_USER_PREFIX; - uid_len = 0; + size_t userid_len; + char* userid_prefix; + if (userid == 0) { + userid_prefix = PRIMARY_USER_PREFIX; + userid_len = 0; } else { - persona_prefix = SECONDARY_USER_PREFIX; - uid_len = snprintf(NULL, 0, "%d/", persona); + userid_prefix = SECONDARY_USER_PREFIX; + userid_len = snprintf(NULL, 0, "%d/", userid); } char *dst = path; size_t dst_size = PKG_PATH_MAX; if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 - || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { + || append_and_increment(&dst, userid_prefix, &dst_size) < 0) { ALOGE("Error building prefix for user path"); return -1; } - if (persona != 0) { - if (dst_size < uid_len + 1) { + if (userid != 0) { + if (dst_size < userid_len + 1) { ALOGE("Error building user path"); return -1; } - int ret = snprintf(dst, dst_size, "%d/", persona); - if (ret < 0 || (size_t) ret != uid_len) { - ALOGE("Error appending persona id to path"); + int ret = snprintf(dst, dst_size, "%d/", userid); + if (ret < 0 || (size_t) ret != userid_len) { + ALOGE("Error appending userid to path"); return -1; } } @@ -138,10 +139,10 @@ int create_persona_path(char path[PKG_PATH_MAX], } /** - * Create the path name for media for a certain persona. + * Create the path name for media for a certain userid. * Returns 0 on success, and -1 on failure. */ -int create_persona_media_path(char path[PATH_MAX], userid_t userid) { +int create_user_media_path(char path[PATH_MAX], userid_t userid) { if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) { return -1; } @@ -151,7 +152,7 @@ int create_persona_media_path(char path[PATH_MAX], userid_t userid) { int create_move_path(char path[PKG_PATH_MAX], const char* pkgname, const char* leaf, - uid_t persona) + userid_t userid) { if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { @@ -997,7 +998,7 @@ int ensure_media_user_dirs(userid_t userid) { char path[PATH_MAX]; // Ensure /data/media/<userid> exists - create_persona_media_path(media_user_path, userid); + create_user_media_path(media_user_path, userid); if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { return -1; } |