diff options
| -rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 7 | ||||
| -rw-r--r-- | cmds/installd/InstalldNativeService.h | 3 | ||||
| -rw-r--r-- | cmds/installd/binder/android/os/IInstalld.aidl | 3 | ||||
| -rw-r--r-- | cmds/installd/dexopt.cpp | 59 | ||||
| -rw-r--r-- | cmds/installd/dexopt.h | 6 |
5 files changed, 49 insertions, 29 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 20b960d218..e9a135c14d 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -1729,7 +1729,8 @@ binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t const std::unique_ptr<std::string>& packageName, const std::string& instructionSet, int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags, const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid, - const std::unique_ptr<std::string>& sharedLibraries) { + const std::unique_ptr<std::string>& sharedLibraries, + const std::unique_ptr<std::string>& seInfo) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (packageName && *packageName != "*") { @@ -1744,9 +1745,9 @@ binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t const char* compiler_filter = compilerFilter.c_str(); const char* volume_uuid = uuid ? uuid->c_str() : nullptr; const char* shared_libraries = sharedLibraries ? sharedLibraries->c_str() : nullptr; - + const char* se_info = seInfo ? seInfo->c_str() : nullptr; int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded, - oat_dir, dexFlags, compiler_filter, volume_uuid, shared_libraries); + oat_dir, dexFlags, compiler_filter, volume_uuid, shared_libraries, se_info); return res ? error(res, "Failed to dexopt") : ok(); } diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index f5b7142a12..fe8aa14703 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -82,7 +82,8 @@ public: const std::unique_ptr<std::string>& packageName, const std::string& instructionSet, int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags, const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid, - const std::unique_ptr<std::string>& sharedLibraries); + const std::unique_ptr<std::string>& sharedLibraries, + const std::unique_ptr<std::string>& seInfo); binder::Status rmdex(const std::string& codePath, const std::string& instructionSet); diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl index 03ff96e866..e738b810d8 100644 --- a/cmds/installd/binder/android/os/IInstalld.aidl +++ b/cmds/installd/binder/android/os/IInstalld.aidl @@ -50,7 +50,8 @@ interface IInstalld { @utf8InCpp String instructionSet, int dexoptNeeded, @nullable @utf8InCpp String outputPath, int dexFlags, @utf8InCpp String compilerFilter, @nullable @utf8InCpp String uuid, - @nullable @utf8InCpp String sharedLibraries); + @nullable @utf8InCpp String sharedLibraries, + @nullable @utf8InCpp String seInfo); void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet); diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index f7e8d130a0..63afdcd111 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -36,6 +36,7 @@ #include <cutils/sched_policy.h> #include <log/log.h> // TODO: Move everything to base/logging. #include <private/android_filesystem_config.h> +#include <selinux/android.h> #include <system/thread_defs.h> #include "dexopt.h" @@ -1302,17 +1303,9 @@ static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid, } std::string dex_dir = dex_path.substr(0, dirIndex); - // Assign the gid to the cache gid so that the oat file storage - // is counted towards the app cache. - int32_t cache_gid = multiuser_get_cache_gid( - multiuser_get_user_id(uid), multiuser_get_app_id(uid)); - // If UID doesn't have a specific cache GID, use UID value - if (cache_gid == -1) { - cache_gid = uid; - } - // Create oat file output directory. - if (prepare_app_cache_dir(dex_dir, "oat", 02711, uid, cache_gid) != 0) { + mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH; + if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) { LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path; return false; } @@ -1322,7 +1315,7 @@ static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid, oat_dir_out->assign(oat_dir); // Create oat/isa output directory. - if (prepare_app_cache_dir(*oat_dir_out, instruction_set, 02711, uid, cache_gid) != 0) { + if (prepare_app_cache_dir(*oat_dir_out, instruction_set, oat_dir_mode, uid, uid) != 0) { LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path; return false; } @@ -1366,12 +1359,15 @@ static bool process_dexoptanalyzer_result(const std::string& dex_path, int resul // Processes the dex_path as a secondary dex files and return true if the path dex file should // be compiled. Returns false for errors (logged) or true if the secondary dex path was process // successfully. -// When returning true, dexopt_needed_out is assigned a valid OatFileAsssitant::DexOptNeeded -// code and oat_dir_out is assigned the oat dir path where the oat file should be stored. +// When returning true, the output parameters will be: +// - is_public_out: whether or not the oat file should not be made public +// - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded +// - oat_dir_out: the oat dir path where the oat file should be stored +// - dex_path_out: the real path of the dex file static bool process_secondary_dex_dexopt(const char* original_dex_path, const char* pkgname, int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set, - const char* compiler_filter, int* dexopt_needed_out, std::string* oat_dir_out, - std::string* dex_path_out) { + const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out, + std::string* oat_dir_out, std::string* dex_path_out) { int storage_flag; if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) { @@ -1407,7 +1403,8 @@ static bool process_secondary_dex_dexopt(const char* original_dex_path, const ch } // Check if the path exist. If not, there's nothing to do. - if (access(dex_path.c_str(), F_OK) != 0) { + struct stat dex_path_stat; + if (stat(dex_path.c_str(), &dex_path_stat) != 0) { if (errno == ENOENT) { // Secondary dex files might be deleted any time by the app. // Nothing to do if that's the case @@ -1418,6 +1415,11 @@ static bool process_secondary_dex_dexopt(const char* original_dex_path, const ch } } + // Check if we should make the oat file public. + // Note that if the dex file is not public the compiled code cannot be made public. + *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) && + ((dex_path_stat.st_mode & S_IROTH) != 0); + // Prepare the oat directories. if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, oat_dir_out)) { return false; @@ -1458,14 +1460,14 @@ static bool process_secondary_dex_dexopt(const char* original_dex_path, const ch int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set, int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, - const char* volume_uuid, const char* shared_libraries) { + const char* volume_uuid, const char* shared_libraries, const char* se_info) { CHECK(pkgname != nullptr); CHECK(pkgname[0] != 0); if ((dexopt_flags & ~DEXOPT_MASK) != 0) { LOG_FATAL("dexopt flags contains unknown fields\n"); } - bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0); + bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0; bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0; bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0; bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0; @@ -1477,7 +1479,8 @@ int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* ins std::string dex_real_path; if (is_secondary_dex) { if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid, - instruction_set, compiler_filter, &dexopt_needed, &oat_dir_str, &dex_real_path)) { + instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str, + &dex_real_path)) { oat_dir = oat_dir_str.c_str(); dex_path = dex_real_path.c_str(); if (dexopt_needed == NO_DEXOPT_NEEDED) { @@ -1516,6 +1519,19 @@ int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* ins return -1; } + // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct + // selinux context (we generate them on the fly during the dexopt invocation and they don't + // fully inherit their parent context). + // Note that for primary apk the oat files are created before, in a separate installd + // call which also does the restorecon. TODO(calin): unify the paths. + if (is_secondary_dex) { + if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid, + SELINUX_ANDROID_RESTORECON_RECURSE)) { + LOG(ERROR) << "Failed to restorecon " << oat_dir; + return -1; + } + } + // Create a swap file if necessary. unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path); @@ -1857,8 +1873,9 @@ int dexopt(const char* const params[DEXOPT_PARAM_COUNT]) { atoi(params[6]), // dexopt_flags params[7], // compiler_filter parse_null(params[8]), // volume_uuid - parse_null(params[9])); // shared_libraries - static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param count"); + parse_null(params[9]), // shared_libraries + parse_null(params[10])); // se_info + static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param count"); } } // namespace installd diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index dbf3faeacd..88144b7bc3 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -60,10 +60,10 @@ bool reconcile_secondary_dex_file(const std::string& dex_path, int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set, int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, - const char* volume_uuid, const char* shared_libraries); + const char* volume_uuid, const char* shared_libraries, const char* se_info); -static constexpr size_t DEXOPT_PARAM_COUNT = 10U; -static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param size"); +static constexpr size_t DEXOPT_PARAM_COUNT = 11U; +static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param size"); // Helper for the above, converting arguments. int dexopt(const char* const params[DEXOPT_PARAM_COUNT]); |