]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
[libzstd] Fix ZSTD_decompressBound() on bad skippable frames
authorNick Terrell <terrelln@fb.com>
Wed, 17 Apr 2019 18:14:49 +0000 (11:14 -0700)
committerNick Terrell <terrelln@fb.com>
Wed, 17 Apr 2019 18:29:42 +0000 (11:29 -0700)
The function didn't verify that the skippable frame size is correct.

lib/decompress/zstd_decompress.c
lib/legacy/zstd_legacy.h

index 675596f5aa9254a45b27b7ec0d8f07974cea48c9..b839a274f86d1914157466865f668e62d17f86f2 100644 (file)
@@ -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;
index e5b383ee4c0ce9c5c55edfb0ed4a2d597a1d5dba..27f88702456f390af814e3d16f75f502ca7e17c3 100644 (file)
@@ -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;
 }