Disclosure summary
### Summary `LZ4FrameInputStream` allocates two new buffers of the frame's maximum block size, up to 4 MiB each, every time it reads a frame header. Because concatenated frames are read by default, an input made of many minimal empty frames forces about 8 MiB of zeroed heap allocation for every 11 input bytes. ### Details In `net.jpountz.lz4.LZ4FrameInputStream.readHeader()`: ```java maxBlockSize = frameInfo.getBD().getBlockMaximumSize(); compressedBuffer = new byte[maxBlockSize]; // Reused during different compressions rawBuffer = new byte[maxBlockSize]; buffer = ByteBuffer.wrap(rawBuffer); ``` This runs for every frame, and the previous frame's arrays are never reused. A valid 11-byte frame consists of the magic number, FLG `0x60`, BD `0x70` (4 MiB blocks), the header checksum, and an immediate end mark. It carries no data, yet triggers the full 8 MiB allocation. `new LZ4FrameInputStream(in)` reads concatenated frames by default. In local measurements on JDK 25, 10,000 such frames (110 KB of input) took about 8 seconds of CPU to read, roughly 70 seconds per MiB of input. This was similar under G1, Parallel, Serial and ZGC. A legitimate stream costs orders of magnitude less per in
Source-specific records & product guidance
Sources retain their own attribution and scoring. Follow the original record to confirm affected versions, fixed releases, and configuration conditions.
GitHub Reviewed Security Advisories · GHSA-gm45-99xc-r7wv
Open original source · Updated Oct 07, 2026
yawkat LZ4 Java: LZ4FrameInputStream reallocates block buffers for every frame, allowing CPU and GC amplification from small inputs
Source severity: MEDIUM / 0
| Ecosystem | Package | Affected range | First patched |
|---|---|---|---|
| maven | at.yawk.lz4:lz4-java | 1.11.4 | |
| maven | org.lz4:lz4-java | Not supplied |
Original records & references
- NIST NVD record
- CVE Program record
- github.com — Reviewed advisory
PUBLISHED 2026-10-07T16:35:40-04:00
MODIFIED 2026-10-07T16:35:41-04:00
INGESTED 2026-10-08T12:30:39-04:00