From: Nick Terrell Date: Wed, 17 Apr 2019 18:14:49 +0000 (-0700) Subject: [libzstd] Fix ZSTD_decompressBound() on bad skippable frames X-Git-Tag: v1.4.1^2~53^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=450feb0f95636a7622e3c4b1e14ba33253a8c5c9;p=thirdparty%2Fzstd.git [libzstd] Fix ZSTD_decompressBound() on bad skippable frames The function didn't verify that the skippable frame size is correct. --- diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 675596f5a..b839a274f 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -467,6 +467,9 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE) && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize); + if (frameSizeInfo.compressedSize > srcSize) { + return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong)); + } return frameSizeInfo; } else { const BYTE* ip = (const BYTE*)src; @@ -529,7 +532,6 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) return frameSizeInfo.compressedSize; } - /** ZSTD_decompressBound() : * compatible with legacy mode * `src` must point to the start of a ZSTD frame or a skippeable frame @@ -546,6 +548,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize) unsigned long long const decompressedBound = frameSizeInfo.decompressedBound; if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR) return ZSTD_CONTENTSIZE_ERROR; + assert(srcSize >= compressedSize); src = (const BYTE*)src + compressedSize; srcSize -= compressedSize; bound += decompressedBound; diff --git a/lib/legacy/zstd_legacy.h b/lib/legacy/zstd_legacy.h index e5b383ee4..27f887024 100644 --- a/lib/legacy/zstd_legacy.h +++ b/lib/legacy/zstd_legacy.h @@ -238,6 +238,10 @@ MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR; break; } + if (frameSizeInfo.compressedSize > srcSize) { + frameSizeInfo.compressedSize = ERROR(srcSize_wrong); + frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR; + } return frameSizeInfo; }