feat(vm): sanitizer-build borrow-scan guard (#548)#552
Merged
Conversation
…w past the cap (#548) The #546 cap on vm_borrow_scan rests on 'no builtin returns a borrowed direct child past index 7', enforced only by a comment. A future violation is a missed compensating incref: the VM pushes a result it doesn't own, and the over-release fires later and lifetime-dependently — a heisenbug UAF, not a test failure. In ASan builds (compiler-set macro gate, EIGS_BORROW_GUARD in vm.h — zero release cost) the scan now continues past VM_BORROW_SCAN_CAP and aborts on a match the capped scan missed, naming the builtin via an env-chain reverse lookup that runs only on the abort path. The cap moved to vm.h so the self-test can reference it. Planted-fault validation (a checker nobody watched fail is not a checker): __borrow_guard_selftest deliberately returns items[count-1] of a >cap arg vector. Registered only in sanitizer builds AND under EIGS_BORROW_GUARD_SELFTEST, so fuzz harnesses (also ASan builds) can never reach a deliberate abort. Suite [119], 4 checks: within-cap clean, past-cap aborts rc=134, message names builtin+cap, opt-in absent by default. SKIPs on release; documented in BUILTINS.md (stdlib index gate now tracks 215). Closes #548 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Machine-checks the #546 borrow-scan invariant (no builtin returns a borrowed direct child past index 7), which was previously enforced only by a comment. A future violation is a missed compensating incref — a lifetime-dependent use-after-free heisenbug, not a test failure.
src/vm.c): in ASan builds,vm_borrow_scancontinues pastVM_BORROW_SCAN_CAPafter a capped-scan miss andabort()s on a match, naming the builtin (env-chain reverse lookup, abort-path only). Gate is the compiler-set ASan macro (EIGS_BORROW_GUARD,src/vm.h) — zero release cost, no Makefile change; active automatically inmake asan, the CI ASan job, and fuzz builds.__borrow_guard_selftestdeliberately violates the invariant — registered only in sanitizer builds and underEIGS_BORROW_GUARD_SELFTEST, so fuzzers can never reach a deliberate abort. Documented in BUILTINS.md (stdlib index gate: 215).VM_BORROW_SCAN_CAPmoved tosrc/vm.h(shared with the self-test); all three call sites (CALL, jit_helper_call, OP_DISPATCH) pass the builtin + frame env for the diagnostic.Validation
detect_leaks=1: 2799/2799 (guard active, 4 new checks), leak tally 0.__borrow_guard_selftestat index 9; within-cap and no-envvar controls clean.Closes #548
🤖 Generated with Claude Code