Skip to content
OpenAdvisories
Unscored RUSTSEC-2026-0403

Uninitialized memory exposed when streaming decompression of a legacy frame fails

Published Oct 16, 2026 · Updated Nov 2, 2026 · Assigned by RUSTSEC

Description

When decompression fails inside a legacy (zstd v0.4 to v0.7) frame, the
bundled zstd library reports the output buffer as fully written although
nothing was written. `DCtx::decompress_stream` committed that position even
on error, and for a `Vec<u8>` destination this extended the vector's length
over uninitialized memory.

Legacy support is enabled by default. A 5- or 6-byte corrupt legacy frame is
enough: through `zstd::stream::write::Decoder`, up to 32 KiB of stale heap
memory is then passed to the wrapped writer on the next `write()` or
`flush()`, or when an `auto_flush()`/`on_flush()` decoder is dropped. Whether
this reaches an attacker depends on where the application sends the
decompressed output. `zstd::stream::read::Decoder`, `zstd::decode_all` and
the bulk API are not affected.

Before zstd-safe 4.0.0, output buffers could only be initialized slices.
The zstd crate's own writer had the same flaw from 0.4.22 to 0.7.x, which is
covered by a separate advisory.

The flaw was corrected by only committing the buffer positions of a
successful call.

Affected packages

EcosystemPackageAffectedFixedRecord
crates.io zstd-safe >= 4.0.0, < 7.4.0 · >= 8.0.0-0, < 8.2.0 7.4.0, 8.2.0 RUSTSEC-2026-0403

References