Loading cmds/installd/InstalldNativeService.cpp +70 −8 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ static constexpr const char* PKG_LIB_POSTFIX = "/lib"; static constexpr const char* CACHE_DIR_POSTFIX = "/cache"; static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache"; static constexpr const char *kIdMapPath = "/system/bin/idmap"; static constexpr const char* IDMAP_PREFIX = "/data/resource-cache/"; static constexpr const char* IDMAP_SUFFIX = "@idmap"; Loading Loading @@ -1951,14 +1952,58 @@ out: static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { static const char *IDMAP_BIN = "/system/bin/idmap"; static const size_t MAX_INT_LEN = 32; char idmap_str[MAX_INT_LEN]; execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)NULL); PLOG(ERROR) << "execl (" << kIdMapPath << ") failed"; } static void run_verify_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { execl(kIdMapPath, kIdMapPath, "--verify", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)NULL); PLOG(ERROR) << "execl (" << kIdMapPath << ") failed"; } static bool delete_stale_idmap(const char* target_apk, const char* overlay_apk, const char* idmap_path, int32_t uid) { int idmap_fd = open(idmap_path, O_RDWR); if (idmap_fd < 0) { PLOG(ERROR) << "idmap open failed: " << idmap_path; unlink(idmap_path); return true; } pid_t pid; pid = fork(); if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { LOG(ERROR) << "setgid(" << uid << ") failed during idmap"; exit(1); } if (setuid(uid) != 0) { LOG(ERROR) << "setuid(" << uid << ") failed during idmap"; exit(1); } if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) { PLOG(ERROR) << "flock(" << idmap_path << ") failed during idmap"; exit(1); } snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd); run_verify_idmap(target_apk, overlay_apk, idmap_fd); exit(1); /* only if exec call to deleting stale idmap failed */ } else { int status = wait_child(pid); close(idmap_fd); execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL); ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno)); if (status != 0) { // Failed on verifying if idmap is made from target_apk and overlay_apk. LOG(DEBUG) << "delete stale idmap: " << idmap_path; unlink(idmap_path); return true; } } return false; } // Transform string /a/b/c.apk to (prefix)/a@b@c.apk@(suffix) Loading Loading @@ -2007,6 +2052,8 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, int idmap_fd = -1; char idmap_path[PATH_MAX]; struct stat idmap_stat; bool outdated = false; if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk, idmap_path, sizeof(idmap_path)) == -1) { Loading @@ -2014,8 +2061,18 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, goto fail; } unlink(idmap_path); if (stat(idmap_path, &idmap_stat) < 0) { outdated = true; } else { outdated = delete_stale_idmap(target_apk, overlay_apk, idmap_path, uid); } if (outdated) { idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644); } else { idmap_fd = open(idmap_path, O_RDWR); } if (idmap_fd < 0) { ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno)); goto fail; Loading @@ -2029,6 +2086,11 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, goto fail; } if (!outdated) { close(idmap_fd); return ok(); } pid_t pid; pid = fork(); if (pid == 0) { Loading Loading
cmds/installd/InstalldNativeService.cpp +70 −8 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ static constexpr const char* PKG_LIB_POSTFIX = "/lib"; static constexpr const char* CACHE_DIR_POSTFIX = "/cache"; static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache"; static constexpr const char *kIdMapPath = "/system/bin/idmap"; static constexpr const char* IDMAP_PREFIX = "/data/resource-cache/"; static constexpr const char* IDMAP_SUFFIX = "@idmap"; Loading Loading @@ -1951,14 +1952,58 @@ out: static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { static const char *IDMAP_BIN = "/system/bin/idmap"; static const size_t MAX_INT_LEN = 32; char idmap_str[MAX_INT_LEN]; execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)NULL); PLOG(ERROR) << "execl (" << kIdMapPath << ") failed"; } static void run_verify_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { execl(kIdMapPath, kIdMapPath, "--verify", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)NULL); PLOG(ERROR) << "execl (" << kIdMapPath << ") failed"; } static bool delete_stale_idmap(const char* target_apk, const char* overlay_apk, const char* idmap_path, int32_t uid) { int idmap_fd = open(idmap_path, O_RDWR); if (idmap_fd < 0) { PLOG(ERROR) << "idmap open failed: " << idmap_path; unlink(idmap_path); return true; } pid_t pid; pid = fork(); if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { LOG(ERROR) << "setgid(" << uid << ") failed during idmap"; exit(1); } if (setuid(uid) != 0) { LOG(ERROR) << "setuid(" << uid << ") failed during idmap"; exit(1); } if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) { PLOG(ERROR) << "flock(" << idmap_path << ") failed during idmap"; exit(1); } snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd); run_verify_idmap(target_apk, overlay_apk, idmap_fd); exit(1); /* only if exec call to deleting stale idmap failed */ } else { int status = wait_child(pid); close(idmap_fd); execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL); ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno)); if (status != 0) { // Failed on verifying if idmap is made from target_apk and overlay_apk. LOG(DEBUG) << "delete stale idmap: " << idmap_path; unlink(idmap_path); return true; } } return false; } // Transform string /a/b/c.apk to (prefix)/a@b@c.apk@(suffix) Loading Loading @@ -2007,6 +2052,8 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, int idmap_fd = -1; char idmap_path[PATH_MAX]; struct stat idmap_stat; bool outdated = false; if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk, idmap_path, sizeof(idmap_path)) == -1) { Loading @@ -2014,8 +2061,18 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, goto fail; } unlink(idmap_path); if (stat(idmap_path, &idmap_stat) < 0) { outdated = true; } else { outdated = delete_stale_idmap(target_apk, overlay_apk, idmap_path, uid); } if (outdated) { idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644); } else { idmap_fd = open(idmap_path, O_RDWR); } if (idmap_fd < 0) { ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno)); goto fail; Loading @@ -2029,6 +2086,11 @@ binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, goto fail; } if (!outdated) { close(idmap_fd); return ok(); } pid_t pid; pid = fork(); if (pid == 0) { Loading