diff options
author | Orion Hodson <oth@google.com> | 2021-06-30 21:17:53 +0100 |
---|---|---|
committer | Orion Hodson <oth@google.com> | 2021-07-02 12:09:41 +0100 |
commit | 50f3251a165e2a72df60dcedfd2b1c520b3a240c (patch) | |
tree | 055fce6a08ee3c6cbe2e54c122c6801770b01714 /runtime | |
parent | 22f8d34e9983994f78aaf0fd30831ea647282130 (diff) |
runtime: add -Xdeny-art-apex-data-files
This option prevents the runtime from loading AOT artifacts installed
in /data/misc/apexdata/com.android.art.
(cherry picked from commit 971068dcaf5955634679dbfaf7b562ed52aff772)
Bug: 192049377
Test: manually adding option and running odsign_e2e_tests
Test: adding option and looking at proc/maps for system_server and zygote
Merged-In: I56c7ce55b64de72faf39a06238089fe4b6b84b88
Change-Id: Iacce98009c51b936149435cfb70a3f744a122031
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/oat_file_assistant.cc | 12 | ||||
-rw-r--r-- | runtime/oat_file_manager.cc | 13 | ||||
-rw-r--r-- | runtime/parsed_options.cc | 6 | ||||
-rw-r--r-- | runtime/runtime.cc | 22 | ||||
-rw-r--r-- | runtime/runtime.h | 7 | ||||
-rw-r--r-- | runtime/runtime_options.def | 1 |
6 files changed, 54 insertions, 7 deletions
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index df7b08fe75..2cbc1ea61a 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -454,7 +454,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& // zip_file_only_contains_uncompressed_dex_ is only set during fetching the dex checksums. DCHECK(required_dex_checksums_attempted_); if (only_load_trusted_executable_ && - !LocationIsTrusted(file.GetLocation()) && + !LocationIsTrusted(file.GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) && file.ContainsDexCode() && zip_file_only_contains_uncompressed_dex_) { LOG(ERROR) << "Not loading " @@ -565,7 +565,7 @@ bool OatFileAssistant::DexLocationToOatFilename(const std::string& location, // Check if `location` could have an oat file in the ART APEX data directory. If so, and the // file exists, use it. const std::string apex_data_file = GetApexDataOdexFilename(location, isa); - if (!apex_data_file.empty()) { + if (!apex_data_file.empty() && !Runtime::Current()->DenyArtApexDataFiles()) { if (OS::FileExists(apex_data_file.c_str(), /*check_file_type=*/true)) { *oat_filename = apex_data_file; return true; @@ -817,6 +817,12 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { return nullptr; } + if (LocationIsOnArtApexData(filename_) && Runtime::Current()->DenyArtApexDataFiles()) { + LOG(WARNING) << "OatFileAssistant rejected file " << filename_ + << ": ART apexdata is untrusted."; + return nullptr; + } + std::string error_msg; bool executable = oat_file_assistant_->load_executable_; if (android::base::EndsWith(filename_, kVdexExtension)) { @@ -856,7 +862,7 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { } } else { if (executable && oat_file_assistant_->only_load_trusted_executable_) { - executable = LocationIsTrusted(filename_); + executable = LocationIsTrusted(filename_, /*trust_art_apex_data_files=*/ true); } VLOG(oat) << "Loading " << filename_ << " with executable: " << executable; if (use_fd_) { diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index a891aa3b41..542ea092ff 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -72,7 +72,7 @@ const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oa WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); CHECK(!only_use_system_oat_files_ || - LocationIsTrusted(oat_file->GetLocation()) || + LocationIsTrusted(oat_file->GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) || !oat_file->IsExecutable()) << "Registering a non /system oat file: " << oat_file->GetLocation(); DCHECK(oat_file != nullptr); @@ -756,6 +756,11 @@ void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*> return; } + if (LocationIsOnArtApexData(odex_filename) && Runtime::Current()->DenyArtApexDataFiles()) { + // Ignore vdex file associated with this odex file as the odex file is not trustworthy. + return; + } + { WriterMutexLock mu(self, *Locks::oat_file_manager_lock_); if (verification_thread_pool_ == nullptr) { @@ -800,7 +805,11 @@ void OatFileManager::SetOnlyUseTrustedOatFiles() { for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { if (boot_set.find(oat_file.get()) == boot_set.end()) { - if (!LocationIsTrusted(oat_file->GetLocation())) { + // 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()) || diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index c85c951deb..8ce914406c 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -414,6 +414,8 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize .IntoKey(M::UseStderrLogger) .Define("-Xonly-use-system-oat-files") .IntoKey(M::OnlyUseTrustedOatFiles) + .Define("-Xdeny-art-apex-data-files") + .IntoKey(M::DenyArtApexDataFiles) .Define("-Xverifier-logging-threshold=_") .WithType<unsigned int>() .IntoKey(M::VerifierLoggingThreshold) @@ -719,7 +721,9 @@ bool ParsedOptions::DoParse(const RuntimeOptions& options, } if (!args.Exists(M::CompilerCallbacksPtr) && !args.Exists(M::Image)) { - std::string image = GetDefaultBootImageLocation(GetAndroidRoot()); + const bool deny_art_apex_data_files = args.Exists(M::DenyArtApexDataFiles); + std::string image = + GetDefaultBootImageLocation(GetAndroidRoot(), deny_art_apex_data_files); args.Set(M::Image, image); } diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 713b4c2d4d..1e563dd0e1 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1334,6 +1334,12 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // Reload all the flags value (from system properties and device configs). ReloadAllFlags(__FUNCTION__); + deny_art_apex_data_files_ = runtime_options.Exists(Opt::DenyArtApexDataFiles); + if (deny_art_apex_data_files_) { + // We will run slower without those files if the system has taken an ART APEX update. + LOG(WARNING) << "ART APEX data files are untrusted."; + } + // Early override for logging output. if (runtime_options.Exists(Opt::UseStderrLogger)) { android::base::SetLogger(android::base::StderrLogger); @@ -1397,7 +1403,21 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { } std::string system_oat_filename = ImageHeader::GetOatLocationFromImageLocation( GetSystemImageFilename(image_location_.c_str(), instruction_set_)); - std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation(image_location_); + std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation( + image_location_); + + if (deny_art_apex_data_files_ && (LocationIsOnArtApexData(system_oat_filename) || + LocationIsOnArtApexData(system_oat_location))) { + // This code path exists for completeness, but we don't expect it to be hit. + // + // `deny_art_apex_data_files` defaults to false unless set at the command-line. The image + // locations come from the -Ximage argument and it would need to be specified as being on + // the ART APEX data directory. This combination of flags would say apexdata is compromised, + // use apexdata to load image files, which is obviously not a good idea. + LOG(ERROR) << "Could not open boot oat file from untrusted location: " << system_oat_filename; + return false; + } + std::string error_msg; std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, system_oat_filename, diff --git a/runtime/runtime.h b/runtime/runtime.h index a855a3771b..1486a9ab85 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -896,6 +896,10 @@ class Runtime { return result; } + bool DenyArtApexDataFiles() const { + return deny_art_apex_data_files_; + } + // Whether or not we use MADV_RANDOM on files that are thought to have random access patterns. // This is beneficial for low RAM devices since it reduces page cache thrashing. bool MAdviseRandomAccess() const { @@ -1374,6 +1378,9 @@ class Runtime { // indirection is changed. This is intended only for testing JNI id swapping. bool automatically_set_jni_ids_indirection_; + // True if files in /data/misc/apexdata/com.android.art are considered untrustworthy. + bool deny_art_apex_data_files_; + // Saved environment. class EnvSnapshot { public: diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def index b73f5c1f7e..966bc83407 100644 --- a/runtime/runtime_options.def +++ b/runtime/runtime_options.def @@ -170,6 +170,7 @@ RUNTIME_OPTIONS_KEY (unsigned int, GlobalRefAllocStackTraceLimit, 0) // RUNTIME_OPTIONS_KEY (Unit, UseStderrLogger) RUNTIME_OPTIONS_KEY (Unit, OnlyUseTrustedOatFiles) +RUNTIME_OPTIONS_KEY (Unit, DenyArtApexDataFiles) RUNTIME_OPTIONS_KEY (unsigned int, VerifierLoggingThreshold, 100) RUNTIME_OPTIONS_KEY (bool, FastClassNotFoundException, true) |