user_heap_smoke could not create a Segment Heap - #186
Merged
Merged
Conversation
`HEAP_CREATE_SEGMENT_HEAP` is documented as a `HeapCreate` option and is not one. `KERNELBASE!HeapCreate` opens with `and ecx,40005h` — `HEAP_CREATE_ENABLE_EXECUTE | HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE` — so 0x100 is dropped before `RtlCreateHeap` is reached, and the example built a classic NT heap instead. It then failed two hundred lines later saying the created heap was not among the roots, which reads as a defect in root enumeration and is not one. That misreading is already in this changelog, blaming ARM64 and the debug heap. Measured on x64 26200, 2026-09-24: through `HeapCreate`, growable, with an initial size and with a fixed maximum all returned an NT heap; the direct `RtlCreateHeap` call returned a Segment Heap in the same process moments later, with `ntdll!RtlpHpHeapFeatures` at 0 throughout. So the wrapper is the whole of the difference, and the per-process feature bit — 1 in `sihost`, whose four heaps are Segment, 0 in `cmd.exe` — governs only the heaps an image gets without asking. The example now calls `RtlCreateHeap` with the flags `HeapCreate` composes for `(_, 0, 0)` plus the one it will not pass on, and reads the heap's signature back at creation so a build that stops honouring it fails there rather than as a missing root. Runs green on this host again: 3 roots, 84 chunks, 35 busy blocks agreed, coverage Complete, on the live target and on the full-memory dump. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUhLUt9rB6zd42Y25btB3h
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HEAP_CREATE_SEGMENT_HEAPis documented as aHeapCreateoption and is not one:0x100 is dropped before
RtlCreateHeapis reached, so this example built a classic NT heap and then failed two hundred lines later saying the created heap was not among the roots — which reads as a defect in root enumeration, and is not one. That misreading is already inCHANGELOG.md, where it is blamed on ARM64 and on the debug heap.Measured
x64 26200, 2026-09-24, one process,
ntdll!RtlpHpHeapFeatures = 0throughout:The wrapper is the whole of the difference. The three
HeapCreateshapes are there becauseRtlpCreateHeap's flag branch does testHEAP_GROWABLEand the parameters block, so "wrong shape of request" had to be ruled out before blaming the mask.The per-process switch is a separate thing, and worth knowing because it is what makes some processes walkable at all:
ntdll!RtlpHpHeapFeaturesbit 0 governs the heaps an image gets without asking. It is 1 insihost, whose four heaps are Segment, and 0 incmd.exe.RtlpCreateHeaptests the caller's flag at+0x14band that global at+0x155, and both feed one decision register read at+0x142.The fix
create_segment_heap()callsRtlCreateHeapwith the flagsHeapCreatecomposes for(_, 0, 0)—HEAP_GROWABLE, plus heap class 1 from its ownbts ecx,0Ch— plus 0x100, and reads the signature back at creation. A build that stops honouring the flag now fails at the call, naming what it got, instead of surfacing as a missing root; the assertion also tells the reader which two routines decide it._SEGMENT_HEAP.Signatureand_HEAP.SegmentSignatureare both at+0x10;_HEAP.Signature(0xeeffeeff) is at+0x98. The constants here are commented with that, because I conflated the two while diagnosing this.Verified
Green on this host again, both arms:
435 tests pass,
cargo fmt --all -- --checkclean, andcargo clippy --all-targets -- -D warningsreports the same 12 pre-existing findings asmainon this toolchain and none from this change.🤖 Generated with Claude Code
https://claude.ai/code/session_01MUhLUt9rB6zd42Y25btB3h