summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorOrion Hodson <oth@google.com>2021-06-30 21:17:53 +0100
committerOrion Hodson <oth@google.com>2021-07-02 12:09:41 +0100
commit50f3251a165e2a72df60dcedfd2b1c520b3a240c (patch)
tree055fce6a08ee3c6cbe2e54c122c6801770b01714 /runtime
parent22f8d34e9983994f78aaf0fd30831ea647282130 (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.cc12
-rw-r--r--runtime/oat_file_manager.cc13
-rw-r--r--runtime/parsed_options.cc6
-rw-r--r--runtime/runtime.cc22
-rw-r--r--runtime/runtime.h7
-rw-r--r--runtime/runtime_options.def1
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)