summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Pawan Wagh <waghpawan@google.com> 2025-03-05 23:25:45 +0000
committer Pawan Wagh <waghpawan@google.com> 2025-03-05 23:59:18 +0000
commit116c58c8f3620779ca2377ea2bc72c29d8e1a9ed (patch)
treeed981f66aa03f5a8bd7b5b744d729ec9f2ab16f0
parent6768e5f02af56c9af5ea48242c282c8bcacf581d (diff)
Ignore 32 bit ELFs in alignment checks
Some apps mixup 32 bit ELFs inside of arm64 directory. Ignore 32 bit ELFs instead of erroring out. 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. Flag: EXEMPT bug_fix Test: atest -c FileSystemUtilsTests Bug: 400741951 Change-Id: Ia9787f795bf9e84e194142f7d3e114daec1db722
-rw-r--r--core/jni/com_android_internal_content_FileSystemUtils.cpp21
-rw-r--r--core/jni/com_android_internal_content_FileSystemUtils.h14
-rw-r--r--core/jni/com_android_internal_content_NativeLibraryHelper.cpp12
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;
}