]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fix decompression buffer overrun 479/head
authorNick Terrell <terrelln@fb.com>
Tue, 13 Dec 2016 02:05:30 +0000 (18:05 -0800)
committerNick Terrell <terrelln@fb.com>
Tue, 13 Dec 2016 02:05:30 +0000 (18:05 -0800)
Allows an adversary to write up to 3 bytes beyond the end of the buffer.
Occurs if the match overlaps the `extDict` and `currentPrefix`, and the
match length in the `currentPrefix` is less than `MINMATCH`, and
`op-(16-MINMATCH) >= oMatchEnd > op-16`.

lib/decompress/zstd_decompress.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 70dd4ccaae7df2dc3a42728273798a969b6a26a6..1422d2b3b3d9ca11c69283350846b04a4bc1d90d 100644 (file)
@@ -963,13 +963,13 @@ size_t ZSTD_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_w) {
+            if (op > oend_w || sequence.matchLength < MINMATCH) {
               U32 i;
               for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
               return sequenceLength;
             }
     }   }
-    /* Requirement: op <= oend_w */
+    /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
 
     /* match within prefix */
     if (sequence.offset < 8) {
@@ -1183,13 +1183,13 @@ size_t ZSTD_execSequenceLong(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_w) {
+            if (op > oend_w || sequence.matchLength < MINMATCH) {
               U32 i;
               for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
               return sequenceLength;
             }
     }   }
-    /* Requirement: op <= oend_w */
+    /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
 #endif
 
     /* match within prefix */
index 5c36c2108e70ddd9b78c93b113a180aa22ae7800..7c8b0f1e6031f8b7ad716788e1f5d56351c6e01e 100644 (file)
@@ -1803,7 +1803,7 @@ static size_t ZSTD_execSequence(BYTE* op,
         } else { ZSTD_copy8(op, match); }
         op += 8; match += 8;
 
-        if (endMatch > oend-12)
+        if (endMatch > oend-(16-MINMATCH))
         {
             if (op < oend-8)
             {
index ed082aad726a290248e61a069e3ef8161f7dfd63..135b5bc90cf4669c14e5d4761311b0e68d3c7918 100644 (file)
@@ -3206,7 +3206,7 @@ static size_t ZSTD_execSequence(BYTE* op,
         }
         op += 8; match += 8;
 
-        if (oMatchEnd > oend-12)
+        if (oMatchEnd > oend-(16-MINMATCH))
         {
             if (op < oend_8)
             {
index 3214506703e2556e02b097724e1180c08d828782..8cb5928fb533876b0951b09e783af4a605b7c7e3 100644 (file)
@@ -2847,7 +2847,7 @@ static size_t ZSTD_execSequence(BYTE* op,
         }
         op += 8; match += 8;
 
-        if (oMatchEnd > oend-12)
+        if (oMatchEnd > oend-(16-MINMATCH))
         {
             if (op < oend_8)
             {
index 11b5481a19184a5700a28cd0dd6bd2667b2e91f6..60cde97c561d889391fa097aa05a1f81208ed24f 100644 (file)
@@ -3107,7 +3107,7 @@ static size_t ZSTD_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_8) {
+            if (op > oend_8 || sequence.matchLength < MINMATCH) {
               while (op < oMatchEnd) *op++ = *match++;
               return sequenceLength;
             }
@@ -3134,7 +3134,7 @@ static size_t ZSTD_execSequence(BYTE* op,
     }
     op += 8; match += 8;
 
-    if (oMatchEnd > oend-12)
+    if (oMatchEnd > oend-(16-MINMATCH))
     {
         if (op < oend_8)
         {
index bf1235a357628079eda1e2869fd52fa75da7b6a1..3dcf703995d6d962ab580950177355bd714ca2bc 100644 (file)
@@ -3325,7 +3325,7 @@ static size_t ZSTDv05_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_8) {
+            if (op > oend_8 || sequence.matchLength < MINMATCH) {
               while (op < oMatchEnd) *op++ = *match++;
               return sequenceLength;
             }
@@ -3348,7 +3348,7 @@ static size_t ZSTDv05_execSequence(BYTE* op,
     }
     op += 8; match += 8;
 
-    if (oMatchEnd > oend-12) {
+    if (oMatchEnd > oend-(16-MINMATCH)) {
         if (op < oend_8) {
             ZSTDv05_wildcopy(op, match, oend_8 - op);
             match += oend_8 - op;
index 6584d48581e3c6f50d5e05cda44672105be53f3e..8aa6dc9990af15dc67c62e192d9f4db569253e4b 100644 (file)
@@ -3470,7 +3470,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_8) {
+            if (op > oend_8 || sequence.matchLength < MINMATCH) {
               while (op < oMatchEnd) *op++ = *match++;
               return sequenceLength;
             }
index 2ae6c5ad214dbb7678a553f0735396189e5676b9..7719ba089526ec97a2016e1c37c9372475d3dbf7 100644 (file)
@@ -3693,7 +3693,7 @@ size_t ZSTDv07_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-            if (op > oend_w) {
+            if (op > oend_w || sequence.matchLength < MINMATCH) {
               while (op < oMatchEnd) *op++ = *match++;
               return sequenceLength;
             }