Skip to content

Drop single-use prefix in ZSTD_DCtx_reset if frame started - #4848

Open
Chieler wants to merge 1 commit into
meta:devfrom
Chieler:fix-dctx-reset-refprefix-4843
Open

Chieler wants to merge 1 commit into
meta:devfrom
Chieler:fix-dctx-reset-refprefix-4843

Conversation

@Chieler

@Chieler Chieler commented Oct 17, 2026

Copy link
Copy Markdown

Fixes #4843

When decompressing a malformed frame header using a single-use prefix (ZSTD_DCtx_refPrefix), decompression aborts before ZSTD_getDDict() can consume the dictionary. A subsequent ZSTD_DCtx_reset(session_only) reset streamStage back to zdss_init without clearing dictUses == ZSTD_use_once, allowing the discarded prefix buffer to leak into subsequent frames and causing heap use-after-free if the caller freed the prefix buffer.

Clear the prefix during session reset if a frame decompression was already initiated (dctx->streamStage != zdss_init). Add regression tests in zstreamtest to verify that the prefix is dropped after a bad header and preserved if reset occurs prior to ingesting input.

This change clears the prefix during session reset if a frame decompression was already initiated (dctx->streamStage != zdss_init).

Regression tests have been added to tests/zstreamtest.c to verify that:

  1. The prefix is dropped after a bad frame header is rejected.
  2. The prefix is preserved if reset occurs prior to ingesting any input.

Checklist

  • [ x] I searched open pull requests and issues: this problem is not already being addressed.
  • [x ] Bug fix: it comes with a reproducer or a test that fails without the fix.
  • Performance change: numbers from repeated runs are included, with CPU, compiler, flags and data.
    A gain in one configuration is not a general gain: see the Performance section of CONTRIBUTING.md.
  • [ x] I stated below whether AI or other automated tools were used.

Tools used

Byteask was used for root cause diagnosis, implementing the fix in zstd_decompress.c, and writing the regression tests in zstreamtest.c.

When decompressing a malformed frame header using a single-use prefix
(ZSTD_DCtx_refPrefix), decompression aborts before ZSTD_getDDict() can
consume the dictionary. A subsequent ZSTD_DCtx_reset(session_only) reset
streamStage back to zdss_init without clearing dictUses == ZSTD_use_once,
allowing the discarded prefix buffer to leak into subsequent frames and
causing heap use-after-free if the caller freed the prefix buffer.

Clear the prefix during session reset if a frame decompression was
already initiated (dctx->streamStage != zdss_init). Add regression tests
in zstreamtest to verify that the prefix is dropped after a bad header
and preserved if reset occurs prior to ingesting input.

Fixes meta#4843
@meta-cla meta-cla Bot added the CLA Signed label Oct 17, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZSTD_DCtx_refPrefix(): whether the prefix survives ZSTD_DCtx_reset(ZSTD_reset_session_only) after an error depends on where the frame failed

1 participant