Vulnerability details
Vulnerability
Data from Dependency-Track
Affected versions
Score
Description
### Summary
`LZ4BlockInputStream` grows its compressed-input buffer to the attacker-controlled `compressedLen` value from the legacy `LZ4Block` stream header before reading any payload bytes. A header-only input can therefore trigger a near-2 GiB allocation and exhaust the JVM heap.
### Details
In `net.jpountz.lz4.LZ4BlockInputStream`, `refill()` validates that `compressedLen` is nonnegative but does not cap it before allocation:
```java
case COMPRESSION_METHOD_LZ4:
if (compressedBuffer.length < compressedLen) {
compressedBuffer = new byte[Math.max(compressedLen, compressedBuffer.length * 3 / 2)];
}
readFully(compressedBuffer, compressedLen);
```
The paired `LZ4BlockOutputStream` never emits such a block. If compression is not smaller than the original block, it writes the block as RAW:
```java
if (compressedLength >= o) {
compressMethod = COMPRESSION_METHOD_RAW;
compressedLength = o;
} else {
compressMethod = COMPRESSION_METHOD_LZ4;
}
```
Existing readers generally accept noncanonical LZ4-method blocks where `compressedLen >= originalLen`, but no canonical writer found produces them.
### Impact
Applications that pass attacker-controlled legacy `LZ4Block` streams to `LZ4BlockInputStream` can suffer heap exhaustion from a header-only input. The impact is availability-only and requires no valid compressed payload.
### Patch
As of lz4-java 1.11.2, lz4-java rejects lz4 blocks where the compressed length is larger than uncompressed. Readers would generally emit these as raw blocks instead. You can use the new `acceptOversizedBlocks` flag to restore the old behavior, but this reintroduces the DoS vector.
Same vulnerability as