Skip to content

Fix pdfium OOM found by parse_pdf fuzzer (stream-length cap) #3

Description

@Fanaperana

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

  • ParseConfig::max_stream_bytes exposed and documented.
  • crates/spdf-core/tests/adversarial.rs gets 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.
  • SECURITY.md bullet on max_input_bytes is updated to mention max_stream_bytes too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghardeningAdversarial PDF / crash / resource hardening

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions