Fix checksum verification when opening DexFiles from OatFiles
Change-Id: Ic3d13f3d591c34f159bf0739536a1751c3e7dc75
diff --git a/src/dex_file.cc b/src/dex_file.cc
index cb90e15..16fd407 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -60,18 +60,28 @@
reinterpret_cast<const DexFile::ClassDef*>(NULL));
}
-void DexFile::OpenDexFiles(const std::vector<const char*>& dex_filenames,
- std::vector<const DexFile*>& dex_files,
- const std::string& strip_location_prefix) {
- for (size_t i = 0; i < dex_filenames.size(); i++) {
- const char* dex_filename = dex_filenames[i];
- const DexFile* dex_file = Open(dex_filename, strip_location_prefix);
- if (dex_file == NULL) {
- fprintf(stderr, "could not open .dex from file %s\n", dex_filename);
- exit(EXIT_FAILURE);
+bool DexFile::GetChecksum(const std::string& filename, uint32_t& checksum) {
+ if (IsValidZipFilename(filename)) {
+ UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(filename));
+ if (zip_archive.get() == NULL) {
+ return false;
}
- dex_files.push_back(dex_file);
+ UniquePtr<ZipEntry> zip_entry(zip_archive->Find(kClassesDex));
+ if (zip_entry.get() == NULL) {
+ return false;
+ }
+ checksum = zip_entry->GetCrc32();
+ return true;
}
+ if (IsValidDexFilename(filename)) {
+ UniquePtr<const DexFile> dex_file(DexFile::OpenFile(filename, "", false));
+ if (dex_file.get() == NULL) {
+ return false;
+ }
+ checksum = dex_file->GetHeader().checksum_;
+ return true;
+ }
+ return false;
}
const DexFile* DexFile::Open(const std::string& filename,
@@ -82,7 +92,7 @@
if (!IsValidDexFilename(filename)) {
LOG(WARNING) << "Attempting to open dex file with unknown extension '" << filename << "'";
}
- return DexFile::OpenFile(filename, filename, strip_location_prefix);
+ return DexFile::OpenFile(filename, strip_location_prefix, true);
}
void DexFile::ChangePermissions(int prot) const {
@@ -103,9 +113,9 @@
}
const DexFile* DexFile::OpenFile(const std::string& filename,
- const std::string& original_location,
- const std::string& strip_location_prefix) {
- std::string location(StripLocationPrefix(original_location, strip_location_prefix));
+ const std::string& strip_location_prefix,
+ bool verify) {
+ std::string location(StripLocationPrefix(filename, strip_location_prefix));
if (location.empty()) {
return NULL;
}
@@ -134,14 +144,22 @@
return NULL;
}
close(fd);
- const DexFile* dex_file = OpenMemory(location, map.release());
+
+ if (map->Size() < sizeof(DexFile::Header)) {
+ LOG(ERROR) << "Failed to open dex file '" << filename << "' that is too short to have a header";
+ return NULL;
+ }
+
+ const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
+
+ const DexFile* dex_file = OpenMemory(location, dex_header->checksum_, map.release());
if (dex_file == NULL) {
- LOG(ERROR) << "Failed to open dex file '" << location << "' from memory";
+ LOG(ERROR) << "Failed to open dex file '" << filename << "' from memory";
return NULL;
}
if (!DexFileVerifier::Verify(dex_file, dex_file->Begin(), dex_file->Size())) {
- LOG(ERROR) << "Failed to verify dex file '" << location << "'";
+ LOG(ERROR) << "Failed to verify dex file '" << filename << "'";
return NULL;
}
@@ -189,7 +207,7 @@
return NULL;
}
- const DexFile* dex_file = OpenMemory(location, map.release());
+ const DexFile* dex_file = OpenMemory(location, zip_entry->GetCrc32(), map.release());
if (dex_file == NULL) {
LOG(ERROR) << "Failed to open dex file '" << location << "' from memory";
return NULL;
@@ -206,9 +224,10 @@
const DexFile* DexFile::OpenMemory(const byte* base,
size_t size,
const std::string& location,
+ uint32_t location_checksum,
MemMap* mem_map) {
CHECK_ALIGNED(base, 4); // various dex file structures must be word aligned
- UniquePtr<DexFile> dex_file(new DexFile(base, size, location, mem_map));
+ UniquePtr<DexFile> dex_file(new DexFile(base, size, location, location_checksum, mem_map));
if (!dex_file->Init()) {
return NULL;
} else {