Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions crates/calamine/RUSTSEC-0000-0000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
```toml
[advisory]
id = "RUSTSEC-0000-0000"
package = "calamine"
date = "2026-10-28"
url = "https://github.com/tafia/calamine/pull/762"
categories = ["denial-of-service"]
cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
keywords = ["dos", "panic", "oom", "cfb", "ole2", "xls", "xlsb"]

[versions]
patched = []
```

# Panic and unbounded allocation (OOM) in the CFB/OLE2 parser on malformed input

The Compound File Binary (OLE2) parser (`src/cfb.rs`), used when reading `.xls` and `.xlsb`
workbooks and when extracting VBA projects from `.xlsx`, can panic or allocate without bound
on crafted input. Both are reachable through the public reader API (`open_workbook`,
`Xls::new`, `Xlsb::new`) on an attacker-supplied file. Impact is denial of service only — no
memory unsafety (safe Rust turns the out-of-bounds read into a bounds-checked panic).

1. **Reachable panic (out-of-bounds slice index).** The directory stream is iterated with
`.chunks(128)`, but `Directory::from_slice` reads fixed offsets (`buf[..64]`,
`buf[116..120]`, `buf[120..128]`) without checking the chunk length. A directory stream
whose length is not a multiple of 128 yields a short final chunk, causing a panic
(`range end index 64 out of range for slice of length N`). `SectorSize::Small` 64-byte
mini sectors are a second trigger.

2. **Unbounded allocation / OOM.** The DIFAT loader grows the `difat` vector without bounding
the number of iterations; a crafted self-referential DIFAT chain drives a multi-gigabyte
allocation from a tiny file (a 512-byte file attempts an allocation of several gigabytes).

A consumer that parses untrusted or user-supplied spreadsheets can be crashed (thread panic,
or process abort under `panic=abort`) or driven out of memory by a small crafted file.

A fix is proposed upstream in https://github.com/tafia/calamine/pull/762.
Loading