Skip to content

Commit 7850df3

Browse files
author
Mariusz Borsa
committed
[Sanitizers][Darwin] Fix invalid gap found by FindAvailableMemoryRange
An application running with ASAN can fail during shadow memory allocation, with an error indicating a failure to map shadow memory region due to negative size parameter passed to mmap. It turns out that the mach_vm_region_recurse() call can return an address of a module which is beyond the range of the VM address space available to the iOS process, i.e. greater than the value returned by GetMaxVirtualAddress(). It leads the FindAvailableMemoryRange function to the an incorrect conclusion that it has found a suitable gap where the shadow memory can fit in, while the shadow memory cannot be really allocated in this case. The fix just takes the maximum VM address into account, causing the function to return 0, meaning that the VM gap to fit the requested size could not be found. rdar://66530705 Differential Revision: https://reviews.llvm.org/D134836
1 parent 01470b6 commit 7850df3

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,7 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
12511251
mach_vm_address_t start_address =
12521252
(SANITIZER_WORDSIZE == 32) ? 0x000000001000 : 0x000100000000;
12531253

1254+
const mach_vm_address_t max_vm_address = GetMaxVirtualAddress() + 1;
12541255
mach_vm_address_t address = start_address;
12551256
mach_vm_address_t free_begin = start_address;
12561257
kern_return_t kr = KERN_SUCCESS;
@@ -1265,15 +1266,15 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
12651266
(vm_region_info_t)&vminfo, &count);
12661267
if (kr == KERN_INVALID_ADDRESS) {
12671268
// No more regions beyond "address", consider the gap at the end of VM.
1268-
address = GetMaxVirtualAddress() + 1;
1269+
address = max_vm_address;
12691270
vmsize = 0;
12701271
} else {
12711272
if (max_occupied_addr) *max_occupied_addr = address + vmsize;
12721273
}
12731274
if (free_begin != address) {
12741275
// We found a free region [free_begin..address-1].
12751276
uptr gap_start = RoundUpTo((uptr)free_begin + left_padding, alignment);
1276-
uptr gap_end = RoundDownTo((uptr)address, alignment);
1277+
uptr gap_end = RoundDownTo((uptr)Min(address, max_vm_address), alignment);
12771278
uptr gap_size = gap_end > gap_start ? gap_end - gap_start : 0;
12781279
if (size < gap_size) {
12791280
return gap_start;

0 commit comments

Comments
 (0)