diff options
-rw-r--r-- | libartbase/base/file_utils.cc | 6 | ||||
-rw-r--r-- | runtime/native/dalvik_system_ZygoteHooks.cc | 6 | ||||
-rw-r--r-- | runtime/oat_file_manager.cc | 40 | ||||
-rw-r--r-- | runtime/oat_file_manager.h | 5 | ||||
-rw-r--r-- | runtime/runtime.cc | 13 | ||||
-rwxr-xr-x | test/etc/run-test-jar | 4 |
6 files changed, 34 insertions, 40 deletions
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc index c6c1b50a71..884bca15b7 100644 --- a/libartbase/base/file_utils.cc +++ b/libartbase/base/file_utils.cc @@ -644,14 +644,12 @@ bool LocationIsOnSystem(const std::string& location) { LOG(FATAL) << "LocationIsOnSystem is unsupported on Windows."; return false; #else - UniqueCPtr<const char[]> full_path(realpath(location.c_str(), nullptr)); - return full_path != nullptr && - android::base::StartsWith(full_path.get(), GetAndroidRoot().c_str()); + return android::base::StartsWith(location, GetAndroidRoot().c_str()); #endif } bool LocationIsTrusted(const std::string& location, bool trust_art_apex_data_files) { - if (LocationIsOnSystem(location)) { + if (LocationIsOnSystem(location) || LocationIsOnArtModule(location)) { return true; } return LocationIsOnArtApexData(location) & trust_art_apex_data_files; diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index e8069d9e51..eae7c2066e 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -316,10 +316,10 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, runtime_flags &= ~DISABLE_VERIFIER; } - if ((runtime_flags & ONLY_USE_TRUSTED_OAT_FILES) != 0 || is_system_server) { - runtime->GetOatFileManager().SetOnlyUseTrustedOatFiles(); - runtime_flags &= ~ONLY_USE_TRUSTED_OAT_FILES; + if ((runtime_flags & ONLY_USE_TRUSTED_OAT_FILES) == 0 && !is_system_server) { + runtime->GetOatFileManager().ClearOnlyUseTrustedOatFiles(); } + runtime_flags &= ~ONLY_USE_TRUSTED_OAT_FILES; api_enforcement_policy = hiddenapi::EnforcementPolicyFromInt( (runtime_flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT); diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 921c6d23f1..64d039af3f 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -65,16 +65,19 @@ using android::base::StringPrintf; // If true, we attempt to load the application image if it exists. static constexpr bool kEnableAppImage = true; -const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) { +const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file, + bool in_memory) { // Use class_linker vlog to match the log for dex file registration. VLOG(class_linker) << "Registered oat file " << oat_file->GetLocation(); PaletteNotifyOatFileLoaded(oat_file->GetLocation().c_str()); WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); - CHECK(!only_use_system_oat_files_ || + CHECK(in_memory || + !only_use_system_oat_files_ || LocationIsTrusted(oat_file->GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) || !oat_file->IsExecutable()) - << "Registering a non /system oat file: " << oat_file->GetLocation(); + << "Registering a non /system oat file: " << oat_file->GetLocation() << " android-root=" + << GetAndroidRoot(); DCHECK(oat_file != nullptr); if (kIsDebugBuild) { CHECK(oat_files_.find(oat_file) == oat_files_.end()); @@ -155,7 +158,9 @@ std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles( std::vector<const OatFile*> oat_files; oat_files.reserve(spaces.size()); for (gc::space::ImageSpace* space : spaces) { - oat_files.push_back(RegisterOatFile(space->ReleaseOatFile())); + // The oat file was generated in memory if the image space has a profile. + bool in_memory = !space->GetProfileFile().empty(); + oat_files.push_back(RegisterOatFile(space->ReleaseOatFile(), in_memory)); } return oat_files; } @@ -795,29 +800,14 @@ void OatFileManager::WaitForBackgroundVerificationTasks() { } } +void OatFileManager::ClearOnlyUseTrustedOatFiles() { + only_use_system_oat_files_ = false; +} + void OatFileManager::SetOnlyUseTrustedOatFiles() { ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); - // Make sure all files that were loaded up to this point are on /system. - // Skip the image files as they can encode locations that don't exist (eg not - // containing the arch in the path, or for JIT zygote /nonx/existent). - std::vector<const OatFile*> boot_vector = GetBootOatFiles(); - std::unordered_set<const OatFile*> boot_set(boot_vector.begin(), boot_vector.end()); - - for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { - if (boot_set.find(oat_file.get()) == boot_set.end()) { - // This method is called during runtime initialization before we can call - // Runtime::Current()->DenyArtApexDataFiles(). Since we don't want to fail hard if - // the ART APEX data files are untrusted, just treat them as trusted for the check here. - const bool trust_art_apex_data_files = true; - if (!LocationIsTrusted(oat_file->GetLocation(), trust_art_apex_data_files)) { - // When the file is not in a trusted location, we check whether the oat file has any - // AOT or DEX code. It is a fatal error if it has. - if (CompilerFilter::IsAotCompilationEnabled(oat_file->GetCompilerFilter()) || - oat_file->ContainsDexCode()) { - LOG(FATAL) << "Executing untrusted code from " << oat_file->GetLocation(); - } - } - } + if (!oat_files_.empty()) { + LOG(FATAL) << "Unexpected non-empty loaded oat files "; } only_use_system_oat_files_ = true; } diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h index abf4ea00c1..0c1a69bb1a 100644 --- a/runtime/oat_file_manager.h +++ b/runtime/oat_file_manager.h @@ -53,7 +53,9 @@ class OatFileManager { // Add an oat file to the internal accounting, std::aborts if there already exists an oat file // with the same base address. Returns the oat file pointer from oat_file. - const OatFile* RegisterOatFile(std::unique_ptr<const OatFile> oat_file) + // The `in_memory` parameter is whether the oat file is not present on disk, + // but only in memory (for example files created with memfd). + const OatFile* RegisterOatFile(std::unique_ptr<const OatFile> oat_file, bool in_memory = false) REQUIRES(!Locks::oat_file_manager_lock_); void UnRegisterAndDeleteOatFile(const OatFile* oat_file) @@ -119,6 +121,7 @@ class OatFileManager { void DumpForSigQuit(std::ostream& os); void SetOnlyUseTrustedOatFiles(); + void ClearOnlyUseTrustedOatFiles(); // Spawn a background thread which verifies all classes in the given dex files. void RunBackgroundVerification(const std::vector<const DexFile*>& dex_files, diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 6eaa435ccb..8dbed9b7f9 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1390,9 +1390,9 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { QuasiAtomic::Startup(); - oat_file_manager_ = new OatFileManager; + oat_file_manager_ = new OatFileManager(); - jni_id_manager_.reset(new jni::JniIdManager); + jni_id_manager_.reset(new jni::JniIdManager()); Thread::SetSensitiveThreadHook(runtime_options.GetOrDefault(Opt::HookIsSensitiveThread)); Monitor::Init(runtime_options.GetOrDefault(Opt::LockProfThreshold), @@ -1438,6 +1438,10 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { image_dex2oat_enabled_ = runtime_options.GetOrDefault(Opt::ImageDex2Oat); dump_native_stack_on_sig_quit_ = runtime_options.GetOrDefault(Opt::DumpNativeStackOnSigQuit); + if (is_zygote_ || runtime_options.Exists(Opt::OnlyUseTrustedOatFiles)) { + oat_file_manager_->SetOnlyUseTrustedOatFiles(); + } + vfprintf_ = runtime_options.GetOrDefault(Opt::HookVfprintf); exit_ = runtime_options.GetOrDefault(Opt::HookExit); abort_ = runtime_options.GetOrDefault(Opt::HookAbort); @@ -1981,11 +1985,6 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { VLOG(startup) << "Runtime::Init exiting"; - // Set OnlyUseTrustedOatFiles only after the boot classpath has been set up. - if (runtime_options.Exists(Opt::OnlyUseTrustedOatFiles)) { - oat_file_manager_->SetOnlyUseTrustedOatFiles(); - } - return true; } diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 6d89720548..b94c475c77 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -906,6 +906,8 @@ installapex_test_cmdline="true" linkdirs() { find "$1" -maxdepth 1 -mindepth 1 -type d | xargs -i ln -sf '{}' "$2" + # Also create a link for the boot image. + ln -sf $ANDROID_HOST_OUT/apex/art_boot_images "$2" } if [ "$CREATE_ANDROID_ROOT" = "y" ]; then @@ -915,6 +917,8 @@ if [ "$CREATE_ANDROID_ROOT" = "y" ]; then # TODO Make this overlay more generic. linkroot_overlay_cmdline="linkdirs $OUT_DIR/soong/host/linux_bionic-x86 ${ANDROID_ROOT}" fi + # Replace the boot image to a location expected by the runtime. + DALVIKVM_BOOT_OPT="-Ximage:${ANDROID_ROOT}/art_boot_images/javalib/boot.art" fi if [ "$USE_ZIPAPEX" = "y" ]; then |