summaryrefslogtreecommitdiff
path: root/rs/java/android/renderscript/RenderScriptGL.java
diff options
context:
space:
mode:
authorNick Desaulniers <ndesaulniers@google.com>2019-12-11 15:33:39 -0800
committerNick Desaulniers <ndesaulniers@google.com>2019-12-13 13:26:19 -0800
commit0dca7da231035fd8e807f2f27c73dd99d78869af (patch)
treea8cac885ef183b657fe13e740adf981ecafa983b /rs/java/android/renderscript/RenderScriptGL.java
parent72f579d5f26239202ab297e354873192856ed45d (diff)
zygote: fix mprotect range for non-page-aligned segments
As of LLVM r369344 commit f66b767abe5e ("[ELF][AArch64] Allow PT_LOAD to have overlapping p_offset ranges") it's no longer guaranteed that binaries linked with LLD have segments that are loaded at virtual addresses that are multiples of the page size. This saves significant space in the binary. This implies the subexpression from `man 3 dl_iterate_phdr`: addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr; is not precise (as noted in bionic/linker/linker.cpp as well). This change results in failures to change page protections via calls to mprotect from execute only pages back to read+execute for apps targeting an Android SDK version < 28 (Q), since mprotect requires a page aligned address. When Zygote forks the app, the child may segfault (SIGSEGV) due to invalid permissions (SEGV_ACCERR). Previously, `info->dlpi_phdr[x].p_vaddr` was page aligned. Now that it's not, we must round it down to the closet multiple of the page size, and extend the range to account for this difference. Previously: +----+ (page) +---+| (segment) | || +---|+ +---+ ^ page boundary, segment p_vaddr (aligned) Now: +----+ (page) | +---+ (segment) | | || +-|--+| +---* ^ segment p_vaddr (unaligned) ^ page boundary Account for the alignment of the segment's virtual address not necessarily being a multiple of the page size by rounding down to the nearest multiple of the page size for the address passed to mprotect, then add the remainder back so the correct number of pages get remapped properly. (It would not be correct to subtract the remainder, otherwise a segment could span two pages, and we might not remap both). Example: p_vaddr == PAGE_START(p_vaddr) + PAGE_OFFSET(p_vaddr) 0x378c == 0x3000 + 0x78c | | | ^ Can't be passed to mprotect, not page aligned. ^ Added to dlpi_addr (which is already page aligned), then passed to mprotect. | ^ Added to size. Finally, check the return code of mprotect, and fail early in zygote, rather than segfault down the line in the child. Test: atest \ CtsSelinuxTargetSdk27TestCases:android.security.SELinuxTargetSdkTest#testNoExecuteOnly Test: launch Facebook or Instagram Bug: 145825270 Merged-in: I6c609e73b59b86c2fd493a8ccf91ccf6c4dc75bf Change-Id: I7161b018e480f36150fe195140207970e37a1270 Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Diffstat (limited to 'rs/java/android/renderscript/RenderScriptGL.java')
0 files changed, 0 insertions, 0 deletions