Skip to content

chore(tools): validate-before-allocate ceiling in frame-crosscheck lz4BlockDecompress (LAB-1202) - #55

Open
27Bslash6 wants to merge 1 commit into
mainfrom
agent/winston/bce985bf
Open

chore(tools): validate-before-allocate ceiling in frame-crosscheck lz4BlockDecompress (LAB-1202)#55
27Bslash6 wants to merge 1 commit into
mainfrom
agent/winston/bce985bf

Conversation

@27Bslash6

Copy link
Copy Markdown
Contributor

Closes LAB-1202 — deferred follow-up 2 of 2 from the LAB-903 crypto/protocol expert panel (#47).

What

lz4BlockDecompress in tools/frame-crosscheck.mjs allocated its output buffer straight from original_size — a value read off the wire — before any bound applied. Not exploitable here (the driver cross-checks original_size against the committed vector first), but this reader is the porting template for SDK envelope readers that will face attacker-controlled envelopes, and the ratified rule is validate-before-allocate. The guard now refuses an implausible expectedSize before new Uint8Array(...) is reached, and refuses non-integer/negative sizes with it.

The ceiling (the decision the ticket delegates)

Ratio-derived, option 1 from the ticket: expectedSize <= 255 * src.length. Derived from the LZ4 block format, not guessed — a match sequence costs at least 3 input bytes (token + 2-byte offset) and each match-length extension byte adds at most 255 output bytes, so per-sequence output L+19+255b <= 255*(3+a+L+b) input; no well-formed block expands more than 255× (the lz4 project's documented maximum compression ratio). Self-scaling: no revisiting when larger vectors land. Derivation lives in the source comment at the guard.

Mutation evidence (LAB-903 convention)

New zero-dep tools/test-frame-crosscheck-guard.mjs, wired into verify.yml before the tool run (same cannot-silently-degrade rule as the version-floors suite):

  • baseline: committed vectors exit 0 under the guarded tool
  • a synthetic vector declaring 64 MiB original_size from 3 compressed bytes exits non-zero with the pre-allocation ceiling refusal
  • guard-strip no-op check, then the stripped tool run: exit codes cannot discriminate guarded from unguarded (the post-allocation op !== expectedSize check the ticket acknowledges fires either way), so the suite discriminates by failure order — the stripped tool's failure is the post-allocation size mismatch, proving the 64 MiB allocation succeeded before any validation. That is the pre-fix vulnerability, pinned.

All 6 cases green locally; frame-crosscheck.mjs and python-frame-reference.py verify green.

Scope guarantees

  • test-vectors/*.json byte-untouched (python-frame.json sha256-pin unmoved)
  • no normative spec text — panel gate not re-triggered, per the panel's own deferral scope
  • wire-format-reference.py untouched (no LZ4 there, per ticket non-goals)

…4BlockDecompress (LAB-1202)

Deferred follow-up from the LAB-903 crypto/protocol panel (protocol#47).
lz4BlockDecompress allocated the output buffer straight from original_size —
a value read off the wire — before any bound applied. Not exploitable in this
repo (the driver matches original_size against the committed vector first),
but this reader is the porting template for SDK envelope readers that WILL
face attacker-controlled envelopes, and the ratified rule is
validate-before-allocate.

Ceiling choice (the one decision the ticket delegates): ratio-derived, not an
absolute cap. The LZ4 block format cannot expand more than 255x — a match
sequence costs at least 3 input bytes (token + 2-byte offset) and each
match-length extension byte adds at most 255 output bytes, so per-sequence
output L+19+255b <= 255*(3+a+L+b) input. expectedSize > 255*src.length is
therefore impossible for well-formed input, self-scales with the fixture, and
needs no revisiting when larger vectors land. Non-integer and negative sizes
are refused by the same guard.

tools/test-frame-crosscheck-guard.mjs pins the guard load-bearing per the
LAB-903 mutation-evidence convention: baseline exit-0 on committed vectors,
mutation no-op checks, and a synthetic vector declaring 64 MiB from 3
compressed bytes. Exit codes cannot discriminate guarded from unguarded (the
ticket-acknowledged post-allocation op !== expectedSize check fires either
way), so the suite discriminates by failure ORDER: guarded fails with the
pre-allocation ceiling refusal; guard-stripped fails with the post-allocation
size mismatch, proving the oversized allocation succeeded first — the exact
pre-fix vulnerability. The suite runs before the tool in verify.yml, same
cannot-silently-degrade rule as the version-floors suite.

test-vectors/*.json byte-untouched; no normative spec text moved (panel gate
not re-triggered, per the panel's own deferral scope).
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 33 minutes.

View limit details

Limit details: You’ve used all 5 included reviews currently available. Your 57 included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9a710057-cf29-47fa-bcee-789de1ce3a92

📥 Commits

Reviewing files that changed from the base of the PR and between 5be35d5 and c1c04b9.

📒 Files selected for processing (3)
  • .github/workflows/verify.yml
  • tools/frame-crosscheck.mjs
  • tools/test-frame-crosscheck-guard.mjs

Comment @coderabbitai help to get the list of available commands.

@kodus-27b

kodus-27b Bot commented Aug 30, 2026

Copy link
Copy Markdown

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

@27Bslash6

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant