[libpas] Support compact reservations >=128MiB
Component: libpas / bmalloc allocator | 5b0cfbc
libpas, the allocator behind bmalloc, TZone and isoheaps, stores many internal pointers as 3-byte "compact" offsets from the base of one fixed virtual reservation. With 8B minimum alignment, 24 bits shifted by 3 cover only 128MiB, so every compact-addressed object (views, directories, heaps, size classes, tree nodes) must come from that region, and allocation inside it was a single upward bump pointer. Each pointer type bakes in an alignment and a decode shift, so layout and alignment invariants are security-relevant: a decoded compact pointer is trusted as a valid metadata address. The heap enumerator, which lets out-of-process tools and crash reporters read the heap, also depends on knowing the reservation's bump extent.
This commit grows the compact reservation from 128MiB to 256MiB, split into two bump-allocation fronts. The bottom front bumps upward and serves objects with alignment under 16B, up to 128MiB. The top front bumps downward and serves only 16B-aligned objects, up to the full 256MiB. A new PAS_DEFINE_OVERALIGNED_COMPACT_PTR type keeps 3B pointers but shifts by 4 instead of 3, so it can address 256MiB, and it is applied to the directory, heap, cartesian tree node and size directory pointer types. The enumerator, immortal heap and crash-report code are updated, new reservation and enumeration tests are added, and two unused ptr headers are removed.
Compact reservation layout (offsets from reservation base)
256MiB ┬───────────────────────────────┐
│ top front (bumps DOWN) │
│ only >=16B-aligned objects │
│ addressed via overaligned │
│ compact ptr (idx << 4) │
├───────────────────────────────┤ <- pas_compact_heap_reservation_top_bump
│ (free gap shared by fronts) │
128MiB ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ limit of bottom front
│ │
├───────────────────────────────┤ <- pas_compact_heap_reservation_bump
│ bottom front (bumps UP) │
│ any alignment <16B allowed │
│ standard compact ptr (idx<<3)│
0MiB ┴───────────────────────────────┘
Both pointer kinds decode relative to the reservation BASE,
even for objects living in the top front.
Significance
Large-memory processes (over 50GiB) were beginning to exhaust the 128MiB compact reservation and crash, and this removes that failure mode without growing hot metadata such as segregated views or the per-thread TLC. It also changes where libpas metadata and objects sit inside the reservation.
Audit directions
This commit changes the addressing model of compact pointers and adds a second, downward-growing allocation front in the allocator's most trusted metadata path.
- Front arithmetic. In
try_allocate_bottom/try_allocate_topandpas_compact_heap_reservation_try_allocate, check how the two bumps are tested against each other and against the 128MiB bottom limit, including overflow or underflow in the alignment math. - Pointer-type vs. front agreement. Check whether any compact pointer type that is not overaligned can receive a top-front allocation, because its 24-bit index would silently truncate or mis-decode. Likewise confirm every converted type (bitfit directory, heap, cartesian tree node, segregated size directory) is only ever allocated 16B-aligned; a missed call site, such as an immortal heap or manual-alignment allocation, would produce a mis-decoded metadata pointer. Look at
pas_immortal_heapbump_is_okandpas_immortal_heap_allocate_with_manual_alignmentfor how alignment requests route to a front. - Enumeration of two extents. In
pas_enumeratorandpas_enumerate_initially_unaccounted_pages, check handling of two bump extents when an out-of-process reader parses an untrusted or corrupted target. A bogus top or bottom bump value could cause out-of-range copies or reads.pas_report_crash_pgm_report.hand the new tests show the intended invariants. - Concurrency. Review locking or atomicity around the two bump pointers under concurrent allocation from multiple threads.