[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