Fix double close in dex2oat when BCP is passed as FDs
Bug: 191052821
Test: Modify odrefresh to pass BCP as FDs to dex2oat. Run w/ --force-compile.
# With thix fix, no longer seeing "fdsan: double-close of file
descriptor 24 detected"
Change-Id: Iac09b06c8e7aa93114896632cdea6c610662455b
diff --git a/libartbase/base/zip_archive.cc b/libartbase/base/zip_archive.cc
index 6abcdc5..70778e7 100644
--- a/libartbase/base/zip_archive.cc
+++ b/libartbase/base/zip_archive.cc
@@ -246,11 +246,22 @@
}
ZipArchive* ZipArchive::OpenFromFd(int fd, const char* filename, std::string* error_msg) {
+ return OpenFromFdInternal(fd, /*assume_ownership=*/true, filename, error_msg);
+}
+
+ZipArchive* ZipArchive::OpenFromOwnedFd(int fd, const char* filename, std::string* error_msg) {
+ return OpenFromFdInternal(fd, /*assume_ownership=*/false, filename, error_msg);
+}
+
+ZipArchive* ZipArchive::OpenFromFdInternal(int fd,
+ bool assume_ownership,
+ const char* filename,
+ std::string* error_msg) {
DCHECK(filename != nullptr);
DCHECK_GT(fd, 0);
ZipArchiveHandle handle;
- const int32_t error = OpenArchiveFd(fd, filename, &handle);
+ const int32_t error = OpenArchiveFd(fd, filename, &handle, assume_ownership);
if (error != 0) {
*error_msg = std::string(ErrorCodeString(error));
CloseArchive(handle);
diff --git a/libartbase/base/zip_archive.h b/libartbase/base/zip_archive.h
index a4e56b5..29c5ea1 100644
--- a/libartbase/base/zip_archive.h
+++ b/libartbase/base/zip_archive.h
@@ -92,12 +92,18 @@
// return new ZipArchive instance on success, null on error.
static ZipArchive* Open(const char* filename, std::string* error_msg);
static ZipArchive* OpenFromFd(int fd, const char* filename, std::string* error_msg);
+ static ZipArchive* OpenFromOwnedFd(int fd, const char* filename, std::string* error_msg);
ZipEntry* Find(const char* name, std::string* error_msg) const;
~ZipArchive();
private:
+ static ZipArchive* OpenFromFdInternal(int fd,
+ bool assume_ownership,
+ const char* filename,
+ std::string* error_msg);
+
explicit ZipArchive(ZipArchiveHandle handle) : handle_(handle) {}
friend class ZipEntry;
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 9ed3b5e..5fd9af5 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -484,7 +484,7 @@
result->SetZ(class_name == nullptr);
}
-static MemMap FindAndExtractEntry(const std::string& jar_file,
+static MemMap FindAndExtractEntry(const std::string& bcp_jar_file,
int jar_fd,
const char* entry_name,
size_t* size,
@@ -493,9 +493,9 @@
std::unique_ptr<ZipArchive> zip_archive;
if (jar_fd >= 0) {
- zip_archive.reset(ZipArchive::OpenFromFd(jar_fd, jar_file.c_str(), error_msg));
+ zip_archive.reset(ZipArchive::OpenFromOwnedFd(jar_fd, bcp_jar_file.c_str(), error_msg));
} else {
- zip_archive.reset(ZipArchive::Open(jar_file.c_str(), error_msg));
+ zip_archive.reset(ZipArchive::Open(bcp_jar_file.c_str(), error_msg));
}
if (zip_archive == nullptr) {
return MemMap::Invalid();
@@ -504,7 +504,7 @@
if (zip_entry == nullptr) {
return MemMap::Invalid();
}
- MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
+ MemMap tmp_map = zip_entry->ExtractToMemMap(bcp_jar_file.c_str(), entry_name, error_msg);
if (!tmp_map.IsValid()) {
return MemMap::Invalid();
}