Change only_use_system_oat_files_ logic.
If we're creating a process which is a zygote, set it to true. Change it
to false on non-system-server fork.
This makes sure that zygote doesn't load oat files from /data, which
would then make system server abort at startup.
Test: 677-fsi, 677-fsi2
Bug: 198531508
Change-Id: I367fcf79f2e60a32457829ddc88b680fc2d00099
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index c6c1b50..884bca1 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -644,14 +644,12 @@
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 e8069d9..eae7c20 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -316,10 +316,10 @@
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 921c6d2..64d039a 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -65,16 +65,19 @@
// 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*> 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::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 abf4ea0..0c1a69b 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -53,7 +53,9 @@
// 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 @@
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 6eaa435..8dbed9b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1390,9 +1390,9 @@
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 @@
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 @@
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 6d89720..b94c475 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -906,6 +906,8 @@
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 @@
# 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