From 34d70e51ee2cb6e8352cd177ef928d9da62a2f2c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 12 Apr 2023 16:00:28 -0700 Subject: [PATCH] [oss-fuzz] Fix simple_round_trip fuzzer with overlapping decompression When `ZSTD_c_maxBlockSize` is set, we weren't computing the decompression margin correctly, leading to `dstSize_tooSmall` errors. Fix that computation. This is just a bug in the fuzzer, not a bug in the library itself. Credit to OSS-Fuzz --- tests/fuzz/simple_round_trip.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/fuzz/simple_round_trip.c b/tests/fuzz/simple_round_trip.c index 8b123197595..0fe46391764 100644 --- a/tests/fuzz/simple_round_trip.c +++ b/tests/fuzz/simple_round_trip.c @@ -27,7 +27,7 @@ static ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; -static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_t srcSize, int hasSmallBlocks) +static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_t srcSize, int hasSmallBlocks, int maxBlockSize) { size_t margin = ZSTD_decompressionMargin(compressed, cSize); if (!hasSmallBlocks) { @@ -37,7 +37,12 @@ static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_ ZSTD_frameHeader zfh; size_t marginM; FUZZ_ZASSERT(ZSTD_getFrameHeader(&zfh, compressed, cSize)); - marginM = ZSTD_DECOMPRESSION_MARGIN(srcSize, zfh.blockSizeMax); + if (maxBlockSize == 0) { + maxBlockSize = zfh.blockSizeMax; + } else { + maxBlockSize = MIN(maxBlockSize, (int)zfh.blockSizeMax); + } + marginM = ZSTD_DECOMPRESSION_MARGIN(srcSize, maxBlockSize); if (marginM < margin) margin = marginM; } @@ -52,12 +57,14 @@ static size_t roundTripTest(void *result, size_t resultCapacity, size_t cSize; size_t dSize; int targetCBlockSize = 0; + int maxBlockSize = 0; if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) { size_t const remainingBytes = FUZZ_dataProducer_remainingBytes(producer); FUZZ_setRandomParameters(cctx, srcSize, producer); cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); FUZZ_ZASSERT(cSize); FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetCBlockSize, &targetCBlockSize)); + FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_maxBlockSize, &maxBlockSize)); // Compress a second time and check for determinism { size_t const cSize0 = cSize; @@ -89,7 +96,7 @@ static size_t roundTripTest(void *result, size_t resultCapacity, FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, result, dSize), "Corruption!"); { - size_t margin = getDecompressionMargin(compressed, cSize, srcSize, targetCBlockSize); + size_t margin = getDecompressionMargin(compressed, cSize, srcSize, targetCBlockSize, maxBlockSize); size_t const outputSize = srcSize + margin; char* const output = (char*)FUZZ_malloc(outputSize); char* const input = output + outputSize - cSize;