Skip to content

fix: guard NiPoPow scorex_parse against allocation bomb - #855

Open
mwaddip wants to merge 1 commit into
ergoplatform:v0.30.0from
mwaddip:fix/nipopow-alloc-bomb
Open

fix: guard NiPoPow scorex_parse against allocation bomb#855
mwaddip wants to merge 1 commit into
ergoplatform:v0.30.0from
mwaddip:fix/nipopow-alloc-bomb

Conversation

@mwaddip

@mwaddip mwaddip commented Apr 9, 2026

Copy link
Copy Markdown

Summary

  • A crafted P2P payload can set num_prefixes or other size fields to 0x7FFFFFFF, causing Vec::with_capacity to request ~790 GB and SIGABRT the node
  • Adds sanity-limit guards to all five attacker-controlled size fields in NipopowProof::scorex_parse and PoPowHeader::scorex_parse
  • Adds tests confirming huge values return Err instead of crashing

Guarded fields

Location Field Cap
NipopowProof::scorex_parse num_prefixes 20,000
NipopowProof::scorex_parse num_suffix_tail 20,000
PoPowHeader::scorex_parse header_size 10,000 bytes
PoPowHeader::scorex_parse interlinks_size 10,000
PoPowHeader::scorex_parse proof_bytes 1,000,000 bytes

Test plan

  • crafted_huge_prefix_count_returns_errnum_prefixes = 0x7FFFFFFFErr
  • crafted_huge_header_size_returns_errheader_size = 0x7FFFFFFFErr
  • crafted_header_size_just_over_limit_returns_errheader_size = 10,001Err
  • Existing nipopowproof_roundtrip proptest still passes

🤖 Generated with Claude Code

@kushti
kushti requested review from Alesfatalis and sethdusek April 9, 2026 19:14
@kushti
kushti changed the base branch from develop to v0.30.0 August 3, 2026 16:33
…d input

A crafted P2P payload could set num_prefixes/num_suffix_tail to
0x7FFFFFFF, causing Vec::with_capacity to request ~790 GB and SIGABRT
the node. Add sanity caps to all five attacker-controlled size fields
in NipopowProof::scorex_parse and PoPowHeader::scorex_parse.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@a-shannon

a-shannon commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I prepared the parser-framing follow-up on top of the current v0.30.0 base while leaving this PR as the owning contribution.

Branch and diff: v0.30.0...bounded framing

The branch contains the allocation guards from #855 on the current base, followed by:

  • d9f0f20: make each prefix, suffix-head, and suffix-tail declared size an authoritative bounded outer frame; propagate suffix-tail size read errors.
  • f48cc7c: require exact nested Merkle-proof frame and digest-count consumption.

The outer element helper reads exactly the declared number of bytes from the stream but deliberately does not require the parsed element to consume the whole slice, matching the JVM parseBytes behavior for padding inside a frame. Allocation caps remain checked before buffer creation.

Validation on the combined branch:

  • ergo-nipopow: 19/19.
  • ergo-chain-generation: 28/28.
  • ergo-lib check passed.
  • rustfmt and strict Clippy passed.

No competing PR was opened. After rebasing #855 onto the current v0.30.0 head, the two follow-up commits can be cherry-picked directly.
Coordinated Drafts: sigma-rust#917, Ergo JVM #2461, 0.28 backport #1, and Rust node #16.

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.

3 participants