Skip to content

Commit a08402f

Browse files
committed
[sanitizer_common][fuchsia] Get correct vmar info
Forward fix for #75256 The process for MmapAlignedOrDieOnFatalError involves trimming the start and end of a mapping to ensure it's aligned correctly. This invloves calling zx_vmar_map again but overwriting a part of the original vmar which involves a call to zx_object_get_info(ZX_INFO_VMAR). After #75256, we unconditionally called this on gSanitizerHeapVmar but this can lead to a ZX_ERR_INVALID_ARGS if the prior mapping was on the root vmar. This can be fixed by also returning the vmar we did the last mapping to and using that for followup operations that specifically involve the same vmar. This way we don't have to try each syscall for both vmars.
1 parent 1df4fb9 commit a08402f

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,24 @@ static zx_status_t GetSanitizerHeapVmar(zx_handle_t *vmar) {
160160

161161
static zx_status_t TryVmoMapSanitizerVmar(zx_vm_option_t options,
162162
size_t vmar_offset, zx_handle_t vmo,
163-
size_t size, uintptr_t *addr) {
163+
size_t size, uintptr_t *addr,
164+
zx_handle_t *vmar_used = nullptr) {
164165
zx_handle_t vmar;
165166
zx_status_t status = GetSanitizerHeapVmar(&vmar);
166167
if (status != ZX_OK)
167168
return status;
168169

169170
status = _zx_vmar_map(gSanitizerHeapVmar, options, vmar_offset, vmo,
170171
/*vmo_offset=*/0, size, addr);
171-
if (status == ZX_ERR_NO_RESOURCES) {
172+
if (vmar_used)
173+
*vmar_used = gSanitizerHeapVmar;
174+
if (status == ZX_ERR_NO_RESOURCES || status == ZX_ERR_INVALID_ARGS) {
172175
// This means there's no space in the heap VMAR, so fallback to the root
173176
// VMAR.
174177
status = _zx_vmar_map(_zx_vmar_root_self(), options, vmar_offset, vmo,
175178
/*vmo_offset=*/0, size, addr);
179+
if (vmar_used)
180+
*vmar_used = _zx_vmar_root_self();
176181
}
177182

178183
return status;
@@ -367,30 +372,33 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
367372
// beginning of the VMO, and unmap the excess before and after.
368373
size_t map_size = size + alignment;
369374
uintptr_t addr;
375+
zx_handle_t vmar_used;
370376
status = TryVmoMapSanitizerVmar(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
371-
/*vmar_offset=*/0, vmo, map_size, &addr);
377+
/*vmar_offset=*/0, vmo, map_size, &addr,
378+
&vmar_used);
372379
if (status == ZX_OK) {
373380
uintptr_t map_addr = addr;
374381
uintptr_t map_end = map_addr + map_size;
375382
addr = RoundUpTo(map_addr, alignment);
376383
uintptr_t end = addr + size;
377384
if (addr != map_addr) {
378385
zx_info_vmar_t info;
379-
status = _zx_object_get_info(gSanitizerHeapVmar, ZX_INFO_VMAR, &info,
380-
sizeof(info), NULL, NULL);
386+
status = _zx_object_get_info(vmar_used, ZX_INFO_VMAR, &info, sizeof(info),
387+
NULL, NULL);
381388
if (status == ZX_OK) {
382389
uintptr_t new_addr;
383-
status = TryVmoMapSanitizerVmar(
390+
status = _zx_vmar_map(
391+
vmar_used,
384392
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC_OVERWRITE,
385-
addr - info.base, vmo, size, &new_addr);
393+
addr - info.base, vmo, 0, size, &new_addr);
386394
if (status == ZX_OK)
387395
CHECK_EQ(new_addr, addr);
388396
}
389397
}
390398
if (status == ZX_OK && addr != map_addr)
391-
status = _zx_vmar_unmap(_zx_vmar_root_self(), map_addr, addr - map_addr);
399+
status = _zx_vmar_unmap(vmar_used, map_addr, addr - map_addr);
392400
if (status == ZX_OK && end != map_end)
393-
status = _zx_vmar_unmap(_zx_vmar_root_self(), end, map_end - end);
401+
status = _zx_vmar_unmap(vmar_used, end, map_end - end);
394402
}
395403
_zx_handle_close(vmo);
396404

0 commit comments

Comments
 (0)