Repository navigation
fix(msan): five "stack-overflow" suites were hiding two uninitialized reads - #2596
Merged
Merged
Conversation
tree_sitter_wit_external_scanner_create() is declared to return void * but had an empty body. tree-sitter's runtime stores its result as the scanner payload (parser.c ts_parser__external_scanner_create), so every WIT parse used an indeterminate value, which C11 6.9.1p12 makes undefined. The scanner never reads its payload, so ordinary builds were unaffected, and the vendored build's -w hid -Wreturn-type. MemorySanitizer reports it at wit/scanner.c:13 from grammar_labels, grammar_probe_e, grammar_regression and lang_contract. Those four suites were excluded from the MSan lane because the report itself crashed and posed as a stack overflow (fixed in the msan.sh commit of this series). Recorded in MANIFEST.md's local-patch table. Upstream bytecodealliance/tree-sitter-wit still has the empty body at 059bfdd1af72, the last change to src/scanner.c. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The test filled 3675 commits' files and count but never their timestamp, and cbm_compute_change_coupling reads each commit's timestamp to track a pair's last co-change (pass_githistory.c:304). MemorySanitizer reports the read; the stack array is now zero-initialized like every other githistory test's commits. Production is unaffected: its commits come from calloc and a zeroed parse state. This was the read behind the pipeline suite's MSan "stack overflow" (the x86-64 CI log of 2026-08-04 aborted in this test). Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Five suites (grammar_regression grammar_labels pipeline lang_contract grammar_probe_e) were excluded from the MSan lane for "stack-overflow under instrumentation". That was never deep recursion. MSan aborted while REPORTING real uninitialized reads: - every abort was on the main thread. MSan's "T<n>" is the OS thread id and equalled the pid in all five x86-64 aborts (CI job 91868259558); the old block read it as a worker-thread ordinal, so the worker-stack knob, MSAN_ORIGINS and CBM_WORKERS=1 could never change anything; - with the default slow unwinder (the image's MSan-instrumented libunwind) a report exhausted the main thread's 256 MiB stack, and the overflow handler then failed with "nested bug in the same thread"; - with fast_unwind_on_fatal=1 the same test prints the use-of-uninitialized-value report instead (measured on one tree and test: slow unwind aborts at the stack limit, fast unwind reports wit/scanner.c:13). The two reads are fixed in the previous commits of this series, so: - MSAN_OPTIONS defaults to fast_unwind_on_fatal=1 (the build already keeps frame pointers); - MSAN_EXCLUDE is down to cli, whose install-path failure is a separate, still-undiagnosed cause; - the known-red block, the header (it still claimed CI runs without exclusions) and the MSAN_ORIGINS and stack comments say what is true; - the partial-lane warning and the exclude-name typo check lived in a branch behind `elif true` that never ran. They now run in the per-suite path, the check as a case match instead of a grep -q pipe that pipefail can misreport; - the comments in scripts/ci/msan-lane.sh and above the test-msan job in _test.yml no longer say the five suites overflow. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
DeusData
added a commit
that referenced
this pull request
Oct 12, 2026
Brings in #2596 (MSan: hidden uninitialized reads) and #2068 (CodeAtlas web). README: main's CBM Atlas line and this branch's infrastructure-as-code line are both kept. tools/list metadata: main and this branch each stayed under the 20 KiB discovery budget, but together they reached 20,809 bytes. The branch's wording is shorter now (search_graph kind/namespace, one hint per trace mode: 136 bytes less), and the reviewed budget is 21 KiB so the topology/deploy/run modes keep their usage hints. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.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.
The MSan lane excluded five suites for "stack-overflow under instrumentation". That was never deep recursion. MSan was crashing while it reported real uninitialized reads. This PR fixes the two reads, makes the reports print, and puts the five suites back in the lane. Follows up on the finding in #2583.
What was hiding
tree_sitter_wit_external_scanner_create()returnsvoid *but had an empty body; the runtime stores the garbage as the scanner payload (UB, C11 6.9.1p12; hidden by the vendored-w)return NULL;plus a row in MANIFEST.md's local-patch table. Upstream bytecodealliance/tree-sitter-wit still has it at059bfdd1af72githistory_coupling_limits_outputfilled its commits' files and count but never their timestamp, whichcbm_compute_change_couplingreads (pass_githistory.c:304)Why it looked like a stack overflow
T<n>is the OS thread id, and it equalled the pid in all five x86-64 aborts (CI job 91868259558, 2026-08-04, the last run without exclusions). The old notes read it as a worker-thread ordinal, so the worker-stack knob,MSAN_ORIGINSandCBM_WORKERS=1could never change anything.grammar_label_goldens.stack-overflow on address 0xffffeffffef0 ... T627, thennested bug in the same threadfast_unwind_on_fatal=1use-of-uninitialized-valueatwit/scanner.c:13:54, with a full stackLane changes (scripts/msan.sh)
MSAN_OPTIONSdefaults tofast_unwind_on_fatal=1. The build already keeps frame pointers.MSAN_EXCLUDEis down tocli, whose install-path failure is a separate cause that is still undiagnosed.MSAN_ORIGINSand stack comments.elif trueand never ran. They now run in the per-suite path. The check is acasematch, not agrep -qpipe, which pipefail can misreport.scripts/ci/msan-lane.shand the comment above thetest-msanjob in.github/workflows/_test.ymlno longer say the five suites overflow. No job or step changes.Checks
Local arm64 MSan (
docker compose … run --rm test-msan, the real msan.sh with its new defaults), on the five formerly excluded suites:grammar_labelsreportedwit/scanner.c:13, and with WIT fixed,pipelinereportedpass_githistory.c:304;test_grammar_labels.candtest_pipeline.c): 443 passed, 0 failed, no MSan output.macOS ASan, the same five suites: 441 passed, 0 failed.
make lint-ciis clean.scripts/security-vendored.shpasses with the two updated checksums (wit/scanner.candMANIFEST.md).PR CI is the gate. The lane selector puts this PR in T5-core (workflow and vendored paths), so
test-msanruns on x86-64.Local legs skipped: the full 3-OS ladder. The C changes are a one-line return in a vendored scanner and a test initializer, so a platform-specific failure is unlikely.