Skip to content

Commit

Permalink
i#7024 hook oom: Allow vm_base=0 to mean pick from OS (#7029)
Browse files Browse the repository at this point in the history
Adds the use of "-vm_base 0" to mean to let the OS pick our vmcode base,
with no random offset applied. This was useful during diagnosing the OOM
from the CrowdStrike hook.

Issue: #7024
  • Loading branch information
derekbruening authored Oct 9, 2024
1 parent 32adb70 commit a947273
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 19 deletions.
39 changes: 23 additions & 16 deletions core/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ vmm_place_vmcode(vm_heap_t *vmh, /*INOUT*/ size_t *size, heap_error_code_t *erro
{
ptr_uint_t preferred = 0;
#ifdef X64
LOG(GLOBAL, LOG_HEAP, 1, "%s: vm heap allowed range " PFX "-" PFX "\n", __FUNCTION__,
heap_allowable_region_start, heap_allowable_region_end);
/* -heap_in_lower_4GB takes top priority and has already set heap_allowable_region_*.
* Next comes -vm_base_near_app. It will fail for -vm_size=2G, which we document.
*/
Expand Down Expand Up @@ -838,20 +840,24 @@ vmm_place_vmcode(vm_heap_t *vmh, /*INOUT*/ size_t *size, heap_error_code_t *erro

/* Next we try the -vm_base value plus a random offset. */
if (vmh->start_addr == NULL) {
/* Out of 32 bits = 12 bits are page offset, windows wastes 4 more
* since its allocation base is 64KB, and if we want to stay
* safely in say 0x20000000-0x2fffffff we're left with only 12
* bits of randomness - which may be too little. On the other
* hand changing any of the lower 16 bits will make our bugs
* non-deterministic. */
/* Make sure we don't waste the lower bits from our random number */
preferred = (DYNAMO_OPTION(vm_base) +
get_random_offset(DYNAMO_OPTION(vm_max_offset) /
DYNAMO_OPTION(vmm_block_size)) *
DYNAMO_OPTION(vmm_block_size));
preferred = ALIGN_FORWARD(preferred, OS_ALLOC_GRANULARITY);
/* overflow check: w/ vm_base shouldn't happen so debug-only check */
ASSERT(!POINTER_OVERFLOW_ON_ADD(preferred, *size));
if (DYNAMO_OPTION(vm_base) == 0) {
/* Let the OS pick where. */
} else {
/* Out of 32 bits = 12 bits are page offset, windows wastes 4 more
* since its allocation base is 64KB, and if we want to stay
* safely in say 0x20000000-0x2fffffff we're left with only 12
* bits of randomness - which may be too little. On the other
* hand changing any of the lower 16 bits will make our bugs
* non-deterministic. */
/* Make sure we don't waste the lower bits from our random number */
preferred = (DYNAMO_OPTION(vm_base) +
get_random_offset(DYNAMO_OPTION(vm_max_offset) /
DYNAMO_OPTION(vmm_block_size)) *
DYNAMO_OPTION(vmm_block_size));
preferred = ALIGN_FORWARD(preferred, OS_ALLOC_GRANULARITY);
/* overflow check: w/ vm_base shouldn't happen so debug-only check */
ASSERT(!POINTER_OVERFLOW_ON_ADD(preferred, *size));
}
/* let's assume a single chunk is sufficient to reserve */
#ifdef X64
if ((byte *)preferred < heap_allowable_region_start ||
Expand All @@ -866,8 +872,9 @@ vmm_place_vmcode(vm_heap_t *vmh, /*INOUT*/ size_t *size, heap_error_code_t *erro
os_heap_reserve((void *)preferred, *size, error_code, true /*+x*/);
vmh->start_addr = vmh->alloc_start;
LOG(GLOBAL, LOG_HEAP, 1,
"vmm_heap_unit_init preferred=" PFX " got start_addr=" PFX "\n",
preferred, vmh->start_addr);
"vmm_heap_unit_init preferred=" PFX " size=" PIFX " => start_addr=" PFX
" (code=0x%08x)\n",
preferred, *size, vmh->start_addr, *error_code);
#ifdef X64
}
#endif
Expand Down
9 changes: 6 additions & 3 deletions core/optionsx.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* *******************************************************************************
* Copyright (c) 2010-2022 Google, Inc. All rights reserved.
* Copyright (c) 2010-2024 Google, Inc. All rights reserved.
* Copyright (c) 2011 Massachusetts Institute of Technology All rights reserved.
* Copyright (c) 2003-2010 VMware, Inc. All rights reserved.
* *******************************************************************************/
Expand Down Expand Up @@ -1627,8 +1627,11 @@ OPTION_DEFAULT(uint_size, vmheap_size_wow64, 128 * 1024 * 1024,
"capacity of virtual memory region reserved for unreachable heap "
"on WoW64 processes")
#endif
/* We hardcode an address in the mmap_text region here, but verify via
* in vmk_init().
/* We hardcode a default vmcode base address, to which we add a random offset
* up to vm_max_offset.
* If -vm_base is set to 0, and -vm_base_near_app is off, we let the OS pick
* the base and do not apply any offset.
* For the default:
* For Linux we start higher to avoid limiting the brk (i#766), but with our
* new default -vm_size of 0x20000000 we want to stay below our various
* preferred addresses of 0x7xxx0000 so we keep the base plus offset plus
Expand Down

0 comments on commit a947273

Please sign in to comment.