1
0
mirror of https://github.com/facebook/zstd.git synced 2025-11-30 11:21:33 +03:00

Fix decompression buffer overrun

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`.
This commit is contained in:
Nick Terrell
2016-12-12 18:05:30 -08:00
parent 4c6ce5a57e
commit e474aa55b4
8 changed files with 13 additions and 13 deletions

View File

@@ -963,13 +963,13 @@ size_t ZSTD_execSequence(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_w) { if (op > oend_w || sequence.matchLength < MINMATCH) {
U32 i; U32 i;
for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
return sequenceLength; return sequenceLength;
} }
} } } }
/* Requirement: op <= oend_w */ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
/* match within prefix */ /* match within prefix */
if (sequence.offset < 8) { if (sequence.offset < 8) {
@@ -1183,13 +1183,13 @@ size_t ZSTD_execSequenceLong(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_w) { if (op > oend_w || sequence.matchLength < MINMATCH) {
U32 i; U32 i;
for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
return sequenceLength; return sequenceLength;
} }
} } } }
/* Requirement: op <= oend_w */ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
#endif #endif
/* match within prefix */ /* match within prefix */

View File

@@ -1803,7 +1803,7 @@ static size_t ZSTD_execSequence(BYTE* op,
} else { ZSTD_copy8(op, match); } } else { ZSTD_copy8(op, match); }
op += 8; match += 8; op += 8; match += 8;
if (endMatch > oend-12) if (endMatch > oend-(16-MINMATCH))
{ {
if (op < oend-8) if (op < oend-8)
{ {

View File

@@ -3206,7 +3206,7 @@ static size_t ZSTD_execSequence(BYTE* op,
} }
op += 8; match += 8; op += 8; match += 8;
if (oMatchEnd > oend-12) if (oMatchEnd > oend-(16-MINMATCH))
{ {
if (op < oend_8) if (op < oend_8)
{ {

View File

@@ -2847,7 +2847,7 @@ static size_t ZSTD_execSequence(BYTE* op,
} }
op += 8; match += 8; op += 8; match += 8;
if (oMatchEnd > oend-12) if (oMatchEnd > oend-(16-MINMATCH))
{ {
if (op < oend_8) if (op < oend_8)
{ {

View File

@@ -3107,7 +3107,7 @@ static size_t ZSTD_execSequence(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_8) { if (op > oend_8 || sequence.matchLength < MINMATCH) {
while (op < oMatchEnd) *op++ = *match++; while (op < oMatchEnd) *op++ = *match++;
return sequenceLength; return sequenceLength;
} }
@@ -3134,7 +3134,7 @@ static size_t ZSTD_execSequence(BYTE* op,
} }
op += 8; match += 8; op += 8; match += 8;
if (oMatchEnd > oend-12) if (oMatchEnd > oend-(16-MINMATCH))
{ {
if (op < oend_8) if (op < oend_8)
{ {

View File

@@ -3325,7 +3325,7 @@ static size_t ZSTDv05_execSequence(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_8) { if (op > oend_8 || sequence.matchLength < MINMATCH) {
while (op < oMatchEnd) *op++ = *match++; while (op < oMatchEnd) *op++ = *match++;
return sequenceLength; return sequenceLength;
} }
@@ -3348,7 +3348,7 @@ static size_t ZSTDv05_execSequence(BYTE* op,
} }
op += 8; match += 8; op += 8; match += 8;
if (oMatchEnd > oend-12) { if (oMatchEnd > oend-(16-MINMATCH)) {
if (op < oend_8) { if (op < oend_8) {
ZSTDv05_wildcopy(op, match, oend_8 - op); ZSTDv05_wildcopy(op, match, oend_8 - op);
match += oend_8 - op; match += oend_8 - op;

View File

@@ -3470,7 +3470,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_8) { if (op > oend_8 || sequence.matchLength < MINMATCH) {
while (op < oMatchEnd) *op++ = *match++; while (op < oMatchEnd) *op++ = *match++;
return sequenceLength; return sequenceLength;
} }

View File

@@ -3693,7 +3693,7 @@ size_t ZSTDv07_execSequence(BYTE* op,
op = oLitEnd + length1; op = oLitEnd + length1;
sequence.matchLength -= length1; sequence.matchLength -= length1;
match = base; match = base;
if (op > oend_w) { if (op > oend_w || sequence.matchLength < MINMATCH) {
while (op < oMatchEnd) *op++ = *match++; while (op < oMatchEnd) *op++ = *match++;
return sequenceLength; return sequenceLength;
} }