From b1da9c1aeee5cf8dfc86bd25f51e2963517beb5b Mon Sep 17 00:00:00 2001 From: Emmanuel Marty Date: Thu, 12 Sep 2019 16:19:14 +0200 Subject: [PATCH] Add extra bound checks in C decompressors --- src/expand_block_v1.c | 39 ++++++++++++++++++++++----------------- src/expand_block_v2.c | 39 ++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/expand_block_v1.c b/src/expand_block_v1.c index 0b87644..c248fb3 100644 --- a/src/expand_block_v1.c +++ b/src/expand_block_v1.c @@ -166,7 +166,7 @@ int lzsa_decompressor_expand_block_v1(const unsigned char *pInBlock, int nBlockS const unsigned char *pSrc = pCurOutData - nMatchOffset; if (pSrc >= pOutData) { 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 + 8, pSrc + 8, 8); memcpy(pCurOutData + 16, pSrc + 16, 2); @@ -181,27 +181,32 @@ int lzsa_decompressor_expand_block_v1(const unsigned char *pInBlock, int nBlockS break; } - if ((pCurOutData + nMatchLen) <= pOutDataEnd) { - /* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */ + if ((pSrc + nMatchLen) <= pOutDataEnd) { + 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)) { - const unsigned char *pCopySrc = pSrc; - unsigned char *pCopyDst = pCurOutData; - const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; + if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) { + const unsigned char *pCopySrc = pSrc; + unsigned char *pCopyDst = pCurOutData; + const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; - do { - memcpy(pCopyDst, pCopySrc, 16); - pCopySrc += 16; - pCopyDst += 16; - } while (pCopyDst < pCopyEndDst); + do { + memcpy(pCopyDst, pCopySrc, 16); + pCopySrc += 16; + pCopyDst += 16; + } while (pCopyDst < pCopyEndDst); - pCurOutData += nMatchLen; + pCurOutData += nMatchLen; + } + else { + while (nMatchLen) { + *pCurOutData++ = *pSrc++; + nMatchLen--; + } + } } else { - while (nMatchLen) { - *pCurOutData++ = *pSrc++; - nMatchLen--; - } + return -1; } } else { diff --git a/src/expand_block_v2.c b/src/expand_block_v2.c index 481461f..9e364f3 100644 --- a/src/expand_block_v2.c +++ b/src/expand_block_v2.c @@ -195,7 +195,7 @@ int lzsa_decompressor_expand_block_v2(const unsigned char *pInBlock, int nBlockS const unsigned char *pSrc = pCurOutData - nMatchOffset; if (pSrc >= pOutData) { 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 + 8, pSrc + 8, 2); pCurOutData += (MIN_MATCH_SIZE_V2 + nMatchLen); @@ -209,27 +209,32 @@ int lzsa_decompressor_expand_block_v2(const unsigned char *pInBlock, int nBlockS break; } - if ((pCurOutData + nMatchLen) <= pOutDataEnd) { - /* Do a deterministic, left to right byte copy instead of memcpy() so as to handle overlaps */ + if ((pSrc + nMatchLen) <= pOutDataEnd) { + 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)) { - const unsigned char *pCopySrc = pSrc; - unsigned char *pCopyDst = pCurOutData; - const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; + if (nMatchOffset >= 16 && (pCurOutData + nMatchLen) < (pOutDataFastEnd - 15)) { + const unsigned char *pCopySrc = pSrc; + unsigned char *pCopyDst = pCurOutData; + const unsigned char *pCopyEndDst = pCurOutData + nMatchLen; - do { - memcpy(pCopyDst, pCopySrc, 16); - pCopySrc += 16; - pCopyDst += 16; - } while (pCopyDst < pCopyEndDst); + do { + memcpy(pCopyDst, pCopySrc, 16); + pCopySrc += 16; + pCopyDst += 16; + } while (pCopyDst < pCopyEndDst); - pCurOutData += nMatchLen; + pCurOutData += nMatchLen; + } + else { + while (nMatchLen) { + *pCurOutData++ = *pSrc++; + nMatchLen--; + } + } } else { - while (nMatchLen) { - *pCurOutData++ = *pSrc++; - nMatchLen--; - } + return -1; } } else {