aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalesh Singh <kaleshsingh@google.com>2024-03-06 17:33:36 -0800
committerKalesh Singh <kaleshsingh@google.com>2024-03-13 13:40:28 -0700
commit1d3ba112ab1b7b1d837f3be7efc032d14822d1aa (patch)
treed9b385292d400f9d154a2c6f60cb81eb8d4698d8
parent702d9b0bad7eac3d1d59e8e433f5a6a0345ea5f8 (diff)
downloadbionic-1d3ba112ab1b7b1d837f3be7efc032d14822d1aa.tar.gz
bionic: loader: Only zero the last partial page in RW segments
Only zero the partial page at the end of the segment. There may be entire pages beyond first page boundary after the segment -- due to segment padding (VMA extension); but these are not expected to be touched (faulted). Do not attempt to zero the extended region past the first partial page, since doing so may: 1) Result in a SIGBUS, as the region is not backed by the underlying file. 2) Break the COW backing, faulting in new anon pages for a region that will not be used. Bug: 327600007 Bug: 328797737 Test: Dexcom G7 app Test: atest -c linker-unit-tests Test: bootup/idle/system-processes-memory-direct Change-Id: Ib76b022f94bfc4a4b7eaca2c155af81478741b91 Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
-rw-r--r--linker/Android.bp1
-rw-r--r--linker/linker_phdr.cpp29
2 files changed, 11 insertions, 19 deletions
diff --git a/linker/Android.bp b/linker/Android.bp
index 55daf2202..f87a92e56 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -116,7 +116,6 @@ cc_defaults {
"libziparchive",
"libbase",
"libz",
- "libprocinfo", // For procinfo::MappedFileSize()
"libasync_safe",
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 821f30dff..074012d3b 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -46,8 +46,6 @@
#include "private/CFIShadow.h" // For kLibraryAlignment
#include "private/elf_note.h"
-#include <procinfo/process_map.h>
-
static int GetTargetElfMachine() {
#if defined(__arm__)
return EM_ARM;
@@ -869,25 +867,20 @@ bool ElfReader::LoadSegments() {
}
}
- // if the segment is writable, and its memory map extends beyond
- // the segment contents on file (p_filesz); zero-fill it until the
- // end of the mapping backed by the file, rounded to the next
- // page boundary; as this portion of the mapping corresponds to either
- // garbage (partial page at the end) or data from other segments.
- //
- // If any part of the mapping extends beyond the file size there is
- // no need to zero it since that region is not touchable by userspace
- // and attempting to do so will causes the kernel to throw a SIGBUS.
+ // if the segment is writable, and does not end on a page boundary,
+ // zero-fill it until the page limit.
//
- // See: system/libprocinfo/include/procinfo/process_map_size.h
- uint64_t file_backed_size = ::android::procinfo::MappedFileSize(seg_page_start,
- page_end(seg_page_start + file_length),
- file_offset_ + file_page_start, file_size_);
+ // Do not attempt to zero the extended region past the first partial page,
+ // since doing so may:
+ // 1) Result in a SIGBUS, as the region is not backed by the underlying
+ // file.
+ // 2) Break the COW backing, faulting in new anon pages for a region
+ // that will not be used.
+
// _seg_file_end = unextended seg_file_end
uint64_t _seg_file_end = seg_start + phdr->p_filesz;
- uint64_t zero_fill_len = file_backed_size - (_seg_file_end - seg_page_start);
- if ((phdr->p_flags & PF_W) != 0 && zero_fill_len > 0) {
- memset(reinterpret_cast<void*>(_seg_file_end), 0, zero_fill_len);
+ if ((phdr->p_flags & PF_W) != 0 && page_offset(_seg_file_end) > 0) {
+ memset(reinterpret_cast<void*>(_seg_file_end), 0, kPageSize - page_offset(_seg_file_end));
}
seg_file_end = page_end(seg_file_end);