Merge "zygote: fix mprotect range for non-page-aligned segments" am: 09c87c5587 am: d5cf7ee795
Change-Id: I6ad482cf03944c7a6b136c675a7c868cd4ac05ae
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index a3f5311..58fd9c0 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -74,6 +74,7 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <bionic/malloc.h>
+#include <bionic/page.h>
#include <cutils/fs.h>
#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
@@ -1673,9 +1674,14 @@
static int disable_execute_only(struct dl_phdr_info *info, size_t size, void *data) {
// Search for any execute-only segments and mark them read+execute.
for (int i = 0; i < info->dlpi_phnum; i++) {
- if ((info->dlpi_phdr[i].p_type == PT_LOAD) && (info->dlpi_phdr[i].p_flags == PF_X)) {
- mprotect(reinterpret_cast<void*>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr),
- info->dlpi_phdr[i].p_memsz, PROT_READ | PROT_EXEC);
+ const auto& phdr = info->dlpi_phdr[i];
+ if ((phdr.p_type == PT_LOAD) && (phdr.p_flags == PF_X)) {
+ auto addr = reinterpret_cast<void*>(info->dlpi_addr + PAGE_START(phdr.p_vaddr));
+ size_t len = PAGE_OFFSET(phdr.p_vaddr) + phdr.p_memsz;
+ if (mprotect(addr, len, PROT_READ | PROT_EXEC) == -1) {
+ ALOGE("mprotect(%p, %zu, PROT_READ | PROT_EXEC) failed: %m", addr, len);
+ return -1;
+ }
}
}
// Return non-zero to exit dl_iterate_phdr.