Summary
cargo-fuzz parse_pdf found a deterministic OOM in pdfium during a run on 2026-04-18. A mutated ~150 KB PDF pushes RSS past 2 GiB inside pdfium's object-stream decoder (Flate-decoded stream with a pathological declared /Length).
- Reproducer artifact:
fuzz/corpus/parse_pdf/oom-d3bf6727d48df284b948852ddbcf7030bccd0cc4 (committed in the seed corpus).
- Reproduce with:
cargo +nightly fuzz run parse_pdf fuzz/corpus/parse_pdf/oom-d3bf6727d48df284b948852ddbcf7030bccd0cc4.
- Reported RSS at abort: ≈ 2147 MB (libFuzzer default rss_limit_mb).
- Currently mitigated in the fuzz target only by
max_input_bytes(1 MiB) + timeout_secs(10). The underlying bug is still exploitable by a real caller that raises those limits.
Proposed fix
Add a pdfium memory guard inside spdf-pdf:
- Reject any PDF stream whose declared
/Length exceeds a configurable ceiling (default: 64 MiB) before handing to pdfium's decoder.
- Thread the ceiling through
ParseConfig::max_stream_bytes (new knob, defaults set for safety).
- Add a regression test that loads the reproducer and asserts a typed
SpdfError rather than an OOM.
Acceptance
Summary
cargo-fuzz parse_pdffound a deterministic OOM in pdfium during a run on 2026-04-18. A mutated ~150 KB PDF pushes RSS past 2 GiB inside pdfium's object-stream decoder (Flate-decoded stream with a pathological declared/Length).fuzz/corpus/parse_pdf/oom-d3bf6727d48df284b948852ddbcf7030bccd0cc4(committed in the seed corpus).cargo +nightly fuzz run parse_pdf fuzz/corpus/parse_pdf/oom-d3bf6727d48df284b948852ddbcf7030bccd0cc4.max_input_bytes(1 MiB)+timeout_secs(10). The underlying bug is still exploitable by a real caller that raises those limits.Proposed fix
Add a pdfium memory guard inside
spdf-pdf:/Lengthexceeds a configurable ceiling (default: 64 MiB) before handing to pdfium's decoder.ParseConfig::max_stream_bytes(new knob, defaults set for safety).SpdfErrorrather than an OOM.Acceptance
ParseConfig::max_stream_bytesexposed and documented.crates/spdf-core/tests/adversarial.rsgets a new test feeding the OOM artifact with default config → typed error, no OOM.fuzz/README.md"Known findings" table moves the OOM row from mitigated at target level to fixed and cross-references this issue number.max_input_bytesis updated to mentionmax_stream_bytestoo.