Add extra bound checks in C decompressors

This commit is contained in:
Emmanuel Marty
2019-09-12 16:19:14 +02:00
committed by GitHub
parent b92a003338
commit b1da9c1aee
2 changed files with 44 additions and 34 deletions

View File

@@ -166,7 +166,7 @@ int lzsa_decompressor_expand_block_v1(const unsigned char *pInBlock, int nBlockS
const unsigned char *pSrc = pCurOutData - nMatchOffset; const unsigned char *pSrc = pCurOutData - nMatchOffset;
if (pSrc >= pOutData) { if (pSrc >= pOutData) {
unsigned int nMatchLen = (unsigned int)(token & 0x0f); unsigned int nMatchLen = (unsigned int)(token & 0x0f);
if (nMatchLen != MATCH_RUN_LEN_V1 && nMatchOffset >= 8 && pCurOutData < pOutDataFastEnd) { if (nMatchLen != MATCH_RUN_LEN_V1 && nMatchOffset >= 8 && pCurOutData < pOutDataFastEnd && (pSrc + 18) <= pOutDataEnd) {
memcpy(pCurOutData, pSrc, 8); memcpy(pCurOutData, pSrc, 8);
memcpy(pCurOutData + 8, pSrc + 8, 8); memcpy(pCurOutData + 8, pSrc + 8, 8);
memcpy(pCurOutData + 16, pSrc + 16, 2); memcpy(pCurOutData + 16, pSrc + 16, 2);
@@ -181,27 +181,32 @@ int lzsa_decompressor_expand_block_v1(const unsigned char *pInBlock, int nBlockS
break; break;
} }
if ((pCurOutData + nMatchLen) <= pOutDataEnd) { if ((pSrc + nMatchLen) <= pOutDataEnd) {
/* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */ if ((pCurOutData + nMatchLen) <= pOutDataEnd) {
/* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */
if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) { if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) {
const unsigned char *pCopySrc = pSrc; const unsigned char *pCopySrc = pSrc;
unsigned char *pCopyDst = pCurOutData; unsigned char *pCopyDst = pCurOutData;
const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; const unsigned char *pCopyEndDst = pCurOutData + nMatchLen;
do { do {
memcpy(pCopyDst, pCopySrc, 16); memcpy(pCopyDst, pCopySrc, 16);
pCopySrc += 16; pCopySrc += 16;
pCopyDst += 16; pCopyDst += 16;
} while (pCopyDst < pCopyEndDst); } while (pCopyDst < pCopyEndDst);
pCurOutData += nMatchLen; pCurOutData += nMatchLen;
}
else {
while (nMatchLen) {
*pCurOutData++ = *pSrc++;
nMatchLen--;
}
}
} }
else { else {
while (nMatchLen) { return -1;
*pCurOutData++ = *pSrc++;
nMatchLen--;
}
} }
} }
else { else {

View File

@@ -195,7 +195,7 @@ int lzsa_decompressor_expand_block_v2(const unsigned char *pInBlock, int nBlockS
const unsigned char *pSrc = pCurOutData - nMatchOffset; const unsigned char *pSrc = pCurOutData - nMatchOffset;
if (pSrc >= pOutData) { if (pSrc >= pOutData) {
unsigned int nMatchLen = (unsigned int)(token & 0x07); unsigned int nMatchLen = (unsigned int)(token & 0x07);
if (nMatchLen != MATCH_RUN_LEN_V2 && nMatchOffset >= 8 && pCurOutData < pOutDataFastEnd) { if (nMatchLen != MATCH_RUN_LEN_V2 && nMatchOffset >= 8 && pCurOutData < pOutDataFastEnd && (pSrc + 10) <= pOutDataEnd) {
memcpy(pCurOutData, pSrc, 8); memcpy(pCurOutData, pSrc, 8);
memcpy(pCurOutData + 8, pSrc + 8, 2); memcpy(pCurOutData + 8, pSrc + 8, 2);
pCurOutData += (MIN_MATCH_SIZE_V2 + nMatchLen); pCurOutData += (MIN_MATCH_SIZE_V2 + nMatchLen);
@@ -209,27 +209,32 @@ int lzsa_decompressor_expand_block_v2(const unsigned char *pInBlock, int nBlockS
break; break;
} }
if ((pCurOutData + nMatchLen) <= pOutDataEnd) { if ((pSrc + nMatchLen) <= pOutDataEnd) {
/* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */ if ((pCurOutData + nMatchLen) <= pOutDataEnd) {
/* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */
if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) { if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) {
const unsigned char *pCopySrc = pSrc; const unsigned char *pCopySrc = pSrc;
unsigned char *pCopyDst = pCurOutData; unsigned char *pCopyDst = pCurOutData;
const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; const unsigned char *pCopyEndDst = pCurOutData + nMatchLen;
do { do {
memcpy(pCopyDst, pCopySrc, 16); memcpy(pCopyDst, pCopySrc, 16);
pCopySrc += 16; pCopySrc += 16;
pCopyDst += 16; pCopyDst += 16;
} while (pCopyDst < pCopyEndDst); } while (pCopyDst < pCopyEndDst);
pCurOutData += nMatchLen; pCurOutData += nMatchLen;
}
else {
while (nMatchLen) {
*pCurOutData++ = *pSrc++;
nMatchLen--;
}
}
} }
else { else {
while (nMatchLen) { return -1;
*pCurOutData++ = *pSrc++;
nMatchLen--;
}
} }
} }
else { else {