fix(pipeline): prevent stack-buffer-overflow in append_args_json#475
Open
rainder wants to merge 1 commit into
Open
fix(pipeline): prevent stack-buffer-overflow in append_args_json#475rainder wants to merge 1 commit into
rainder wants to merge 1 commit into
Conversation
A call carrying enough long arguments drove append_args_json()'s running position past the fixed CBM_SZ_2K `props` stack buffer in emit_normal_calls_edge(): format_call_arg() returns snprintf's *untruncated* length, so `pos += (size_t)n` could exceed `bufsize`, after which the trailing `buf[pos] = '\0'` (and `buf[pos++] = ']'`) wrote out of bounds. The stack canary caught it as SIGABRT, so full-repo indexing of large TypeScript codebases crashed the server in the parallel resolve pass (emit_service_edge -> emit_normal_calls_edge -> finalize_and_emit -> append_args_json). Confirmed with AddressSanitizer: stack-buffer-overflow WRITE at pass_parallel.c:1124, 'props' (2048 B). Fix: when an argument does not fully fit, roll back to before its separator and stop appending (atomic field, matching append_json_string's behaviour), so `pos` can never advance past the buffer. Add regression test parallel_args_json_no_overflow: indexes a fixture whose single call carries 60 long string args (args JSON well past 2 KB); under the ASan test build it aborts without this fix and passes with it. Signed-off-by: Andrius Skerla <1492322+rainder@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <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
Fixes the stack-buffer-overflow — the
SIGABRTthat crashes the MCP server whenindex_repositoryruns over a large TypeScript codebase.Root cause:
format_call_arg()returnssnprintf's untruncated length.append_args_json()didpos += (size_t)n, so a call carrying enough long arguments pushedpospast the fixedCBM_SZ_2Kpropsstack buffer inemit_normal_calls_edge(); the trailingbuf[pos] = '\0'(andbuf[pos++] = ']') then wrote out of bounds. The stack canary caught it as an abort, so full-repo indexing died in the parallel resolve pass.AddressSanitizer pinpoint:
Fix
When an argument does not fully fit, roll back to before its separator and stop appending — atomic field, matching
append_json_string()'s existing behaviour — soposcan never advance past the buffer. No newsystem/popen/fork/network calls (nosecurity-allowlist.txtchange needed).Test
parallel_args_json_no_overflow(tests/test_parallel.c) indexes a fixture whose single call carries 60 long string args (args JSON well past 2 KB). Aborts under the ASan test build without this fix; passes with it.Verification
make test(ASan + UBSan): 5605 passed, 0 sanitizer errorscli index_repositoryon the originally-crashing repo: clean, completes-O2, mimalloc, stack-protector): fresh full index exits 0 (was SIGABRT 134)clang-formatclean; change is +58/−2 across 2 filesOut of scope: the sibling
pass_definitions.cappender was checked and does not share this pattern.🤖 Generated with Claude Code