Repository navigation
cfb: fix panic and unbounded allocation (OOM) on malformed compound files - #762
Open
1337-L3V1ATH0N wants to merge 1 commit into
Open
1337-L3V1ATH0N wants to merge 1 commit into
1337-L3V1ATH0N wants to merge 1 commit into
Conversation
Open
3 of 4 tasks
Author
|
For coordinated disclosure: I've filed a RustSec advisory for these two DoS issues — rustsec/advisory-db#3457. Since this is a security fix, would you be open to either enabling private vulnerability reporting (Settings → Code security) or publishing a GitHub Security Advisory for it? That would allow a CVE to be assigned and linked to the fix. I'm happy to provide whatever the advisory needs (minimal PoC |
The OLE2/CFB parser (used by .xls, .xlsb, and VBA extraction in .xlsx) could
panic or allocate without bound on crafted input, reachable via the public
reader API (open_workbook / Xls::new / Xlsb::new):
- Directory::from_slice read fixed offsets (0..64, 116..120, 120..128) from
`.chunks(128)` entries without checking the chunk length, panicking on a short
final chunk ("range end index 64 out of range for slice of length N"). Skip
chunks that are not a full 128-byte entry.
- The DIFAT loader grew `difat` without bounding iterations (a self-referential
chain), so a 512-byte file could drive a multi-GB allocation (OOM). Bound the
chain to `maxid` sectors and error out; also replace difat.pop().unwrap() with
a checked error.
Both are denial-of-service only (safe Rust; no memory unsafety). Adds regression
tests and fixtures.
Co-Authored-By: Claude <noreply@anthropic.com>
1337-L3V1ATH0N
force-pushed
the
fix-cfb-dos
branch
from
October 29, 2026 03:17
65aa43b to
908d121
Compare
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
Two denial-of-service bugs in the CFB/OLE2 parser (
src/cfb.rs), reachable via the public reader API (open_workbook,Xls::new,Xlsb::new; also VBA extraction in.xlsx) on crafted input. DoS only — no memory unsafety (safe Rust turns the out-of-bounds read into a bounds-checked panic). Found by fuzzing the.xlspath (the existingfuzz_allharness only covers.xlsx). Both reproduce on the current release (0.37.0).1. Panic — out-of-bounds slice index in
Directory::from_sliceThe directory stream is parsed in
.chunks(128), but fixed offsets (buf[..64],buf[116..120],buf[120..128]) are read without checking the chunk is 128 bytes, so a stream length that isn't a multiple of 128 yields a short final chunk and panics (range end index 64 out of range for slice of length N).SectorSize::Small64-byte mini-sectors are a second trigger. Fix: skip chunks that aren't a full 128-byte entry.2. Unbounded allocation / OOM in the DIFAT loader
A crafted self-referential DIFAT chain grows
difatwithout bounding iterations (the code notes//TODO: check if in infinite loop); a 512-byte file can drive a multi-GB allocation. Fix: bound the chain tomaxidsectors and error out, and replacedifat.pop().unwrap()with a checked error.Tests
Adds two regression fixtures + tests (
cfb_short_directory_chunk_does_not_panic,cfb_difat_chain_does_not_oom).cargo testpasses; both fail (panic / OOM) without the fix.Disclosure / CVE
These are reachable by any consumer that parses untrusted spreadsheets. I'm filing a RustSec advisory and will request a CVE; happy to coordinate on a patched release and a GitHub Security Advisory. Minimal PoCs are included as the test fixtures (and available separately on request).