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

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 30 15:05:38 PST 2025


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

>From 96fce1685f8d0d8cbe145df90282eba477fab7f9 Mon Sep 17 00:00:00 2001
From: thetruestblue <bgaston2 at apple.com>
Date: Mon, 27 Jan 2025 23:08:23 -0800
Subject: [PATCH 1/2] [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
---
 .../lib/sanitizer_common/sanitizer_mac.cpp       | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index d15f30c61b5863..1ed9f3e2c312c5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -1203,13 +1203,14 @@ 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;
+
   VReport(2, "FindDynamicShadowStart, space_size = %p\n", (void *)space_size);
   uptr shadow_start =
-      FindAvailableMemoryRange(space_size, alignment, granularity,
+      FindAvailableMemoryRange(space_size, alignment, left_padding,
                                &largest_gap_found, &max_occupied_addr);
   // If the shadow doesn't fit, restrict the address space to make it fit.
   if (shadow_start == 0) {
@@ -1229,9 +1230,9 @@ 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,
+    shadow_start = FindAvailableMemoryRange(space_size, alignment, left_padding,
                                             nullptr, nullptr);
     if (shadow_start == 0) {
       Report("Unable to find a memory range after restricting VM.\n");
@@ -1272,10 +1273,15 @@ 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) {
+
+    // There are cases where going beyond the processes' max vm does
+    // not return KERN_INVALID_ADDRESS so we check for going beyond that 
+    // max address as well.
+    if (kr == KERN_INVALID_ADDRESS || address > max_vm_address) {
       // 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;
     }

>From 72dcb5b08529dd23fd071c83382b17af9a0f0590 Mon Sep 17 00:00:00 2001
From: thetruestblue <bblueconway at gmail.com>
Date: Thu, 30 Jan 2025 15:05:29 -0800
Subject: [PATCH 2/2] Update sanitizer_mac.cpp

---
 compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 1ed9f3e2c312c5..0b8a75391136df 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -1275,7 +1275,7 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
                                 (vm_region_info_t)&vminfo, &count);
 
     // There are cases where going beyond the processes' max vm does
-    // not return KERN_INVALID_ADDRESS so we check for going beyond that 
+    // not return KERN_INVALID_ADDRESS so we check for going beyond that
     // max address as well.
     if (kr == KERN_INVALID_ADDRESS || address > max_vm_address) {
       // No more regions beyond "address", consider the gap at the end of VM.



More information about the llvm-commits mailing list