From b487660309d4245eec87e3ada4712bc2a19df791 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 18 Jul 2019 18:45:32 -0700 Subject: [lz4frame] Skip magic and checksums in fuzzing mode When `FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` is defined we skip magic and checksum checks. This makes it easier to fuzz decompression. --- lib/lz4frame.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/lz4frame.c b/lib/lz4frame.c index cc7f2d5..13c1ae9 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -1131,8 +1131,10 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize } /* control magic number */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (LZ4F_readLE32(srcPtr) != LZ4F_MAGICNUMBER) return err0r(LZ4F_ERROR_frameType_unknown); +#endif dctx->frameInfo.frameType = LZ4F_frame; /* Flags */ @@ -1171,10 +1173,12 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize /* check header */ assert(frameHeaderSize > 5); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION { BYTE const HC = LZ4F_headerChecksum(srcPtr+4, frameHeaderSize-5); if (HC != srcPtr[frameHeaderSize-1]) return err0r(LZ4F_ERROR_headerChecksum_invalid); } +#endif /* save */ dctx->frameInfo.blockMode = (LZ4F_blockMode_t)blockMode; @@ -1211,8 +1215,10 @@ size_t LZ4F_headerSize(const void* src, size_t srcSize) return 8; /* control magic number */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (LZ4F_readLE32(src) != LZ4F_MAGICNUMBER) return err0r(LZ4F_ERROR_frameType_unknown); +#endif /* Frame Header Size */ { BYTE const FLG = ((const BYTE*)src)[4]; @@ -1555,8 +1561,10 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx, } { U32 const readCRC = LZ4F_readLE32(crcSrc); U32 const calcCRC = XXH32_digest(&dctx->blockChecksum); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (readCRC != calcCRC) return err0r(LZ4F_ERROR_blockChecksum_invalid); +#endif } } dctx->dStage = dstage_getBlockHeader; /* new block */ break; @@ -1595,8 +1603,10 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx, assert(selectedIn != NULL); /* selectedIn is defined at this stage (either srcPtr, or dctx->tmpIn) */ { U32 const readBlockCrc = LZ4F_readLE32(selectedIn + dctx->tmpInTarget); U32 const calcBlockCrc = XXH32(selectedIn, dctx->tmpInTarget, 0); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (readBlockCrc != calcBlockCrc) return err0r(LZ4F_ERROR_blockChecksum_invalid); +#endif } } if ((size_t)(dstEnd-dstPtr) >= dctx->maxBlockSize) { @@ -1724,8 +1734,10 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx, /* case dstage_checkSuffix: */ /* no direct entry, avoid initialization risks */ { U32 const readCRC = LZ4F_readLE32(selectedIn); U32 const resultCRC = XXH32_digest(&(dctx->xxh)); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (readCRC != resultCRC) return err0r(LZ4F_ERROR_contentChecksum_invalid); +#endif nextSrcSizeHint = 0; LZ4F_resetDecompressionContext(dctx); doAnotherStage = 0; -- cgit v0.12