Skip to content

← Public intelligence

crates.io package

zstd-safe

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

12 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. Unratedcrates.ioAmendedPublished

    Out-of-bounds read with an out-of-range InBuffer::pos

    Affected
    • crates.io zstd-safe >= 7.2.2, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `InBuffer`'s fields are public, so safe code can set `pos` past the end of `src`. The position was passed to the C library unchecked, and `ZSTD_seekable_compressStream`, unlike the other streaming functions, does not validate it: it read past the end of the input slice, by up to the frame size, and compressed that memory into the output. The flaw was corrected by checking the position before every call into the C library.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  2. Unratedcrates.ioAmendedPublished

    Seekable reads a NULL or out-of-bounds seek table

    Affected
    • crates.io zstd-safe >= 7.2.2, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `Seekable` did not record whether it was initialized. On a fresh `Seekable`, or one whose `init_buff()` failed, `decompress`, `offset_to_frame_index` and `frame_decompressed_size` made the C library read a NULL seek table. After a failed re-initialization, `decompress` returned data from the refused buffer using the previous seek table. Separately, `frame_decompressed_size(num_frames())`, on `Seekable` and `SeekTable`, read one entry past the end of the seek table. The flaw was corrected by refusing to use a `Seekable` until an initialization succeeded, and by checking the frame index.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  3. Unratedcrates.ioAmendedPublished

    OutBuffer::around_pos exposes uninitialized memory

    Affected
    • crates.io zstd-safe >= 4.0.0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `OutBuffer::around_pos` accepted a position past the initialized length of a `Vec `. The next streaming call then marked everything before the position as initialized, so safe code could read stale heap memory between the vector's previous length and that position. The flaw was corrected by zero-filling that gap.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  4. Unratedcrates.ioAmendedPublished

    Use-after-free with CParameter::StableInBuffer

    Affected
    • crates.io zstd-safe >= 4.1.0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    With `CParameter::StableInBuffer(true)` (`experimental` feature), the C library keeps a pointer to the input of one streaming call and reads from it in later calls, including `flush_stream` and `end_stream`, which take no input. An `InBuffer` only borrows its slice for one call, so safe code could free it in between, and freed memory was compressed into the frame. The C library behaves this way since zstd 1.5.4, whether bundled or linked from the system. The flaw was corrected by refusing to enable the parameter.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  5. Unratedcrates.ioAmendedPublished

    Heap buffer overflow in CCtx::try_clone on a multithreaded context

    Affected
    • crates.io zstd-safe >= 4.1.4, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `CCtx::try_clone` (`experimental` feature, deprecated) copies tables sized from the context's applied parameters. Starting a multithreaded frame (`zstdmt` feature) replaces those parameters with the workers' without resizing the context's own tables, so after an abandoned single-threaded frame, the copy wrote up to 512 KiB past a heap allocation, or read past one. This became reachable with the bundled zstd 1.5.6. The flaw was corrected by refusing `try_clone` (and the unsafe `compress_block`) once `NbWorkers` was set on the context.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  6. Unratedcrates.ioAmendedPublished

    Use-after-free through init_using_cdict and init_using_ddict

    Affected
    • crates.io zstd-safe >= 3.0.0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `CCtx::init_using_cdict` and `DCtx::init_using_ddict` (`experimental` feature, deprecated) took the dictionary as `&CDict ` and `&DDict ` with only `'b: 'a`, so the dictionary itself could be dropped while the context still pointed at it. The same mistake in other constructors was fixed earlier ( ). The flaw was corrected by taking `&'a CDict ` and `&'a DDict `.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  7. Unratedcrates.ioAmendedPublished

    Use-after-free when changing a multithreaded context with an unfinished frame

    Affected
    • crates.io zstd-safe >= 0.0.0-0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    When a multithreaded frame (`zstdmt` feature, `CParameter::NbWorkers`) is left unfinished, its jobs may still be running on the worker threads: the C library only waits for them when the next frame starts, or when the context is freed. A session reset makes the context accept changes again in the meantime, so: - unloading the dictionary (`load_dictionary`, `ref_cdict`, `ref_prefix`, `disable_dictionary`, `init*`, or `reset` with parameters) freed the dictionary a worker was still compressing against; - changing `NbWorkers` made the next frame resize the job table before waiting for the old jobs. The flaw was corrected by refusing these calls while a multithreaded frame is unfinished. The new `CCtx::wait_for_workers()` waits for the workers first.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  8. Unratedcrates.ioAmendedPublished

    Uninitialized memory exposed when streaming decompression of a legacy frame fails

    Affected
    • crates.io zstd-safe >= 4.0.0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    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 ` 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…

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  9. Unratedcrates.ioAmendedPublished

    Use-after-free of a dictionary after a one-shot call on a context with an open stream

    Affected
    • crates.io zstd-safe >= 3.0.1, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    The one-shot `DCtx` and `CCtx` methods assumed the C library resets the context, but it leaves an open stream as it is. When a stream was left unfinished on a context, a one-shot call such as `decompress_using_dict` could leave the context pointing at the dictionary borrowed for that call, and the next streaming call resumed the stream against it after it was freed: decompressed output then contained freed heap memory. On the compression side, the stream resumed against the one-shot call's buffers. This requires an application to use one context for both streaming and one-shot calls without a reset in between. The flaw was corrected by resetting the session after one-shot calls whenever a stream may be open.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  10. Unratedcrates.ioAmendedPublished

    Seekable::decompress sets a Vec length beyond its capacity for offsets past the end

    Affected
    • crates.io zstd-safe >= 7.2.2, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `ZSTD_seekable_decompress` shortens the requested length to the end of the data without checking that the offset is before it. For an offset past the end, it returns a wrapped-around length without writing anything, and `Seekable::decompress` passed that length to `Vec::set_len`. With the `seekable` feature, whoever supplies the archive, or chooses the offset, can leave the caller's `Vec ` with a length far beyond its capacity. Reading it then discloses neighbouring heap memory, and appending to it corrupts memory. Offsets near `u64::MAX` can also hang the call. The flaw was corrected by clamping requests to the end of the data, and by checking every count reported by the C library against the buffer capacity.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  11. Unratedcrates.ioAmendedPublished

    Out-of-bounds read in train_from_buffer when sample sizes overflow

    Affected
    • crates.io zstd-safe >= 0.0.0-0, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `ZDICT_trainFromBuffer` is never told the length of the samples buffer, so `train_from_buffer` checked that the sample sizes add up to it. With overflow checks off, as in release builds, that sum wrapped around: sizes totalling 2^64 plus the buffer length passed the check, and the trainer read past the end of the buffer. `zstd::dict::from_continuous` relies on this check from zstd 0.4.10; older versions of zstd had their own, covered by a separate advisory. This requires the sample sizes to come from an untrusted source. The flaw was corrected by summing the sizes with overflow checks.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →
  12. Unratedcrates.ioAmendedPublished

    Double free in DCtx::try_clone

    Affected
    • crates.io zstd-safe >= 4.1.4, < 7.4.0; >= 8.0.0-0, < 8.2.0
    Fixed in
    7.4.08.2.0· Vendor fix available
    Issue
    `DCtx::try_clone` (`experimental` feature, deprecated) is a plain copy of the C context. A context owning a dictionary (from `load_dictionary`, `ref_prefix` or `init_using_dict`) or a dictionary table (`ref_ddict` with `RefMultipleDDicts`) ended up with both copies freeing it. A context cloned mid-frame resumed on uninitialized stream state. The clone also silently lost the `WindowLogMax` limit. The flaw was corrected by refusing to clone such contexts, and by carrying over the parameters the copy leaves out.

    Recommended action: Upgrade to 8.2.0 or 7.4.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.devSource checked Evidence →