diff options
| author | 2018-03-21 18:16:36 -0700 | |
|---|---|---|
| committer | 2018-03-22 09:45:08 -0700 | |
| commit | e8a494d5937ed9d2a05be6cdb888b6784f14f733 (patch) | |
| tree | 78177f577b992eb35ab3e7e5bbc0d479fb72afa6 | |
| parent | 2e0327ee45c9c2c31ad8a4df3c98d8649ec1f6d1 (diff) | |
Run dex verifier for OOB + compact-dex-level combination
Previously, there was logic to not run the dex verifier if
compact-dex-level was not "none". The idea was that the dex writing
would have run the verifier. This caused issues for OOB APKs since
these don't write out the DEX. This CL moves the dex verifier
avoidance logic to the dex loader for the compact dex input case.
Bug: 75970654
Test: test-art-host
(cherry picked from commit d45863a976c2fd10cf179d8ff42926a7a37c70f0)
Merged-In: Ic7af6857edb8f7d8e449fee6a544f184aad79b3a
Change-Id: I755e706822db189373b3f6983e5f6ceaae5f98ed
| -rw-r--r-- | dex2oat/dex2oat.cc | 8 | ||||
| -rw-r--r-- | dex2oat/dex2oat_test.cc | 33 | ||||
| -rw-r--r-- | libdexfile/dex/dex_file_loader.cc | 2 |
3 files changed, 38 insertions, 5 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 9b6771d3b5..ffd359a555 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1609,11 +1609,9 @@ class Dex2Oat FINAL { // Unzip or copy dex files straight to the oat file. std::vector<std::unique_ptr<MemMap>> opened_dex_files_map; std::vector<std::unique_ptr<const DexFile>> opened_dex_files; - // No need to verify the dex file for: - // 1) Dexlayout since it does the verification. It also may not pass the verification since - // we don't update the dex checksum. - // 2) when we have a vdex file, which means it was already verified. - const bool verify = !DoDexLayoutOptimizations() && (input_vdex_file_ == nullptr); + // No need to verify the dex file when we have a vdex file, which means it was already + // verified. + const bool verify = (input_vdex_file_ == nullptr); if (!oat_writers_[i]->WriteAndOpenDexFiles( vdex_files_[i].get(), rodata_.back(), diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index 5590c8b3ab..5e9782aadf 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -2013,4 +2013,37 @@ TEST_F(Dex2oatTest, QuickenedInput) { ASSERT_EQ(vdex_unquickened->FlushCloseOrErase(), 0) << "Could not flush and close"; } +// Test that compact dex generation with invalid dex files doesn't crash dex2oat. b/75970654 +TEST_F(Dex2oatTest, CompactDexInvalidSource) { + ScratchFile invalid_dex; + { + FILE* file = fdopen(invalid_dex.GetFd(), "w+b"); + ZipWriter writer(file); + writer.StartEntry("classes.dex", ZipWriter::kAlign32); + DexFile::Header header = {}; + StandardDexFile::WriteMagic(header.magic_); + StandardDexFile::WriteCurrentVersion(header.magic_); + header.file_size_ = 4 * KB; + header.data_size_ = 4 * KB; + header.data_off_ = 10 * MB; + header.map_off_ = 10 * MB; + header.class_defs_off_ = 10 * MB; + header.class_defs_size_ = 10000; + ASSERT_GE(writer.WriteBytes(&header, sizeof(header)), 0); + writer.FinishEntry(); + writer.Finish(); + ASSERT_EQ(invalid_dex.GetFile()->Flush(), 0); + } + const std::string dex_location = invalid_dex.GetFilename(); + const std::string odex_location = GetOdexDir() + "/output.odex"; + std::string error_msg; + int status = GenerateOdexForTestWithStatus( + {dex_location}, + odex_location, + CompilerFilter::kQuicken, + &error_msg, + { "--compact-dex-level=fast" }); + ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_; +} + } // namespace art diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc index 758a2f0599..1e0f5ac6ae 100644 --- a/libdexfile/dex/dex_file_loader.cc +++ b/libdexfile/dex/dex_file_loader.cc @@ -348,6 +348,8 @@ std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const uint8_t* base, location_checksum, oat_dex_file, std::move(container))); + // Disable verification for CompactDex input. + verify = false; } else { *error_msg = "Invalid or truncated dex file"; } |