[compiler-rt] [Sanitizers][Apple] Fix logic bugs that break RestrictMemoryToMaxAddress (PR #124712)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 27 23:15:22 PST 2025


https://github.com/thetruestblue created https://github.com/llvm/llvm-project/pull/124712

There are two logic bugs breaking RestrictMemoryToMaxAddress -- adding left_padding within MapDynamicShadow.

There is also an issue with the expectation of hitting KERN_INVALID_ADDRESS when we are beyond the addressable regions.

For most embedded scenarios, we exceed vm_max_address and setting max_occupied address to a memory region the process doesn't have access to.

Because of this, our check if (new_max_vm < max_occupied_addr) { will always fail and we will never restrict the address on smaller devices.

rdar://66603866


>From 58c430db3854c080bf3d1f7aad5b1cadb138b8f9 Mon Sep 17 00:00:00 2001
From: thetruestblue <bgaston2 at apple.com>
Date: Mon, 27 Jan 2025 23:08:23 -0800
Subject: [PATCH] [Sanitizers][Apple] Fix logic bugs that break
 RestrictMemoryToMaxAddress

There are two logic bugs breaking RestrictMemoryToMaxAddress -- adding left_padding within MapDynamicShadow.

There is also an issue with the expectation of hitting KERN_INVALID_ADDRESS when we are beyond the addressable regions.

For most embedded scenarios, we exceed vm_max_address and setting max_occupied address to a memory region the process doesn't have access to.

Because of this, our check if (new_max_vm < max_occupied_addr) { will always fail and we will never restrict the address on smaller devices.

rdar://66603866
---
 compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index d15f30c61b5863..ade2ed2da6e4aa 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -1203,7 +1203,7 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
   const uptr left_padding =
       Max<uptr>(granularity, 1ULL << min_shadow_base_alignment);
 
-  uptr space_size = shadow_size_bytes + left_padding;
+  uptr space_size = shadow_size_bytes;
 
   uptr largest_gap_found = 0;
   uptr max_occupied_addr = 0;
@@ -1229,7 +1229,7 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
     }
     RestrictMemoryToMaxAddress(new_max_vm);
     high_mem_end = new_max_vm - 1;
-    space_size = (high_mem_end >> shadow_scale) + left_padding;
+    space_size = (high_mem_end >> shadow_scale);
     VReport(2, "FindDynamicShadowStart, space_size = %p\n", (void *)space_size);
     shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity,
                                             nullptr, nullptr);
@@ -1272,10 +1272,11 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
     mach_msg_type_number_t count = kRegionInfoSize;
     kr = mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
                                 (vm_region_info_t)&vminfo, &count);
-    if (kr == KERN_INVALID_ADDRESS) {
+    if (kr == KERN_INVALID_ADDRESS || address > GetMaxVirtualAddress()) {
       // No more regions beyond "address", consider the gap at the end of VM.
       address = max_vm_address;
       vmsize = 0;
+      kr = -1; // break after this iteration.
     } else {
       if (max_occupied_addr) *max_occupied_addr = address + vmsize;
     }



More information about the llvm-commits mailing list