Skip to content

Add regression coverage for the list pre-allocation DoS guard#27

Open
ilitteri wants to merge 1 commit into
mainfrom
coverage-prealloc-dos-25
Open

Add regression coverage for the list pre-allocation DoS guard#27
ilitteri wants to merge 1 commit into
mainfrom
coverage-prealloc-dos-25

Conversation

@ilitteri

Copy link
Copy Markdown
Collaborator

Follow-up to #24 / #25.

The fix in #24 prevents the pre-allocation OOM, but its tests (panic sentinels) only cover the capped SszList path. The most severe variant is the uncapped one: Vec<T> and ProgressiveList decode with no max-length backstop and depend entirely on the out-of-bounds first-offset check running before Vec::with_capacity. Nothing exercised that, so a future refactor could weaken the guard with every test still green.

Changes

  • crates/ssz testVec::<Vec<u8>>::from_ssz_bytes with an oversized first offset (0xFFFFFFFC in an 8-byte buffer) must return OffsetOutOfBounds before allocating.
  • crates/ssz-types test — same assertion for ProgressiveList<Vec<u8>> (adds a test module; the file had none).
  • offset_adversarial fuzz target — add a variable-size-element collection (Vec<Vec<u8>>, plus a derived struct field). The existing target only used fixed-size u8 elements, so it never reached the offset-table allocation — the blind spot that hid this class.
  • decode.rs comment — document why the early first_offset > bytes.len() check must stay (it looks redundant with the per-offset loop check, but that one runs after allocating).

No production code behavior change — tests, fuzz coverage, and a comment only.

Verification

  • cargo test -p libssz -p libssz-types — both new tests pass; full suite green.
  • cargo fmt --check and cargo clippy clean.
  • cargo +nightly fuzz run offset_adversarial builds and runs with no crashes.

The fix in #24 added panic-sentinel tests, but those only exercise the capped
SszList path. The more severe, uncapped paths — Vec<T> and ProgressiveList —
have no max-length backstop and rely solely on the out-of-bounds first-offset
check running before Vec::with_capacity. Nothing tested that, so a future
refactor could drop the guard and leave every test passing.

- ssz: assert Vec<Vec<u8>> rejects an oversized first offset before allocating
- ssz-types: same assertion for ProgressiveList<Vec<u8>>
- offset_adversarial fuzz: add a variable-size-element collection (Vec<Vec<u8>>),
  the offset-table allocation path the existing fixed-element targets never hit
- decode: document why the early first-offset bound check must not be removed

Closes #25.
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