Merge pull request #3476 from facebook/fix55714
fix oss-fuzz case 55714
This commit is contained in:
+13
-7
@@ -1720,20 +1720,26 @@ static size_t ZSTD_execSequence(BYTE* op,
|
||||
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
|
||||
static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* subtracted */
|
||||
const BYTE* const ostart = op;
|
||||
BYTE* const oLitEnd = op + sequence.litLength;
|
||||
const size_t litLength = sequence.litLength;
|
||||
BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
|
||||
const BYTE* const litEnd = *litPtr + litLength;
|
||||
|
||||
/* check */
|
||||
/* checks */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
|
||||
if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected);
|
||||
|
||||
if (endMatch > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected);
|
||||
if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */
|
||||
|
||||
/* copy Literals */
|
||||
if (((size_t)(*litPtr - op) < 8) || ((size_t)(oend-litEnd) < 8) || (op+litLength > oend-8))
|
||||
memmove(op, *litPtr, litLength); /* overwrite risk */
|
||||
else
|
||||
ZSTD_wildcopy(op, *litPtr, litLength);
|
||||
ZSTD_memmove(op, *litPtr, sequence.litLength); /* note : v0.1 seems to allow scenarios where output or input are close to end of buffer */
|
||||
|
||||
op += litLength;
|
||||
*litPtr = litEnd; /* update for next sequence */
|
||||
|
||||
|
||||
@@ -3066,12 +3066,19 @@ static size_t ZSTD_execSequence(BYTE* op,
|
||||
const BYTE* const litEnd = *litPtr + sequence.litLength;
|
||||
|
||||
/* checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use the pointer check */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected);
|
||||
|
||||
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
|
||||
/* copy Literals */
|
||||
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
ZSTD_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = litEnd; /* update for next sequence */
|
||||
|
||||
|
||||
+10
-4
@@ -2706,18 +2706,24 @@ static size_t ZSTD_execSequence(BYTE* op,
|
||||
const BYTE* const litEnd = *litPtr + sequence.litLength;
|
||||
|
||||
/* checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected);
|
||||
|
||||
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
|
||||
/* copy Literals */
|
||||
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
ZSTD_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = litEnd; /* update for next sequence */
|
||||
|
||||
/* copy Match */
|
||||
{
|
||||
const BYTE* match = op - sequence.offset;
|
||||
{ const BYTE* match = op - sequence.offset;
|
||||
|
||||
/* check */
|
||||
if (sequence.offset > (size_t)op) return ERROR(corruption_detected); /* address space overflow test (this test seems kept by clang optimizer) */
|
||||
|
||||
+10
-4
@@ -2828,13 +2828,19 @@ static size_t ZSTD_execSequence(BYTE* op,
|
||||
const BYTE* const litEnd = *litPtr + sequence.litLength;
|
||||
const BYTE* match = oLitEnd - sequence.offset;
|
||||
|
||||
/* check */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||
/* checks */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
|
||||
|
||||
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
|
||||
/* copy Literals */
|
||||
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
ZSTD_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = litEnd; /* update for next sequence */
|
||||
|
||||
|
||||
+10
-4
@@ -3182,13 +3182,19 @@ static size_t ZSTDv05_execSequence(BYTE* op,
|
||||
const BYTE* const litEnd = *litPtr + sequence.litLength;
|
||||
const BYTE* match = oLitEnd - sequence.offset;
|
||||
|
||||
/* check */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||
/* checks */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
|
||||
|
||||
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */
|
||||
if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
|
||||
/* copy Literals */
|
||||
ZSTDv05_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
ZSTDv05_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = litEnd; /* update for next sequence */
|
||||
|
||||
|
||||
+10
-4
@@ -3322,13 +3322,19 @@ static size_t ZSTDv06_execSequence(BYTE* op,
|
||||
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
||||
const BYTE* match = oLitEnd - sequence.offset;
|
||||
|
||||
/* check */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||
/* checks */
|
||||
size_t const seqLength = sequence.litLength + sequence.matchLength;
|
||||
|
||||
if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
|
||||
/* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
|
||||
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
|
||||
|
||||
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||
if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
||||
if (iLitEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
|
||||
|
||||
/* copy Literals */
|
||||
ZSTDv06_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
ZSTDv06_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = iLitEnd; /* update for next sequence */
|
||||
|
||||
|
||||
@@ -3552,11 +3552,14 @@ size_t ZSTDv07_execSequence(BYTE* op,
|
||||
const BYTE* match = oLitEnd - sequence.offset;
|
||||
|
||||
/* check */
|
||||
if ((oLitEnd>oend_w) | (oMatchEnd>oend)) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
|
||||
if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
||||
assert(oend >= op);
|
||||
if (sequence.litLength + WILDCOPY_OVERLENGTH > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
if (sequenceLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
|
||||
assert(litLimit >= *litPtr);
|
||||
if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);;
|
||||
|
||||
/* copy Literals */
|
||||
ZSTDv07_wildcopy(op, *litPtr, sequence.litLength); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
|
||||
ZSTDv07_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
|
||||
op = oLitEnd;
|
||||
*litPtr = iLitEnd; /* update for next sequence */
|
||||
|
||||
@@ -3570,7 +3573,7 @@ size_t ZSTDv07_execSequence(BYTE* op,
|
||||
return sequenceLength;
|
||||
}
|
||||
/* span extDict & currentPrefixSegment */
|
||||
{ size_t const length1 = dictEnd - match;
|
||||
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||
memmove(oLitEnd, match, length1);
|
||||
op = oLitEnd + length1;
|
||||
sequence.matchLength -= length1;
|
||||
|
||||
Reference in New Issue
Block a user