Skip to content

Reject oversized self-update ZIP entries#784

Closed
SS-42 wants to merge 2 commits into
DeusData:mainfrom
SS-42:fix/cppcheck-cleanups
Closed

Reject oversized self-update ZIP entries#784
SS-42 wants to merge 2 commits into
DeusData:mainfrom
SS-42:fix/cppcheck-cleanups

Conversation

@SS-42

@SS-42 SS-42 commented Jul 2, 2026

Copy link
Copy Markdown

Summary

  • reject self-update ZIP entries whose declared compressed size exceeds the remaining archive bytes before inflating
  • parse ZIP local-header sizes through explicit little-endian helpers and size_t allocation bounds
  • remove unreachable null checks in Cypher IS NULL / IS NOT NULL evaluation after the existing null guard

Observed locally on macOS 26.5.2 (Darwin 25.5.0, arm64) with Cppcheck 2.21.0 and Homebrew clang-format 22.1.8.

Tests

  • red-first: with the old header_end + (int)comp_size > data_len check restored, ASAN_OPTIONS=detect_leaks=0 ./build/c/test-runner cli fails cli_extract_binary_from_zip_rejects_truncated_deflate_size_over_int_max because the truncated deflated entry is accepted
  • scripts/lint.sh --ci
  • make -f Makefile.cbm build/c/test-runner CC=clang CXX=clang++
  • ASAN_OPTIONS=detect_leaks=0 ./build/c/test-runner cli cypher

@SS-42 SS-42 requested a review from DeusData as a code owner July 2, 2026 19:19
@SS-42 SS-42 force-pushed the fix/cppcheck-cleanups branch from d1d8272 to ce1f704 Compare July 2, 2026 19:37
@DeusData DeusData added bug Something isn't working cypher Cypher query language parser/executor bugs stability/performance Server crashes, OOM, hangs, high CPU/memory priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 3, 2026
@DeusData

DeusData commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Thanks for the cppcheck cleanup. Triage: bug/static-analysis cleanup touching CLI ZIP parsing and Cypher null handling.

Review will check that the ZIP size/bounds changes have regression coverage for truncation and allocation overflow, and that the Cypher changes preserve the intended NULL semantics. This looks focused, but it still needs normal test/lint evidence because it changes parser/evaluator behavior.

@DeusData

DeusData commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Thanks — all four hunk groups check out as genuine fixes: the LE helpers are behavior-identical, the size_t widening is sound, and we verified the cypher IS NULL guards are truly unreachable (eval_condition returns early on !actual just above). Two asks before merge, both about the third hunk — which is much more than lint cleanup: the old int-cast truncation check is genuinely bypassable for comp_size >= 2^31, letting inflate read past the downloaded archive buffer. That's a real bounds-check fix in the self-update path and deserves to be visible, not buried: (1) please retitle/split so the security-relevant fix is called out (its own commit at minimum, ideally its own PR line in the body); (2) the current regression test passes on unfixed code — comp_size=65536 against a 49-byte buffer already fails the old check, and it never triggers the >=2^31 overflow nor the DEFLATE path. Please make it red-first: comp_size >= 0x80000000 (e.g. 0xFFFF0000) with method=DEFLATE, so it fails on main and passes only with the corrected check. Then we're glad to merge. Thanks!


Update: to keep momentum on the bug backlog, we're going to carry the changes above over the line ourselves shortly — a distilled follow-up on current main implementing the notes in this thread, with you credited as Co-authored-by on the commit, and this PR closed referencing it. If you'd prefer to push the update yourself, just reply within the next couple of days and we'll gladly take yours instead. Thanks again for the contribution!

@SS-42 SS-42 force-pushed the fix/cppcheck-cleanups branch from ce1f704 to 1d1c718 Compare July 3, 2026 17:16
@SS-42 SS-42 changed the title Clean cppcheck findings Reject oversized self-update ZIP entries Jul 3, 2026
SS-42 added 2 commits July 3, 2026 20:33
Signed-off-by: SS-42 <noreply@incogni.to>
Signed-off-by: SS-42 <noreply@incogni.to>
@SS-42 SS-42 force-pushed the fix/cppcheck-cleanups branch from 1d1c718 to d520a01 Compare July 3, 2026 17:33
vvenegasv pushed a commit to vvenegasv/codebase-memory-mcp that referenced this pull request Jul 4, 2026
The truncation check `header_end + (int)comp_size > data_len` was
bypassable for comp_size >= 2^31: the int cast turns the size negative,
the sum drops below data_len, and the entry is accepted -- authorizing
inflate to read up to ~4GB past the downloaded archive buffer during
self-update ZIP extraction. Replace it with
`header_end > data_len || comp_size > (uint32_t)(data_len - header_end)`,
which is overflow-safe and strictly tighter.

Regression guard cli_extract_binary_from_zip_rejects_truncated_deflate_size_over_int_max
builds a 52-byte archive whose entry claims comp_size=0xFFFF0000 with a
self-terminating DEFLATE stream: the old check admits it and extraction
returns non-NULL (verified red pre-fix); the new check rejects it.

Secondary cppcheck cleanups from the same review:
- cli.c: extract zip_read_u16le/zip_read_u32le little-endian helpers
  (behavior-identical) and widen zip_extract_entry sizes to size_t with
  an explicit UINT_MAX guard before the zlib uInt narrowing.
- cypher.c: drop unreachable IS NULL / IS NOT NULL null guards in
  eval_condition (resolve_condition_value result is checked earlier).

Distilled from PR DeusData#784.

Co-authored-by: SS-42 <noreply@incogni.to>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData

DeusData commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Thank you — every hunk here was a genuine fix, and the ZIP truncation change was much more than lint cleanup: the int-cast bypass for comp_size >= 2^31 was a real OOB-read in self-update extraction, and we've retitled it accordingly so it gets the visibility it deserves. Special thanks for amending the regression test to the 0xFFFF0000 case after the review — we verified it's a genuine red-first guard and carried it as-is. Merged as 010ac9b (PR #812) with you credited as co-author. Closing in favor of the distill — thanks again!

@DeusData DeusData closed this Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working cypher Cypher query language parser/executor bugs priority/normal Standard review queue; useful PR with ordinary maintainer urgency. stability/performance Server crashes, OOM, hangs, high CPU/memory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants