]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
[lib] Fix assertion when dictionary is prefix 2131/head
authorNick Terrell <terrelln@fb.com>
Tue, 12 May 2020 21:33:59 +0000 (14:33 -0700)
committerNick Terrell <terrelln@fb.com>
Tue, 12 May 2020 21:33:59 +0000 (14:33 -0700)
lib/decompress/zstd_ddict.c
lib/decompress/zstd_decompress.c
lib/decompress/zstd_decompress_block.c
lib/decompress/zstd_decompress_internal.h

index b0e025e7aae1e2ae13a32c3df4dd90a8d751f9e4..c8cb8ecc952435afe743905b23f52f5bf231e8e4 100644 (file)
@@ -66,6 +66,7 @@ void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
     dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
     dctx->previousDstEnd = dctx->dictEnd;
 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    dctx->dictContentBeginForFuzzing = dctx->prefixStart;
     dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
 #endif
     if (ddict->entropyPresent) {
index d8f6eb7db05121b7c66e1113279bb63194e27548..be5c7cfc3347da0291d839379b8ca15aab809e7c 100644 (file)
@@ -1043,6 +1043,7 @@ static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dict
     dctx->prefixStart = dict;
     dctx->previousDstEnd = (const char*)dict + dictSize;
 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    dctx->dictContentBeginForFuzzing = dctx->prefixStart;
     dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
 #endif
     return 0;
index b2a10c0d8948db7b86bbf8134bb1331be12ffa85..ad3b3d8dbd0ae6b490ff3fa8e3e0b0087d512aa7 100644 (file)
@@ -953,6 +953,8 @@ static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStar
     size_t const windowSize = dctx->fParams.windowSize;
     /* No dictionary used. */
     if (dctx->dictContentEndForFuzzing == NULL) return 0;
+    /* Dictionary is our prefix. */
+    if (prefixStart == dctx->dictContentBeginForFuzzing) return 1;
     /* Dictionary is not our ext-dict. */
     if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0;
     /* Dictionary is not within our window size. */
@@ -970,11 +972,13 @@ MEM_STATIC void ZSTD_assertValidSequence(
     size_t const windowSize = dctx->fParams.windowSize;
     size_t const sequenceSize = seq.litLength + seq.matchLength;
     BYTE const* const oLitEnd = op + seq.litLength;
+    DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
+            (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
     assert(op <= oend);
     assert((size_t)(oend - op) >= sequenceSize);
     assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
     if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
-        size_t const dictSize = (size_t)(prefixStart - virtualStart);
+        size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
         /* Offset must be within the dictionary. */
         assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
         assert(seq.offset <= windowSize + dictSize);
@@ -1071,6 +1075,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
             seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_noPrefetch);
             size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+            assert(!ZSTD_isError(oneSeqSize));
             if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
 #endif
             DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
@@ -1174,6 +1179,7 @@ ZSTD_decompressSequencesLong_body(
             seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_prefetch);
             size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+            assert(!ZSTD_isError(oneSeqSize));
             if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
 #endif
             if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
@@ -1188,6 +1194,7 @@ ZSTD_decompressSequencesLong_body(
         for ( ; seqNb<nbSeq ; seqNb++) {
             size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[seqNb&STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+            assert(!ZSTD_isError(oneSeqSize));
             if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
 #endif
             if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
index 1aa1face09d52f9b1e7a3b5ba27dc2108f1ade66..9ad96c554885c6d1c287d18e5e8588664cdf2d52 100644 (file)
@@ -162,6 +162,7 @@ struct ZSTD_DCtx_s
     size_t oversizedDuration;
 
 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    void const* dictContentBeginForFuzzing;
     void const* dictContentEndForFuzzing;
 #endif
 };  /* typedef'd to ZSTD_DCtx within "zstd.h" */