Fix OatFile leak causing dlopen to return stale OatFile contents
Bug: 10917637
Change-Id: If6b7bb8dd9c7aa3d870bd43964f31512385c5d39
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 210386a..800fab0 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -596,6 +596,7 @@
// change process groups, so we don't get reaped by ProcessManager
setpgid(0, 0);
+ // gLogVerbosity.class_linker = true;
VLOG(class_linker) << dex2oat
<< " --runtime-arg -Xms64m"
<< " --runtime-arg -Xmx64m"
@@ -832,10 +833,14 @@
RegisterOatFileLocked(*oat_file);
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
if (oat_dex_file == NULL) {
- LOG(ERROR) << "Failed to find dex file in generated oat file: " << oat_location;
+ LOG(ERROR) << "Failed to find dex file " << dex_location << " in generated oat file: " << oat_location;
return NULL;
}
- return oat_dex_file->OpenDexFile();
+ const DexFile* result = oat_dex_file->OpenDexFile();
+ CHECK_EQ(dex_location_checksum, result->GetLocationChecksum()) << std::hex
+ << "dex_location_checksum=" << dex_location_checksum
+ << " DexFile::GetLocationChecksum()=" << result->GetLocationChecksum();
+ return result;
}
bool ClassLinker::VerifyOatFileChecksums(const OatFile* oat_file,
@@ -870,14 +875,14 @@
std::string image_file(image_header.GetImageRoot(
ImageHeader::kOatLocation)->AsString()->ToModifiedUtf8());
LOG(WARNING) << "oat file " << oat_file->GetLocation()
- << " mismatch ( " << std::hex << oat_file->GetOatHeader().GetImageFileLocationOatChecksum()
+ << " mismatch (" << std::hex << oat_file->GetOatHeader().GetImageFileLocationOatChecksum()
<< ", " << oat_file->GetOatHeader().GetImageFileLocationOatDataBegin()
<< ") with " << image_file
<< " (" << image_oat_checksum << ", " << std::hex << image_oat_data_begin << ")";
}
if (!dex_check) {
LOG(WARNING) << "oat file " << oat_file->GetLocation()
- << " mismatch ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum()
+ << " mismatch (" << std::hex << oat_dex_file->GetDexFileLocationChecksum()
<< ") with " << dex_location
<< " (" << std::hex << dex_location_checksum << ")";
}
@@ -889,6 +894,7 @@
uint32_t dex_location_checksum) {
bool verified = VerifyOatFileChecksums(oat_file, dex_location, dex_location_checksum);
if (!verified) {
+ delete oat_file;
return NULL;
}
RegisterOatFileLocked(*oat_file);
@@ -906,8 +912,8 @@
// Look for an existing file next to dex. for example, for
// /foo/bar/baz.jar, look for /foo/bar/baz.odex.
std::string odex_filename(OatFile::DexFilenameToOdexFilename(dex_location));
- const OatFile* oat_file = FindOatFileFromOatLocationLocked(odex_filename);
- if (oat_file != NULL) {
+ UniquePtr<const OatFile> oat_file(FindOatFileFromOatLocationLocked(odex_filename));
+ if (oat_file.get() != NULL) {
uint32_t dex_location_checksum;
if (!DexFile::GetChecksum(dex_location, dex_location_checksum)) {
// If no classes.dex found in dex_location, it has been stripped, assume oat is up-to-date.
@@ -917,7 +923,7 @@
RegisterOatFileLocked(*oat_file);
return oat_dex_file->OpenDexFile();
}
- const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file,
+ const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file.release(),
dex_location,
dex_location_checksum);
if (dex_file != NULL) {
@@ -927,21 +933,21 @@
// Look for an existing file in the dalvik-cache, validating the result if found
// not found in /foo/bar/baz.odex? try /data/dalvik-cache/foo@bar@baz.jar@classes.dex
std::string cache_location(GetDalvikCacheFilenameOrDie(dex_location));
- oat_file = FindOatFileFromOatLocationLocked(cache_location);
- if (oat_file != NULL) {
+ oat_file.reset(FindOatFileFromOatLocationLocked(cache_location));
+ if (oat_file.get() != NULL) {
uint32_t dex_location_checksum;
if (!DexFile::GetChecksum(dex_location, dex_location_checksum)) {
LOG(WARNING) << "Failed to compute checksum: " << dex_location;
return NULL;
}
- const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file,
+ const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file.release(),
dex_location,
dex_location_checksum);
if (dex_file != NULL) {
return dex_file;
}
- if (TEMP_FAILURE_RETRY(unlink(oat_file->GetLocation().c_str())) != 0) {
- PLOG(FATAL) << "Failed to remove obsolete oat file " << oat_file->GetLocation();
+ if (TEMP_FAILURE_RETRY(unlink(cache_location.c_str())) != 0) {
+ PLOG(FATAL) << "Failed to remove obsolete oat file from " << cache_location;
}
}
LOG(INFO) << "Failed to open oat file from " << odex_filename << " or " << cache_location << ".";