Loading cmds/installd/InstalldNativeService.cpp +0 −204 Original line number Diff line number Diff line Loading @@ -92,10 +92,6 @@ 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"; // fsverity assumes the page size is always 4096. If not, the feature can not be // enabled. static constexpr int kVerityPageSize = 4096; Loading Loading @@ -2253,206 +2249,6 @@ out: return res; } static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)nullptr); 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*)nullptr); 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); } 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); 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) // eg /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap static int flatten_path(const char *prefix, const char *suffix, const char *overlay_path, char *idmap_path, size_t N) { if (overlay_path == nullptr || idmap_path == nullptr) { return -1; } const size_t len_overlay_path = strlen(overlay_path); // will access overlay_path + 1 further below; requires absolute path if (len_overlay_path < 2 || *overlay_path != '/') { return -1; } const size_t len_idmap_root = strlen(prefix); const size_t len_suffix = strlen(suffix); if (SIZE_MAX - len_idmap_root < len_overlay_path || SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) { // additions below would cause overflow return -1; } if (N < len_idmap_root + len_overlay_path + len_suffix) { return -1; } memset(idmap_path, 0, N); snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix); char *ch = idmap_path + len_idmap_root; while (*ch != '\0') { if (*ch == '/') { *ch = '@'; } ++ch; } return 0; } binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, const std::string& overlayApkPath, int32_t uid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PATH(targetApkPath); CHECK_ARGUMENT_PATH(overlayApkPath); std::lock_guard<std::recursive_mutex> lock(mLock); const char* target_apk = targetApkPath.c_str(); const char* overlay_apk = overlayApkPath.c_str(); ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid); 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) { ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk); goto fail; } 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; } if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) { ALOGE("idmap cannot chown '%s'\n", idmap_path); goto fail; } if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { ALOGE("idmap cannot chmod '%s'\n", idmap_path); goto fail; } if (!outdated) { close(idmap_fd); return ok(); } pid_t pid; pid = fork(); if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { ALOGE("setgid(%d) failed during idmap\n", uid); exit(1); } if (setuid(uid) != 0) { ALOGE("setuid(%d) failed during idmap\n", uid); exit(1); } if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno)); exit(1); } run_idmap(target_apk, overlay_apk, idmap_fd); exit(1); /* only if exec call to idmap failed */ } else { int status = wait_child(pid); if (status != 0) { ALOGE("idmap failed, status=0x%04x\n", status); goto fail; } } close(idmap_fd); return ok(); fail: if (idmap_fd >= 0) { close(idmap_fd); unlink(idmap_path); } return error(); } binder::Status InstalldNativeService::removeIdmap(const std::string& overlayApkPath) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PATH(overlayApkPath); std::lock_guard<std::recursive_mutex> lock(mLock); const char* overlay_apk = overlayApkPath.c_str(); char idmap_path[PATH_MAX]; if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk, idmap_path, sizeof(idmap_path)) == -1) { ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk); return error(); } if (unlink(idmap_path) < 0) { ALOGE("couldn't unlink idmap file %s\n", idmap_path); return error(); } return ok(); } binder::Status InstalldNativeService::restoreconAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo) { Loading cmds/installd/InstalldNativeService.h +0 −3 Original line number Diff line number Diff line Loading @@ -119,9 +119,6 @@ public: binder::Status destroyProfileSnapshot(const std::string& packageName, const std::string& profileName); binder::Status idmap(const std::string& targetApkPath, const std::string& overlayApkPath, int32_t uid); binder::Status removeIdmap(const std::string& overlayApkPath); binder::Status rmPackageDir(const std::string& packageDir); binder::Status markBootComplete(const std::string& instructionSet); binder::Status freeCache(const std::unique_ptr<std::string>& uuid, int64_t targetFreeBytes, Loading cmds/installd/binder/android/os/IInstalld.aidl +0 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,6 @@ interface IInstalld { @utf8InCpp String profileName, @utf8InCpp String classpath); void destroyProfileSnapshot(@utf8InCpp String packageName, @utf8InCpp String profileName); void idmap(@utf8InCpp String targetApkPath, @utf8InCpp String overlayApkPath, int uid); void removeIdmap(@utf8InCpp String overlayApkPath); void rmPackageDir(@utf8InCpp String packageDir); void markBootComplete(@utf8InCpp String instructionSet); void freeCache(@nullable @utf8InCpp String uuid, long targetFreeBytes, Loading Loading
cmds/installd/InstalldNativeService.cpp +0 −204 Original line number Diff line number Diff line Loading @@ -92,10 +92,6 @@ 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"; // fsverity assumes the page size is always 4096. If not, the feature can not be // enabled. static constexpr int kVerityPageSize = 4096; Loading Loading @@ -2253,206 +2249,6 @@ out: return res; } static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) { execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk, StringPrintf("%d", idmap_fd).c_str(), (char*)nullptr); 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*)nullptr); 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); } 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); 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) // eg /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap static int flatten_path(const char *prefix, const char *suffix, const char *overlay_path, char *idmap_path, size_t N) { if (overlay_path == nullptr || idmap_path == nullptr) { return -1; } const size_t len_overlay_path = strlen(overlay_path); // will access overlay_path + 1 further below; requires absolute path if (len_overlay_path < 2 || *overlay_path != '/') { return -1; } const size_t len_idmap_root = strlen(prefix); const size_t len_suffix = strlen(suffix); if (SIZE_MAX - len_idmap_root < len_overlay_path || SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) { // additions below would cause overflow return -1; } if (N < len_idmap_root + len_overlay_path + len_suffix) { return -1; } memset(idmap_path, 0, N); snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix); char *ch = idmap_path + len_idmap_root; while (*ch != '\0') { if (*ch == '/') { *ch = '@'; } ++ch; } return 0; } binder::Status InstalldNativeService::idmap(const std::string& targetApkPath, const std::string& overlayApkPath, int32_t uid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PATH(targetApkPath); CHECK_ARGUMENT_PATH(overlayApkPath); std::lock_guard<std::recursive_mutex> lock(mLock); const char* target_apk = targetApkPath.c_str(); const char* overlay_apk = overlayApkPath.c_str(); ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid); 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) { ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk); goto fail; } 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; } if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) { ALOGE("idmap cannot chown '%s'\n", idmap_path); goto fail; } if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { ALOGE("idmap cannot chmod '%s'\n", idmap_path); goto fail; } if (!outdated) { close(idmap_fd); return ok(); } pid_t pid; pid = fork(); if (pid == 0) { /* child -- drop privileges before continuing */ if (setgid(uid) != 0) { ALOGE("setgid(%d) failed during idmap\n", uid); exit(1); } if (setuid(uid) != 0) { ALOGE("setuid(%d) failed during idmap\n", uid); exit(1); } if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno)); exit(1); } run_idmap(target_apk, overlay_apk, idmap_fd); exit(1); /* only if exec call to idmap failed */ } else { int status = wait_child(pid); if (status != 0) { ALOGE("idmap failed, status=0x%04x\n", status); goto fail; } } close(idmap_fd); return ok(); fail: if (idmap_fd >= 0) { close(idmap_fd); unlink(idmap_path); } return error(); } binder::Status InstalldNativeService::removeIdmap(const std::string& overlayApkPath) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PATH(overlayApkPath); std::lock_guard<std::recursive_mutex> lock(mLock); const char* overlay_apk = overlayApkPath.c_str(); char idmap_path[PATH_MAX]; if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk, idmap_path, sizeof(idmap_path)) == -1) { ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk); return error(); } if (unlink(idmap_path) < 0) { ALOGE("couldn't unlink idmap file %s\n", idmap_path); return error(); } return ok(); } binder::Status InstalldNativeService::restoreconAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo) { Loading
cmds/installd/InstalldNativeService.h +0 −3 Original line number Diff line number Diff line Loading @@ -119,9 +119,6 @@ public: binder::Status destroyProfileSnapshot(const std::string& packageName, const std::string& profileName); binder::Status idmap(const std::string& targetApkPath, const std::string& overlayApkPath, int32_t uid); binder::Status removeIdmap(const std::string& overlayApkPath); binder::Status rmPackageDir(const std::string& packageDir); binder::Status markBootComplete(const std::string& instructionSet); binder::Status freeCache(const std::unique_ptr<std::string>& uuid, int64_t targetFreeBytes, Loading
cmds/installd/binder/android/os/IInstalld.aidl +0 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,6 @@ interface IInstalld { @utf8InCpp String profileName, @utf8InCpp String classpath); void destroyProfileSnapshot(@utf8InCpp String packageName, @utf8InCpp String profileName); void idmap(@utf8InCpp String targetApkPath, @utf8InCpp String overlayApkPath, int uid); void removeIdmap(@utf8InCpp String overlayApkPath); void rmPackageDir(@utf8InCpp String packageDir); void markBootComplete(@utf8InCpp String instructionSet); void freeCache(@nullable @utf8InCpp String uuid, long targetFreeBytes, Loading