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:
@@ -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 */
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user