diff options
author | Max Dymond <cmeister2@gmail.com> | 2019-06-25 17:22:02 +0100 |
---|---|---|
committer | Max Dymond <cmeister2@gmail.com> | 2019-06-28 08:30:02 +0100 |
commit | a5cf079d4dc9097c4e58f0eb7b0996b0a6d91696 (patch) | |
tree | 9c91b612a8bcbcfb0137518509d0fe3bcead50cc | |
parent | 798301b4e144fab5d25fc34566c1419685f5f1eb (diff) | |
download | lz4-a5cf079d4dc9097c4e58f0eb7b0996b0a6d91696.tar.gz lz4-a5cf079d4dc9097c4e58f0eb7b0996b0a6d91696.tar.bz2 lz4-a5cf079d4dc9097c4e58f0eb7b0996b0a6d91696.zip |
Add a fuzzing target that compiles in the oss-fuzz environment
-rw-r--r-- | .travis.yml | 6 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | ossfuzz/Makefile | 54 | ||||
-rw-r--r-- | ossfuzz/compress_fuzzer.cc | 22 | ||||
-rwxr-xr-x | ossfuzz/ossfuzz.sh | 26 | ||||
-rw-r--r-- | ossfuzz/standaloneengine.cc | 74 | ||||
-rw-r--r-- | ossfuzz/testinput.h | 3 | ||||
-rwxr-xr-x | ossfuzz/travisoss.sh | 24 |
8 files changed, 210 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml index ee643e5..4d45e89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -194,5 +194,11 @@ matrix: - pushd build - DESTDIR=./staging ninja install - tree ./staging + + # oss-fuzz compilation test + - name: Compile OSS-Fuzz targets + script: + - ./ossfuzz/travisoss.sh + allow_failures: - env: ALLOW_FAILURES=true @@ -34,6 +34,7 @@ LZ4DIR = lib PRGDIR = programs TESTDIR = tests EXDIR = examples +FUZZDIR = ossfuzz include Makefile.inc diff --git a/ossfuzz/Makefile b/ossfuzz/Makefile new file mode 100644 index 0000000..94829b2 --- /dev/null +++ b/ossfuzz/Makefile @@ -0,0 +1,54 @@ +# ########################################################################## +# LZ4 oss fuzzer - Makefile +# +# GPL v2 License +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# You can contact the author at : +# - LZ4 homepage : http://www.lz4.org +# - LZ4 source repository : https://github.com/lz4/lz4 +# ########################################################################## +# lz4_fuzzer : OSS Fuzz test tool +# ########################################################################## + +LZ4DIR := ../lib +LIB_FUZZING_ENGINE ?= standaloneengine.o + +DEBUGLEVEL?= 1 +DEBUGFLAGS = -g -DLZ4_DEBUG=$(DEBUGLEVEL) + +CFLAGS += -I$(LZ4DIR) $(DEBUGFLAGS) $(MOREFLAGS) +CPPFLAGS+= -I$(LZ4DIR) -DXXH_NAMESPACE=LZ4_ +FLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + +include ../Makefile.inc + +# Include a rule to build the static library if calling this target +# directly. +$(LZ4DIR)/liblz4.a: + $(MAKE) -C $(LZ4DIR) CFLAGS="$(CFLAGS)" liblz4.a + +%.o: %.cc + $(CXX) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + +.PHONY: compress_fuzzer +compress_fuzzer: compress_fuzzer.o $(LZ4DIR)/liblz4.a + # Compile the standalone code just in case. The OSS-Fuzz code might + # override the LIB_FUZZING_ENGINE value to "-fsanitize=fuzzer" + $(CXX) -c $(CFLAGS) $(CPPFLAGS) standaloneengine.cc -o standaloneengine.o + + # Now compile the actual fuzzer. + $(CXX) $(FLAGS) $(LIB_FUZZING_ENGINE) $^ -o $@$(EXT) diff --git a/ossfuzz/compress_fuzzer.cc b/ossfuzz/compress_fuzzer.cc new file mode 100644 index 0000000..006a0ab --- /dev/null +++ b/ossfuzz/compress_fuzzer.cc @@ -0,0 +1,22 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include "lz4.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + size_t const compressed_dest_size = LZ4_compressBound(size); + char *const dest_buffer = (char *)malloc(compressed_dest_size); + + int result = LZ4_compress_default((const char*)data, dest_buffer, + size, compressed_dest_size); + + if (result == 0) + { + abort(); + } + + free(dest_buffer); + + return 0; +} diff --git a/ossfuzz/ossfuzz.sh b/ossfuzz/ossfuzz.sh new file mode 100755 index 0000000..e0cb63c --- /dev/null +++ b/ossfuzz/ossfuzz.sh @@ -0,0 +1,26 @@ +#!/bin/bash -eu + +# This script is called by the oss-fuzz main project when compiling the fuzz +# targets. This script is regression tested by travisoss.sh. + +# Save off the current folder as the build root. +export BUILD_ROOT=$PWD + +# lz4 uses CPPFLAGS rather than CXX flags. +export CPPFLAGS="${CXXFLAGS}" + +echo "CC: $CC" +echo "CXX: $CXX" +echo "LIB_FUZZING_ENGINE: $LIB_FUZZING_ENGINE" +echo "CFLAGS: $CFLAGS" +echo "CPPFLAGS: $CPPFLAGS" +echo "OUT: $OUT" + +export MAKEFLAGS+="-j$(nproc)" + +pushd ossfuzz +make V=1 compress_fuzzer +popd + +# Copy the fuzzers to the target directory. +cp -v ossfuzz/compress_fuzzer $OUT/ diff --git a/ossfuzz/standaloneengine.cc b/ossfuzz/standaloneengine.cc new file mode 100644 index 0000000..175360e --- /dev/null +++ b/ossfuzz/standaloneengine.cc @@ -0,0 +1,74 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include "testinput.h" + +/** + * Main procedure for standalone fuzzing engine. + * + * Reads filenames from the argument array. For each filename, read the file + * into memory and then call the fuzzing interface with the data. + */ +int main(int argc, char **argv) +{ + int ii; + for(ii = 1; ii < argc; ii++) + { + FILE *infile; + printf("[%s] ", argv[ii]); + + /* Try and open the file. */ + infile = fopen(argv[ii], "rb"); + if(infile) + { + uint8_t *buffer = NULL; + size_t buffer_len; + + printf("Opened.. "); + + /* Get the length of the file. */ + fseek(infile, 0L, SEEK_END); + buffer_len = ftell(infile); + + /* Reset the file indicator to the beginning of the file. */ + fseek(infile, 0L, SEEK_SET); + + /* Allocate a buffer for the file contents. */ + buffer = (uint8_t *)calloc(buffer_len, sizeof(uint8_t)); + if(buffer) + { + /* Read all the text from the file into the buffer. */ + fread(buffer, sizeof(uint8_t), buffer_len, infile); + printf("Read %zu bytes, fuzzing.. ", buffer_len); + + /* Call the fuzzer with the data. */ + LLVMFuzzerTestOneInput(buffer, buffer_len); + + printf("complete !!"); + + /* Free the buffer as it's no longer needed. */ + free(buffer); + buffer = NULL; + } + else + { + fprintf(stderr, + "[%s] Failed to allocate %zu bytes \n", + argv[ii], + buffer_len); + } + + /* Close the file as it's no longer needed. */ + fclose(infile); + infile = NULL; + } + else + { + /* Failed to open the file. Maybe wrong name or wrong permissions? */ + fprintf(stderr, "[%s] Open failed. \n", argv[ii]); + } + + printf("\n"); + } +} diff --git a/ossfuzz/testinput.h b/ossfuzz/testinput.h new file mode 100644 index 0000000..6ab9b51 --- /dev/null +++ b/ossfuzz/testinput.h @@ -0,0 +1,3 @@ +#include <inttypes.h> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); diff --git a/ossfuzz/travisoss.sh b/ossfuzz/travisoss.sh new file mode 100755 index 0000000..3b2f26f --- /dev/null +++ b/ossfuzz/travisoss.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -ex + +# Clone the oss-fuzz repository +git clone https://github.com/google/oss-fuzz.git /tmp/ossfuzz + +if [[ ! -d /tmp/ossfuzz/projects/lz4 ]] +then + echo "Could not find the lz4 project in ossfuzz" + + # Exit with a success code while the lz4 project is not expected to exist + # on oss-fuzz. + exit 0 +fi + +# Modify the oss-fuzz Dockerfile so that we're checking out the current branch on travis. +sed -i "s@https://github.com/lz4/lz4.git@-b $TRAVIS_BRANCH https://github.com/lz4/lz4.git@" /tmp/ossfuzz/projects/lz4/Dockerfile + +# Try and build the fuzzers +pushd /tmp/ossfuzz +python infra/helper.py build_image --pull lz4 +python infra/helper.py build_fuzzers lz4 +popd |