summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2018-03-21 18:16:36 -0700
committer Mathieu Chartier <mathieuc@google.com> 2018-03-22 09:45:08 -0700
commite8a494d5937ed9d2a05be6cdb888b6784f14f733 (patch)
tree78177f577b992eb35ab3e7e5bbc0d479fb72afa6
parent2e0327ee45c9c2c31ad8a4df3c98d8649ec1f6d1 (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.cc8
-rw-r--r--dex2oat/dex2oat_test.cc33
-rw-r--r--libdexfile/dex/dex_file_loader.cc2
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";
}