diff options
| author | Andreas Gampe <agampe@google.com> | 2014-12-10 20:51:45 -0800 |
|---|---|---|
| committer | The Android Automerger <android-build@google.com> | 2014-12-11 13:49:24 -0800 |
| commit | 38078c6449ea5c53ce390343eb57327552a7eaff (patch) | |
| tree | a77c30bcba28b28fc7633c48020c19fa8de2d7c3 | |
| parent | 8a483aa099041683b8e11f2b62e45a9cf63e09de (diff) | |
| download | android_art-38078c6449ea5c53ce390343eb57327552a7eaff.tar.gz android_art-38078c6449ea5c53ce390343eb57327552a7eaff.tar.bz2 android_art-38078c6449ea5c53ce390343eb57327552a7eaff.zip | |
ART: More ELF and oat file safety measures
In an ELF file, look for a shstrtab section when loading in
program-header-only mode. If the section is outside the file size,
it strongly indicates a broken compile.
When compiling oat files in the class linker, explicitly unlink
on failure. This should catch cases when dex2oat is killed or
crashes and doesn't have a chance to delete its (partial) output.
Bug: 15567083
Change-Id: Ia0c75f151d91c6f26a71696967255d6d409ca882
| -rw-r--r-- | runtime/class_linker.cc | 10 | ||||
| -rw-r--r-- | runtime/elf_file.cc | 14 |
2 files changed, 23 insertions, 1 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index cb2831cf33..cd1a93a30c 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -19,6 +19,7 @@ #include <fcntl.h> #include <sys/file.h> #include <sys/stat.h> +#include <unistd.h> #include <deque> #include <memory> #include <string> @@ -662,7 +663,14 @@ bool ClassLinker::GenerateOatFile(const char* dex_filename, argv.push_back(compiler_options[i].c_str()); } - return Exec(argv, error_msg); + if (!Exec(argv, error_msg)) { + // Manually delete the file. Ensures there is no garbage left over if the process unexpectedly + // died. Ignore unlink failure, propagate the original error. + TEMP_FAILURE_RETRY(unlink(oat_cache_filename)); + return false; + } + + return true; } const OatFile* ClassLinker::RegisterOatFile(const OatFile* oat_file) { diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index 6ec0712f0d..29628f1e0d 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -432,6 +432,20 @@ bool ElfFile::CheckSectionsExist(std::string* error_msg) const { return false; } + // We'd also like to confirm a shstrtab in program_header_only_ mode (else Open() does this for + // us). This is usually the last in an oat file, and a good indicator of whether writing was + // successful (or the process crashed and left garbage). + if (program_header_only_) { + // It might not be mapped, but we can compare against the file size. + int64_t offset = static_cast<int64_t>(GetHeader().e_shoff + + (GetHeader().e_shstrndx * GetHeader().e_shentsize)); + if (offset >= file_->GetLength()) { + *error_msg = StringPrintf("Shstrtab is not in the mapped ELF file: '%s'", + file_->GetPath().c_str()); + return false; + } + } + return true; } |
