From: Nick Terrell Date: Wed, 21 Aug 2019 00:13:04 +0000 (-0700) Subject: [legacy] Fix buffer overflow in v0.2 and v0.4 raw literals decompression X-Git-Tag: v1.4.4~1^2~75^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07f22d465d0f85aa00f20fc2f0b59a50ddfe494f;p=thirdparty%2Fzstd.git [legacy] Fix buffer overflow in v0.2 and v0.4 raw literals decompression Extends the fix in PR#1722 to v0.2 and v0.4. These aren't built into zstd by default, and v0.5 onward are not affected. I only add the `srcSize > BLOCKSIZE` check to v0.4 because the comments say that it must hold, but the equivalent comment isn't present in v0.2. Credit to OSS-Fuzz. --- diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 793df6024..de0a4bd6b 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -2889,6 +2889,7 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ if (litSize > srcSize-11) /* risk of reading too far with wildcopy */ { + if (litSize > BLOCKSIZE) return ERROR(corruption_detected); if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); dctx->litPtr = dctx->litBuffer; diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 645a6e313..201ce2b69 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -2655,6 +2655,7 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ if (litSize > srcSize-11) /* risk of reading too far with wildcopy */ { + if (litSize > BLOCKSIZE) return ERROR(corruption_detected); if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); dctx->litPtr = dctx->litBuffer; @@ -3034,9 +3035,12 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, { /* blockType == blockCompressed */ const BYTE* ip = (const BYTE*)src; + size_t litCSize; + + if (srcSize > BLOCKSIZE) return ERROR(corruption_detected); /* Decode literals sub-block */ - size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); + litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); if (ZSTD_isError(litCSize)) return litCSize; ip += litCSize; srcSize -= litCSize;