diff options
author | 2021-04-05 17:43:17 -0700 | |
---|---|---|
committer | 2021-04-08 04:52:33 +0000 | |
commit | 92a785785423b99cf903ce0e79d06fbf62ecf51a (patch) | |
tree | 09553e0a28050395d2e1a9255af04d93949758f0 | |
parent | 722992f7b63b5e2962aaba6119402c7b93deb2f4 (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.cc | 38 | ||||
-rw-r--r-- | dex2oat/dex2oat_vdex_test.cc | 30 |
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 |