summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-14 07:49:36 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-14 07:49:36 +0000
commit89cc90b242351416b1c2a952721381e7186dfe28 (patch)
treec820706e3e7f1033fa6c11a8369e7d276e6de5ec
parentb91a6ee768980d244dbfc3ae7a90122ff7330a7d (diff)
parentc4be0fcab2f88a629251a38fd2ff20e1e604e20f (diff)
downloadart-android12-mainline-ipsec-release.tar.gz
Snap for 8180713 from c4be0fcab2f88a629251a38fd2ff20e1e604e20f to mainline-ipsec-releaseandroid-mainline-12.0.0_r88android12-mainline-ipsec-release
Change-Id: I93e46c51436d696339e390205f8a4f1a88b01605
-rw-r--r--OWNERS3
-rw-r--r--libartbase/base/file_magic.cc4
-rw-r--r--runtime/gc/space/image_space.cc93
-rw-r--r--runtime/gc/space/image_space.h10
-rw-r--r--test/OWNERS1
5 files changed, 105 insertions, 6 deletions
diff --git a/OWNERS b/OWNERS
index 1d8d2ba8ce..f9f6035ceb 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,13 +3,16 @@ hboehm@google.com
jiakaiz@google.com
lokeshgidra@google.com
mast@google.com
+miguelaranda@google.com
mingaleev@google.com
+mythria@google.com
ngeoffray@google.com
nikitai@google.com
oth@google.com
prb@google.com
rpl@google.com
skvadrik@google.com
+solanes@google.com
sorinbasca@google.com
vichang@google.com
vmarko@google.com
diff --git a/libartbase/base/file_magic.cc b/libartbase/base/file_magic.cc
index 1471c59b73..21b762f6e0 100644
--- a/libartbase/base/file_magic.cc
+++ b/libartbase/base/file_magic.cc
@@ -44,6 +44,10 @@ File OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_
}
bool ReadMagicAndReset(int fd, uint32_t* magic, std::string* error_msg) {
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ *error_msg = StringPrintf("Failed to seek to beginning of file : %s", strerror(errno));
+ return false;
+ }
int n = TEMP_FAILURE_RETRY(read(fd, magic, sizeof(*magic)));
if (n != sizeof(*magic)) {
*error_msg = StringPrintf("Failed to find magic");
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 4eb7f25de0..3a92965114 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -25,7 +25,6 @@
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "android-base/unique_fd.h"
-
#include "arch/instruction_set.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
@@ -1503,6 +1502,12 @@ class ImageSpace::BootImageLayout {
const char* file_description,
/*out*/std::string* error_msg);
+ bool ValidateOatFile(const std::string& base_location,
+ const std::string& base_filename,
+ size_t bcp_index,
+ size_t component_count,
+ /*out*/std::string* error_msg);
+
bool ReadHeader(const std::string& base_location,
const std::string& base_filename,
size_t bcp_index,
@@ -1811,6 +1816,61 @@ bool ImageSpace::BootImageLayout::ValidateHeader(const ImageHeader& header,
return true;
}
+bool ImageSpace::BootImageLayout::ValidateOatFile(
+ const std::string& base_location,
+ const std::string& base_filename,
+ size_t bcp_index,
+ size_t component_count,
+ /*out*/std::string* error_msg) {
+ std::string art_filename = ExpandLocation(base_filename, bcp_index);
+ std::string art_location = ExpandLocation(base_location, bcp_index);
+ std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(art_filename);
+ std::string oat_location = ImageHeader::GetOatLocationFromImageLocation(art_location);
+ int oat_fd = -1;
+ int vdex_fd = -1;
+ auto dex_filenames =
+ ArrayRef<const std::string>(boot_class_path_).SubArray(bcp_index, component_count);
+ auto dex_fds = ArrayRef<const int>();
+ // We open the oat file here only for validating that it's up-to-date. We don't open it as
+ // executable or mmap it to a reserved space. This `OatFile` object will be dropped after
+ // validation, and will not go into the `ImageSpace`.
+ std::unique_ptr<OatFile> oat_file;
+ DCHECK_EQ(oat_fd >= 0, vdex_fd >= 0);
+ if (oat_fd >= 0) {
+ oat_file.reset(OatFile::Open(
+ /*zip_fd=*/ -1,
+ vdex_fd,
+ oat_fd,
+ oat_location,
+ /*executable=*/ false,
+ /*low_4gb=*/ false,
+ dex_filenames,
+ /*reservation=*/ nullptr,
+ error_msg));
+ } else {
+ oat_file.reset(OatFile::Open(
+ /*zip_fd=*/ -1,
+ oat_filename,
+ oat_location,
+ /*executable=*/ false,
+ /*low_4gb=*/ false,
+ dex_filenames,
+ /*reservation=*/ nullptr,
+ error_msg));
+ }
+ if (oat_file == nullptr) {
+ *error_msg = StringPrintf("Failed to open oat file '%s' when validating it for image '%s': %s",
+ oat_filename.c_str(),
+ art_location.c_str(),
+ error_msg->c_str());
+ return false;
+ }
+ if (!ImageSpace::ValidateOatFile(*oat_file, error_msg, dex_filenames, dex_fds)) {
+ return false;
+ }
+ return true;
+}
+
bool ImageSpace::BootImageLayout::ReadHeader(const std::string& base_location,
const std::string& base_filename,
size_t bcp_index,
@@ -1828,6 +1888,15 @@ bool ImageSpace::BootImageLayout::ReadHeader(const std::string& base_location,
return false;
}
+ // Validate oat files. We do it here so that the boot image will be re-compiled in memory if it's
+ // outdated.
+ size_t component_count = (header.GetImageSpaceCount() == 1u) ? header.GetComponentCount() : 1u;
+ for (size_t i = 0; i < header.GetImageSpaceCount(); i++) {
+ if (!ValidateOatFile(base_location, base_filename, bcp_index + i, component_count, error_msg)) {
+ return false;
+ }
+ }
+
if (chunks_.empty()) {
base_address_ = reinterpret_cast32<uint32_t>(header.GetImageBegin());
}
@@ -3120,6 +3189,8 @@ bool ImageSpace::BootImageLoader::LoadFromSystem(
return false;
}
+ // Load the image. We don't validate oat files in this stage because they have been validated
+ // before.
if (!LoadImage(layout,
/*validate_oat_file=*/ false,
extra_reservation_size,
@@ -3268,20 +3339,32 @@ void ImageSpace::Dump(std::ostream& os) const {
}
bool ImageSpace::ValidateOatFile(const OatFile& oat_file, std::string* error_msg) {
+ return ValidateOatFile(oat_file, error_msg, ArrayRef<const std::string>(), ArrayRef<const int>());
+}
+
+bool ImageSpace::ValidateOatFile(const OatFile& oat_file,
+ std::string* error_msg,
+ ArrayRef<const std::string> dex_filenames,
+ ArrayRef<const int> dex_fds) {
const ArtDexFileLoader dex_file_loader;
+ size_t dex_file_index = 0;
for (const OatDexFile* oat_dex_file : oat_file.GetOatDexFiles()) {
- const std::string& dex_file_location = oat_dex_file->GetDexFileLocation();
-
// Skip multidex locations - These will be checked when we visit their
// corresponding primary non-multidex location.
- if (DexFileLoader::IsMultiDexLocation(dex_file_location.c_str())) {
+ if (DexFileLoader::IsMultiDexLocation(oat_dex_file->GetDexFileLocation().c_str())) {
continue;
}
+ DCHECK(dex_filenames.empty() || dex_file_index < dex_filenames.size());
+ const std::string& dex_file_location =
+ dex_filenames.empty() ? oat_dex_file->GetDexFileLocation() : dex_filenames[dex_file_index];
+ int dex_fd = dex_file_index < dex_fds.size() ? dex_fds[dex_file_index] : -1;
+ dex_file_index++;
+
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations_ignored;
if (!dex_file_loader.GetMultiDexChecksums(
- dex_file_location.c_str(), &checksums, &dex_locations_ignored, error_msg)) {
+ dex_file_location.c_str(), &checksums, &dex_locations_ignored, error_msg, dex_fd)) {
*error_msg = StringPrintf("ValidateOatFile failed to get checksums of dex file '%s' "
"referenced by oat file %s: %s",
dex_file_location.c_str(),
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 545f659c68..350b9883bb 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -266,6 +266,16 @@ class ImageSpace : public MemMapSpace {
// This function is exposed for testing purposes.
static bool ValidateOatFile(const OatFile& oat_file, std::string* error_msg);
+ // Same as above, but allows to use `dex_filenames` and `dex_fds` to find the dex files instead of
+ // using the dex filenames in the header of the oat file. This overload is useful when the actual
+ // dex filenames are different from what's in the header (e.g., when we run dex2oat on host), or
+ // when the runtime can only access files through FDs (e.g., when we run dex2oat on target in a
+ // restricted SELinux domain).
+ static bool ValidateOatFile(const OatFile& oat_file,
+ std::string* error_msg,
+ ArrayRef<const std::string> dex_filenames,
+ ArrayRef<const int> dex_fds);
+
// Return the end of the image which includes non-heap objects such as ArtMethods and ArtFields.
uint8_t* GetImageEnd() const {
return Begin() + GetImageHeader().GetImageSize();
diff --git a/test/OWNERS b/test/OWNERS
index 28d5064aff..7d11748d44 100644
--- a/test/OWNERS
+++ b/test/OWNERS
@@ -1,4 +1,3 @@
# See also ART owners in the parent directory.
rpl@google.com
dsrbecky@google.com
-*