]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fix stack buffer overrun when weightTotal == 0
authorNick Terrell <terrelln@fb.com>
Wed, 19 Oct 2016 18:19:54 +0000 (11:19 -0700)
committerNick Terrell <terrelln@fb.com>
Wed, 19 Oct 2016 18:39:11 +0000 (11:39 -0700)
If `weightTotal == 0`, then `BIT_highbit32(weightTotal)` is
undefined behavior in the case that it calls `__builtin_clz()`.
If `tableLog == HUF_TABLELOG_ABSOLUTEMAX` then we will access one
byte beyond the end of the buffer.

lib/common/entropy_common.c
lib/legacy/zstd_v01.c
lib/legacy/zstd_v02.c
lib/legacy/zstd_v03.c
lib/legacy/zstd_v04.c
lib/legacy/zstd_v05.c
lib/legacy/zstd_v06.c
lib/legacy/zstd_v07.c

index 6625a8057960790d345f2e95f87845396c5256b4..18bba0e87b06dc370c00b1eb0091e23f0587582e 100644 (file)
@@ -200,6 +200,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
             rankStats[huffWeight[n]]++;
             weightTotal += (1 << huffWeight[n]) >> 1;
     }   }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     {   U32 const tableLog = BIT_highbit32(weightTotal) + 1;
index 217f34aa363873506e6c63773dcbcdebad2a72b8..5c36c2108e70ddd9b78c93b113a180aa22ae7800 100644 (file)
@@ -1008,6 +1008,7 @@ static size_t HUF_readDTable (U16* DTable, const void* src, size_t srcSize)
         rankVal[huffWeight[n]]++;
         weightTotal += (1 << huffWeight[n]) >> 1;
     }
+    if (weightTotal == 0) return (size_t)-FSE_ERROR_corruptionDetected;
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     maxBits = FSE_highbit32(weightTotal) + 1;
index cd1ce647e065e090be63b7844852c078830eb573..24498fedf8f47785229a6b05c39973daa8ae7bfc 100644 (file)
@@ -1654,6 +1654,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
         rankStats[huffWeight[n]]++;
         weightTotal += (1 << huffWeight[n]) >> 1;
     }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     tableLog = BIT_highbit32(weightTotal) + 1;
index 2de41f2bd8c7ca26d9435d3f55857fe0fdd31ec2..a3bd1da23811c26a247a1aea2b2febcd98ae2def 100644 (file)
@@ -1651,6 +1651,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
         rankStats[huffWeight[n]]++;
         weightTotal += (1 << huffWeight[n]) >> 1;
     }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     tableLog = BIT_highbit32(weightTotal) + 1;
index 599778b87e58d2749a03fb60b84243309bd4d755..60479cb7915383fc871ff314aeccd03b2e4b7b57 100644 (file)
@@ -1943,6 +1943,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
         rankStats[huffWeight[n]]++;
         weightTotal += (1 << huffWeight[n]) >> 1;
     }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     tableLog = BIT_highbit32(weightTotal) + 1;
index 0b46f0895d00973a17e090f5d6be8562b94776fa..2fde052c25a60d665235405358e2ef058954b5ec 100644 (file)
@@ -1912,6 +1912,7 @@ static size_t HUFv05_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
         rankStats[huffWeight[n]]++;
         weightTotal += (1 << huffWeight[n]) >> 1;
     }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     tableLog = BITv05_highbit32(weightTotal) + 1;
index 659b0e8eab7d22532c77a9a6928a953c90d16b24..3d65128460bf370bed7902bfcc379abfb4ddcae9 100644 (file)
@@ -1971,6 +1971,7 @@ MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankSta
             rankStats[huffWeight[n]]++;
             weightTotal += (1 << huffWeight[n]) >> 1;
     }   }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     {   U32 const tableLog = BITv06_highbit32(weightTotal) + 1;
index c8f223af7cacb0a88180531c1846712c8831fbae..ace64ede4f2d38905946020c05693cac0992466f 100644 (file)
@@ -1421,6 +1421,7 @@ size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
             rankStats[huffWeight[n]]++;
             weightTotal += (1 << huffWeight[n]) >> 1;
     }   }
+    if (weightTotal == 0) return ERROR(corruption_detected);
 
     /* get last non-null symbol weight (implied, total must be 2^n) */
     {   U32 const tableLog = BITv07_highbit32(weightTotal) + 1;