From 44b2464a3f33723df19d43705b89a32cd5938859 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Mon, 16 Apr 2018 12:16:54 +1000 Subject: [PATCH] Revert "move libtiff build scripts and fuzzers to the libtiff repo (#1317)" (#1319) This reverts commit 70b4b39e678bd6e671fd0c5c6803f000ba94f407. --- projects/libtiff/build.sh | 31 ++++++++++- projects/libtiff/tiff_read_rgba_fuzzer.cc | 67 +++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 projects/libtiff/tiff_read_rgba_fuzzer.cc diff --git a/projects/libtiff/build.sh b/projects/libtiff/build.sh index 088951579..487b4572c 100755 --- a/projects/libtiff/build.sh +++ b/projects/libtiff/build.sh @@ -15,4 +15,33 @@ # ################################################################################ -. contrib/oss-fuzz/build.sh + +# build zlib +pushd "$SRC/zlib" +./configure --static --prefix="$WORK" +make -j$(nproc) CFLAGS="$CFLAGS -fPIC" +make install +popd + +# Build libjpeg-turbo +pushd "$SRC/libjpeg-turbo" +cmake . -DCMAKE_INSTALL_PREFIX=$WORK -DENABLE_STATIC=on -DENABLE_SHARED=off +make -j$(nproc) +make install +popd + +cmake . -DCMAKE_INSTALL_PREFIX=$WORK -DBUILD_SHARED_LIBS=off +make -j$(nproc) +make install + +$CXX $CXXFLAGS -std=c++11 -I$WORK/include \ + $SRC/tiff_read_rgba_fuzzer.cc -o $OUT/tiff_read_rgba_fuzzer \ + -lFuzzingEngine $WORK/lib/libtiffxx.a $WORK/lib/libtiff.a $WORK/lib/libz.a $WORK/lib/libjpeg.a + +mkdir afl_testcases +(cd afl_testcases; tar xf "$SRC/afl_testcases.tgz") +mkdir tif +find afl_testcases -type f -name '*.tif' -exec mv -n {} tif/ \; +zip -rj tif.zip tif/ +cp tif.zip "$OUT/tiff_read_rgba_fuzzer_seed_corpus.zip" +cp "$SRC/tiff.dict" "$OUT/tiff_read_rgba_fuzzer.dict" diff --git a/projects/libtiff/tiff_read_rgba_fuzzer.cc b/projects/libtiff/tiff_read_rgba_fuzzer.cc new file mode 100644 index 000000000..e19481f4e --- /dev/null +++ b/projects/libtiff/tiff_read_rgba_fuzzer.cc @@ -0,0 +1,67 @@ +#include +#include +#include +#include + + +/* stolen from tiffiop.h, which is a private header so we can't just include it */ +/* safe multiply returns either the multiplied value or 0 if it overflowed */ +#define __TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) + +const tmsize_t MAX_SIZE = 500000000; + +extern "C" void handle_error(const char *unused, const char *unused2, va_list unused3) { + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + TIFFSetErrorHandler(handle_error); + TIFFSetWarningHandler(handle_error); + std::istringstream s(std::string(Data,Data+Size)); + TIFF* tif = TIFFStreamOpen("MemTIFF", &s); + if (!tif) { + return 0; + } + uint32 w, h; + size_t npixels; + uint32* raster; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + /* don't continue if image has negative size or the file size is ludicrous */ + if (TIFFTileSize(tif) > MAX_SIZE || w <=0 || h <= 0) { + TIFFClose(tif); + return 0; + } + tmsize_t bufsize = __TIFFSafeMultiply(tmsize_t, TIFFTileSize(tif), 4); + /* don't continue if the buffer size greater than the max allowed by the fuzzer */ + if (bufsize > MAX_SIZE || bufsize == 0) { + TIFFClose(tif); + return 0; + } + /* another hack to work around an OOM in tif_fax3.c */ + uint32 tilewidth = 0; + uint32 imagewidth = 0; + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tilewidth); + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth); + tilewidth = __TIFFSafeMultiply(uint32, tilewidth, 2); + imagewidth = __TIFFSafeMultiply(uint32, imagewidth, 2); + if (tilewidth * 2 > MAX_SIZE || imagewidth * 2 > MAX_SIZE || tilewidth == 0 || imagewidth == 0) { + TIFFClose(tif); + return 0; + } + npixels = w * h; + uint32 size = __TIFFSafeMultiply(uint32, w, h); + if (size > MAX_SIZE || size == 0) { + TIFFClose(tif); + return 0; + } + raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); + if (raster != NULL) { + TIFFReadRGBAImage(tif, w, h, raster, 0); + _TIFFfree(raster); + } + TIFFClose(tif); + + return 0; +}