diff --git a/.travis.yml b/.travis.yml index 501afe9fe..83a6f23a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,9 @@ env: - ZSTD_TRAVIS_CI_ENV=armtest - ZSTD_TRAVIS_CI_ENV=test - ZSTD_TRAVIS_CI_ENV="-C programs test32" - - ZSTD_TRAVIS_CI_ENV=sanitize - - ZSTD_TRAVIS_CI_ENV="-C programs memtest" + - ZSTD_TRAVIS_CI_ENV=usan + - ZSTD_TRAVIS_CI_ENV=asan + - ZSTD_TRAVIS_CI_ENV="-C programs valgrindTest" matrix: fast_finish: true diff --git a/Makefile b/Makefile index a5e6cf8b0..4d837af85 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ # ################################################################ # Version number -export VERSION := 0.2.0 +export VERSION := 0.3.0 PRGDIR = programs ZSTDDIR = lib @@ -83,7 +83,13 @@ armtest: clean $(MAKE) -C $(ZSTDDIR) -e all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror" $(MAKE) -C $(PRGDIR) -e CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror" -sanitize: clean +usan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined" +asan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address" + +uasan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined" + endif diff --git a/lib/zstd.c b/lib/zstd.c index 6c3db75b0..e947fb8f7 100644 --- a/lib/zstd.c +++ b/lib/zstd.c @@ -173,14 +173,14 @@ struct ZSTD_CCtx_s #else U32 hashTable[HASH_TABLESIZE]; #endif - BYTE buffer[WORKPLACESIZE]; + BYTE buffer[WORKPLACESIZE]; }; void ZSTD_resetCCtx(ZSTD_CCtx* ctx) { ctx->base = NULL; - ctx->seqStore.buffer = ctx->buffer; + ctx->seqStore.buffer = ctx->buffer; ctx->seqStore.offsetStart = (U32*) (ctx->seqStore.buffer); ctx->seqStore.offCodeStart = (BYTE*) (ctx->seqStore.offsetStart + (BLOCKSIZE>>2)); ctx->seqStore.litStart = ctx->seqStore.offCodeStart + (BLOCKSIZE>>2); @@ -850,7 +850,7 @@ struct ZSTD_DCtx_s const BYTE* litPtr; size_t litBufSize; size_t litSize; - BYTE litBuffer[BLOCKSIZE]; + BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */]; }; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */ @@ -916,22 +916,29 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx, { case 0: { - size_t nbLiterals = BLOCKSIZE; - const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &nbLiterals, src, srcSize); + size_t litSize = BLOCKSIZE; + const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); dctx->litPtr = dctx->litBuffer; dctx->litBufSize = BLOCKSIZE; - dctx->litSize = nbLiterals; + dctx->litSize = litSize; return readSize; /* works if it's an error too */ } case IS_RAW: { const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ - if (litSize > srcSize-3) return ERROR(corruption_detected); + if (litSize > srcSize-11) /* risk of reading too far with wildcopy */ + { + if (litSize > srcSize-3) return ERROR(corruption_detected); + memcpy(dctx->litBuffer, istart, litSize); + dctx->litBufSize = BLOCKSIZE; + dctx->litSize = litSize; + return litSize+3; + } + /* direct reference into compressed stream */ dctx->litPtr = istart+3; dctx->litBufSize = srcSize-3; dctx->litSize = litSize; - return litSize+3; - } + return litSize+3; } case IS_RLE: { const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ @@ -1151,7 +1158,7 @@ static size_t ZSTD_execSequence(BYTE* op, /* check */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */ + if (litEnd > litLimit-8) 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 */ @@ -1311,7 +1318,7 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const magicNumber = MEM_readLE32(src); #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) if (magicNumber == ZSTDv01_magicNumberLE) return ZSTDv01_decompressDCtx(ctx, dst, maxDstSize, src, srcSize); -#endif /* ZSTD_LEGACY_SUPPORT */ +#endif if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown); ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize; diff --git a/programs/Makefile b/programs/Makefile index 891c55f75..be578c053 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -117,7 +117,7 @@ test: test-zstd test-fullbench test-fuzzer test32: test-zstd32 test-fullbench32 test-fuzzer32 -test-all: test test32 memtest +test-all: test test32 valgrindTest test-zstd: zstd datagen @echo "\n**** frame concatenation **** " @@ -159,7 +159,7 @@ test-fuzzer: fuzzer test-fuzzer32: fuzzer32 ./fuzzer32 -memtest: zstd datagen fuzzer fullbench +valgrindTest: zstd datagen fuzzer fullbench @echo "\n ---- valgrind tests : memory analyzer ----" valgrind --leak-check=yes --error-exitcode=1 ./datagen -g50M > $(VOID) ./datagen -g16KB > tmp