Repository navigation
Conversation
…ocks When a block's literals are split between dst and litExtraBuffer, the first part of the literals is stored at the end of the block's area in dst. A block that decodes to more than that area could overwrite these literals before reading them, and decode to wrong output: - ZSTD_safecopyDstBeforeSrc() used ZSTD_wildcopy() when src was more than 16 bytes ahead of dst, but ZSTD_wildcopy() can write up to 31 bytes past its length, onto source bytes not yet copied. Only use it when src is at least WILDCOPY_OVERLENGTH bytes ahead. - ZSTD_execSequenceEndSplitLitBuffer() only detected op starting inside the literals being copied. Reject any sequence whose output runs past the end of the literals it consumes, which also covers matches overwriting the literals of the next sequences. - ZSTD_decompressFrame() didn't check that a block decodes to at most blockSizeMax, unlike ZSTD_decompressContinue(). One-shot decompression accepted such blocks, including raw and RLE blocks larger than ZSTD_d_maxBlockSize. Valid blocks never decode to more than MIN(blockSizeMax, dstCapacity), so the output stays at least 64 KB - 32 bytes behind the literals in dst, and isn't affected. All writes were within dst, so this was not a memory safety issue. Frames with blocks larger than the window are now rejected by the one-shot API, as they already were by streaming. Add tests with a crafted block for the block and frame APIs, and for ZSTD_d_maxBlockSize with raw and RLE blocks.
Cyan4973
approved these changes
Nov 5, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a block's literals are split between
dstandlitExtraBuffer, the first part of the literals is stored at the end of the block's area indst. A block that decodes to more than that area could overwrite these literals before reading them, and decode to wrong output:ZSTD_safecopyDstBeforeSrc()usedZSTD_wildcopy()whensrcwas more than 16 bytes ahead ofdst, butZSTD_wildcopy()can write up to 31 bytes past its length, onto source bytes not yet copied. Only use it whensrcis at leastWILDCOPY_OVERLENGTHbytes ahead.ZSTD_execSequenceEndSplitLitBuffer()only detectedopstarting inside the literals being copied. Reject any sequence whose output runs past the end of the literals it consumes, which also covers matches overwriting the literals of the next sequences.ZSTD_decompressFrame()didn't check that a block decodes to at mostblockSizeMax, unlikeZSTD_decompressContinue(). One-shot decompression accepted such blocks, including raw and RLE blocks larger thanblockSizeMax.Valid blocks never decode to more than
MIN(blockSizeMax, dstCapacity), so the output stays at least 64 KB - 32 bytes behind the literals indst, and isn't affected. All writes were withindst, so this was not a memory safety issue. Frames with blocks larger than the window are now rejected by the one-shot API, as they already were by streaming.Add tests with a crafted block for the block and frame APIs, and for
ZSTD_d_maxBlockSizewith raw and RLE blocks.