summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Calin Juravle <calin@google.com> 2021-04-05 17:43:17 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2021-04-08 04:52:33 +0000
commit92a785785423b99cf903ce0e79d06fbf62ecf51a (patch)
tree09553e0a28050395d2e1a9255af04d93949758f0
parent722992f7b63b5e2962aaba6119402c7b93deb2f4 (diff)
Validate vdex checksums during dex2oat compilation
If the checksums from the vdex files that comes from the .dm archive does not match the input dex files, the compilation will fail. Test: gtest Bug: 184291791 Change-Id: I10db75b4381946d7f2b695ff317d0b4e897a32b0
-rw-r--r--dex2oat/dex2oat.cc38
-rw-r--r--dex2oat/dex2oat_vdex_test.cc30
2 files changed, 68 insertions, 0 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index c8a2cbdcb7..7d463b0634 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1464,6 +1464,10 @@ class Dex2Oat final {
compiler_options_->dex_files_for_oat_file_ = MakeNonOwningPointerVector(opened_dex_files_);
const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
+ if (!ValidateInputVdexChecksums()) {
+ return dex2oat::ReturnCode::kOther;
+ }
+
// Check if we need to downgrade the compiler-filter for size reasons.
// Note: This does not affect the compiler filter already stored in the key-value
// store which is used for determining whether the oat file is up to date,
@@ -1717,6 +1721,40 @@ class Dex2Oat final {
return dex2oat::ReturnCode::kNoFailure;
}
+ // Validates that the input vdex checksums match the source dex checksums.
+ // Note that this is only effective and relevant if the input_vdex_file does not
+ // contain a dex section (e.g. when they come from .dm files).
+ // If the input vdex does contain dex files, the dex files will be opened from there
+ // and so this check is redundant.
+ bool ValidateInputVdexChecksums() {
+ if (input_vdex_file_ == nullptr) {
+ // Nothing to validate
+ return true;
+ }
+ if (input_vdex_file_->GetNumberOfDexFiles()
+ != compiler_options_->dex_files_for_oat_file_.size()) {
+ LOG(ERROR) << "Vdex file contains a different number of dex files than the source. "
+ << " vdex_num=" << input_vdex_file_->GetNumberOfDexFiles()
+ << " dex_source_num=" << compiler_options_->dex_files_for_oat_file_.size();
+ return false;
+ }
+
+ for (size_t i = 0; i < compiler_options_->dex_files_for_oat_file_.size(); i++) {
+ uint32_t dex_source_checksum =
+ compiler_options_->dex_files_for_oat_file_[i]->GetLocationChecksum();
+ uint32_t vdex_checksum = input_vdex_file_->GetLocationChecksum(i);
+ if (dex_source_checksum != vdex_checksum) {
+ LOG(ERROR) << "Vdex file checksum different than source dex checksum for position " << i
+ << std::hex
+ << " vdex_checksum=0x" << vdex_checksum
+ << " dex_source_checksum=0x" << dex_source_checksum
+ << std::dec;
+ return false;
+ }
+ }
+ return true;
+ }
+
// If we need to keep the oat file open for the image writer.
bool ShouldKeepOatFileOpen() const {
return IsImage() && oat_fd_ != File::kInvalidFd;
diff --git a/dex2oat/dex2oat_vdex_test.cc b/dex2oat/dex2oat_vdex_test.cc
index d9a555a3ea..3b980e0784 100644
--- a/dex2oat/dex2oat_vdex_test.cc
+++ b/dex2oat/dex2oat_vdex_test.cc
@@ -266,4 +266,34 @@ TEST_F(Dex2oatVdexTest, VerifyCorruptVdexFile) {
extra_args)) << output_;
}
+// Check that if the input dm a vdex with mismatching checksums the compilation fails
+TEST_F(Dex2oatVdexTest, VerifyInputDmWithMismatchedChecksums) {
+ std::string error_msg;
+
+ // Generate a vdex file for Dex2oatVdexTestDex.
+ std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Dex2oatVdexTestDex"));
+
+ ASSERT_TRUE(RunDex2oat(
+ dex_file->GetLocation(),
+ GetOdex(dex_file),
+ /*public_sdk=*/ nullptr,
+ /*copy_dex_files=*/ false));
+
+ // Create the .dm file with the output.
+ std::string dm_file = GetScratchDir() + "/base.dm";
+ CreateDexMetadata(GetVdex(dex_file), dm_file);
+ std::vector<std::string> extra_args;
+ extra_args.push_back("--dm-file=" + dm_file);
+
+ // Try to compile Main using an input dm which contains the vdex for
+ // Dex2oatVdexTestDex. It should fail.
+ std::unique_ptr<const DexFile> dex_file2(OpenTestDexFile("Main"));
+ ASSERT_FALSE(RunDex2oat(
+ dex_file2->GetLocation(),
+ GetOdex(dex_file2, "v2"),
+ /*public_sdk=*/ nullptr,
+ /*copy_dex_files=*/ false,
+ extra_args)) << output_;
+}
+
} // namespace art