diff options
3 files changed, 32 insertions, 15 deletions
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp index 48c92c87f54e..886b9f1ae658 100644 --- a/core/jni/com_android_internal_content_FileSystemUtils.cpp +++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp @@ -201,8 +201,8 @@ bool punchHoles(const char *filePath, const uint64_t offset, return true; } -bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, - std::vector<Elf64_Phdr> &programHeaders) { +read_elf_status_t getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, + std::vector<Elf64_Phdr> &programHeaders) { // Open Elf file Elf64_Ehdr ehdr; std::ifstream inputStream(filePath, std::ifstream::in); @@ -212,13 +212,13 @@ bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, // read executable headers inputStream.read((char *)&ehdr, sizeof(ehdr)); if (!inputStream.good()) { - return false; + return ELF_READ_ERROR; } - // only consider elf64 for punching holes + // only consider ELF64 files if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) { ALOGW("Provided file is not ELF64"); - return false; + return ELF_IS_NOT_64_BIT; } // read the program headers from elf file @@ -229,7 +229,7 @@ bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, uint64_t phOffset; if (__builtin_add_overflow(offset, programHeaderOffset, &phOffset)) { ALOGE("Overflow occurred when calculating phOffset"); - return false; + return ELF_READ_ERROR; } inputStream.seekg(phOffset); @@ -237,7 +237,7 @@ bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, Elf64_Phdr header; inputStream.read((char *)&header, sizeof(header)); if (!inputStream.good()) { - return false; + return ELF_READ_ERROR; } if (header.p_type != PT_LOAD) { @@ -246,13 +246,14 @@ bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, programHeaders.push_back(header); } - return true; + return ELF_READ_OK; } bool punchHolesInElf64(const char *filePath, const uint64_t offset) { std::vector<Elf64_Phdr> programHeaders; - if (!getLoadSegmentPhdrs(filePath, offset, programHeaders)) { - ALOGE("Failed to read program headers from ELF file."); + read_elf_status_t status = getLoadSegmentPhdrs(filePath, offset, programHeaders); + if (status != ELF_READ_OK) { + ALOGE("Failed to read program headers from 64 bit ELF file."); return false; } return punchHoles(filePath, offset, programHeaders); diff --git a/core/jni/com_android_internal_content_FileSystemUtils.h b/core/jni/com_android_internal_content_FileSystemUtils.h index 4a95686c5a0c..c4dc1115e6c4 100644 --- a/core/jni/com_android_internal_content_FileSystemUtils.h +++ b/core/jni/com_android_internal_content_FileSystemUtils.h @@ -22,6 +22,12 @@ namespace android { +enum read_elf_status_t { + ELF_IS_NOT_64_BIT = -2, + ELF_READ_ERROR = -1, + ELF_READ_OK = 0, +}; + /* * This function deallocates space used by zero padding at the end of LOAD segments in given * uncompressed ELF file. Read ELF headers and find out the offset and sizes of LOAD segments. @@ -39,10 +45,10 @@ bool punchHolesInElf64(const char* filePath, uint64_t offset); bool punchHolesInZip(const char* filePath, uint64_t offset, uint16_t extraFieldLen); /* - * This function reads program headers from ELF file. ELF can be specified with file path directly - * or it should be at offset inside Apk. Program headers passed to function is populated. + * This function reads program headers from 64 bit ELF file. ELF can be specified with file path + * directly or it should be at offset inside Apk. Program headers passed to function is populated. */ -bool getLoadSegmentPhdrs(const char* filePath, const uint64_t offset, - std::vector<Elf64_Phdr>& programHeaders); +read_elf_status_t getLoadSegmentPhdrs(const char* filePath, const uint64_t offset, + std::vector<Elf64_Phdr>& programHeaders); } // namespace android
\ No newline at end of file diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 14132e61ff0e..7cf523f18a90 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -640,7 +640,17 @@ com_android_internal_content_NativeLibraryHelper_openApkFd(JNIEnv *env, jclass, static jint checkLoadSegmentAlignment(const char* fileName, off64_t offset) { std::vector<Elf64_Phdr> programHeaders; - if (!getLoadSegmentPhdrs(fileName, offset, programHeaders)) { + read_elf_status_t status = getLoadSegmentPhdrs(fileName, offset, programHeaders); + // Ignore the ELFs which are not 64 bit. + if (status == ELF_IS_NOT_64_BIT) { + ALOGW("ELF file is not 64 Bit"); + // PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED is equivalent of skipping the current file. + // on return, flag is OR'ed with flags from other ELF files. If some app has 32 bit ELF in + // 64 bit directory, alignment of that ELF will be ignored. + return PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED; + } + + if (status == ELF_READ_ERROR) { ALOGE("Failed to read program headers from ELF file."); return PAGE_SIZE_APP_COMPAT_FLAG_ERROR; } |