fix(parser): prevent integer overflow in Parser::next bounds check - #9
Open
dingledropper wants to merge 1 commit into
Open
fix(parser): prevent integer overflow in Parser::next bounds check#9dingledropper wants to merge 1 commit into
dingledropper wants to merge 1 commit into
Conversation
`Parser::next(n)` previously computed `self.offset + n` to check whether the read would exceed the buffer. A peer-controlled CompactSize length prefix can produce an `n` of `usize::MAX` (the `0xff` prefix is followed by an 8-byte little-endian u64). The unchecked addition wraps, the bounds check returns `false`, and the function panics — either at the overflow site under `-Cdebug-assertions` (libfuzzer build) or at the subsequent slice access in a release build. Reproducer: `[0xff; 9].chain([0x04])` (10 bytes) fed through `DBKey::parse_data`, found in seconds by libfuzzer. Switch to `checked_add` so out-of-range lengths return `Error::BufferUnderflow` cleanly. CWE-190 (Integer Overflow), CWE-754 (Improper Check for Unusual Conditions).
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 #8.
Parser::next(src/parser/parser_impl.rs) computedself.offset + n > self.buffer.len()with uncheckedusizeaddition. ACompactSizelength prefix of0xfffollowed by 8 bytes of0xffdecodes ton = usize::MAX, wrapping the addition modulo2^64and bypassing the bounds check. The subsequent slice access then panics the thread (orpanic_const_add_overflowfires one line earlier under-Cdebug-assertions).Found via cargo-fuzz within seconds of running fresh harnesses against
DBKey::parse_dataand the fullBDBDump → ZcashdDump → ZcashdParser::parse_dumppipeline.Fix
Use
checked_addto detect the overflow and returnError::BufferUnderflowcleanly. Audited siblings (peekline 270,restline 275,std::io::Readimpl line 296) — each saturatesntomin(n, self.remaining())before slice access, so they cannot wrap and need no change.What's in this PR
src/parser/parser_impl.rs— replace the unchecked addition inParser::nextwithchecked_add+ an inline comment explaining the fuzz finding.fuzz/— two cargo-fuzz harnesses (fuzz_dbkey_parse_data,fuzz_zcashd_full_parse) that surfaced the panic in the first few thousand iterations. Both reproducers are committed underfuzz/corpus/so the regression class is caught in CI if you'd like to adopt the harness.Test plan
cargo testpasses.ff ff ff ff ff ff ff ff ff 04(10 bytes) returnsErr(BufferUnderflow)instead of panicking.ZcashdParser::parse_dumpreturnsErrcleanly.cargo +nightly fuzz run fuzz_dbkey_parse_dataran for ~10 hours post-patch, 0 sibling panics.cargo +nightly fuzz run fuzz_zcashd_full_parseran for ~10 hours post-patch, 0 sibling panics.Notes
The
fuzz/Cargo.tomlincludes[patch.crates-io] zewif = { path = "../../zewif" }because the publishedzewif-zcashdCargo.toml currently requireszewif = "0.1.0"while only0.0.0exists on crates.io. Happy to drop the patch line oncezewifis bumped.AI disclosure
This finding was identified, the fix was drafted, and the fuzz harnesses were built with assistance from Claude (Anthropic). I reviewed each step and am the responsible author.