From 24cc9dd0789d368861d750e0ebdda8747a0597d0 Mon Sep 17 00:00:00 2001 From: Max Dymond Date: Thu, 18 Jul 2019 14:49:07 +0100 Subject: Move ossfuzz directory and use Makefile.am --- .travis.yml | 2 +- Makefile.am | 12 ------ configure.ac | 15 +++++++ ossfuzz/json_load_fuzzer.cc | 11 ------ ossfuzz/ossfuzz.sh | 28 ------------- ossfuzz/standaloneengine.cc | 74 ----------------------------------- ossfuzz/testinput.h | 3 -- ossfuzz/travisoss.sh | 26 ------------ test/Makefile.am | 2 +- test/ossfuzz/.gitignore | 1 + test/ossfuzz/Makefile.am | 32 +++++++++++++++ test/ossfuzz/json_load_dump_fuzzer.cc | 47 ++++++++++++++++++++++ test/ossfuzz/ossfuzz.sh | 27 +++++++++++++ test/ossfuzz/standaloneengine.cc | 74 +++++++++++++++++++++++++++++++++++ test/ossfuzz/testinput.h | 3 ++ test/ossfuzz/travisoss.sh | 26 ++++++++++++ 16 files changed, 227 insertions(+), 156 deletions(-) delete mode 100644 ossfuzz/json_load_fuzzer.cc delete mode 100755 ossfuzz/ossfuzz.sh delete mode 100644 ossfuzz/standaloneengine.cc delete mode 100644 ossfuzz/testinput.h delete mode 100755 ossfuzz/travisoss.sh create mode 100644 test/ossfuzz/.gitignore create mode 100644 test/ossfuzz/Makefile.am create mode 100644 test/ossfuzz/json_load_dump_fuzzer.cc create mode 100755 test/ossfuzz/ossfuzz.sh create mode 100644 test/ossfuzz/standaloneengine.cc create mode 100644 test/ossfuzz/testinput.h create mode 100755 test/ossfuzz/travisoss.sh diff --git a/.travis.yml b/.travis.yml index 449e9bb..8dae9a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,4 @@ script: - if [ "$JANSSON_BUILD_METHOD" = "autotools" ]; then autoreconf -f -i && CFLAGS=-Werror ./configure && make check; fi - if [ "$JANSSON_BUILD_METHOD" = "cmake" ]; then mkdir build && cd build && cmake $JANSSON_CMAKE_OPTIONS .. && cmake --build . && ctest --output-on-failure; fi - if [ "$JANSSON_BUILD_METHOD" = "coverage" ]; then mkdir build && cd build && cmake $JANSSON_CMAKE_OPTIONS .. && cmake --build . && cmake --build . --target coveralls; fi - - if [ "$JANSSON_BUILD_METHOD" = "fuzzer" ]; then ./ossfuzz/travisoss.sh; fi + - if [ "$JANSSON_BUILD_METHOD" = "fuzzer" ]; then ./test/ossfuzz/travisoss.sh; fi diff --git a/Makefile.am b/Makefile.am index 3e3dc09..0de2ac1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,15 +8,3 @@ dvi: pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = jansson.pc - - -# Add fuzzing support -LIB_FUZZING_ENGINE ?= standaloneengine.o - -ossfuzz/%.o: ossfuzz/%.cc - $(CXX) -c -Isrc $(CXXFLAGS) $< -o $@ - -.PHONY: json_load_fuzzer -json_load_fuzzer: ossfuzz/json_load_fuzzer.o src/.libs/libjansson.a - $(CXX) -c $(CXXFLAGS) ossfuzz/standaloneengine.cc -o standaloneengine.o - $(CXX) $(CXXFLAGS) $(LIB_FUZZING_ENGINE) $^ -o $@$(EXT) diff --git a/configure.ac b/configure.ac index cf9ac33..1e6500b 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,7 @@ AC_CONFIG_HEADERS([jansson_private_config.h]) # Checks for programs. AC_PROG_CC +AC_PROG_CXX AC_PROG_LIBTOOL AM_CONDITIONAL([GCC], [test x$GCC = xyes]) @@ -136,6 +137,19 @@ fi AS_IF([test "x$with_Bsymbolic" = "xyes"], [JSON_BSYMBOLIC_LDFLAGS=-Wl[,]-Bsymbolic-functions]) AC_SUBST(JSON_BSYMBOLIC_LDFLAGS) + +AC_ARG_ENABLE([ossfuzzers], + [AS_HELP_STRING([--enable-ossfuzzers], + [Whether to generate the fuzzers for OSS-Fuzz])], + [have_ossfuzzers=yes], [have_ossfuzzers=no]) +AM_CONDITIONAL([USE_OSSFUZZERS], [test "x$have_ossfuzzers" = "xyes"]) + + +AC_SUBST([LIB_FUZZING_ENGINE]) +AM_CONDITIONAL([USE_OSSFUZZ_FLAG], [test "x$LIB_FUZZING_ENGINE" = "x-fsanitize=fuzzer"]) +AM_CONDITIONAL([USE_OSSFUZZ_STATIC], [test -f "x$LIB_FUZZING_ENGINE"]) + + if test x$GCC = xyes; then AC_MSG_CHECKING(for -Wno-format-truncation) wnoformat_truncation="-Wno-format-truncation" @@ -156,6 +170,7 @@ AC_CONFIG_FILES([ src/jansson_config.h test/Makefile test/bin/Makefile + test/ossfuzz/Makefile test/suites/Makefile test/suites/api/Makefile ]) diff --git a/ossfuzz/json_load_fuzzer.cc b/ossfuzz/json_load_fuzzer.cc deleted file mode 100644 index 09e7da5..0000000 --- a/ossfuzz/json_load_fuzzer.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#include "jansson.h" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - json_error_t error; - auto jobj = json_loadb(reinterpret_cast(data), size, 0, &error); - if (jobj) - json_decref(jobj); - return 0; -} diff --git a/ossfuzz/ossfuzz.sh b/ossfuzz/ossfuzz.sh deleted file mode 100755 index 897e5a6..0000000 --- a/ossfuzz/ossfuzz.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/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 - -echo "CC: $CC" -echo "CXX: $CXX" -echo "LIB_FUZZING_ENGINE: $LIB_FUZZING_ENGINE" -echo "CFLAGS: $CFLAGS" -echo "CXXFLAGS: $CXXFLAGS" -echo "OUT: $OUT" - -export MAKEFLAGS+="-j$(nproc)" - -# Install dependencies -apt-get -y install automake libtool - -# Compile the fuzzer. -autoreconf -i -./configure -make -make json_load_fuzzer - -# Copy the fuzzer to the output directory. -cp -v json_load_fuzzer $OUT/ diff --git a/ossfuzz/standaloneengine.cc b/ossfuzz/standaloneengine.cc deleted file mode 100644 index 175360e..0000000 --- a/ossfuzz/standaloneengine.cc +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include - -#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 deleted file mode 100644 index 6ab9b51..0000000 --- a/ossfuzz/testinput.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); diff --git a/ossfuzz/travisoss.sh b/ossfuzz/travisoss.sh deleted file mode 100755 index e99cc6e..0000000 --- a/ossfuzz/travisoss.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -set -ex - -PROJECT_NAME=jansson - -# Clone the oss-fuzz repository -git clone https://github.com/google/oss-fuzz.git /tmp/ossfuzz - -if [[ ! -d /tmp/ossfuzz/projects/${PROJECT_NAME} ]] -then - echo "Could not find the ${PROJECT_NAME} project in ossfuzz" - - # Exit with a success code while the jansson 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/akheron/jansson.git@-b $TRAVIS_BRANCH https://github.com/akheron/jansson.git@" /tmp/ossfuzz/projects/${PROJECT_NAME}/Dockerfile - -# Try and build the fuzzers -pushd /tmp/ossfuzz -python infra/helper.py build_image --pull ${PROJECT_NAME} -python infra/helper.py build_fuzzers ${PROJECT_NAME} -popd diff --git a/test/Makefile.am b/test/Makefile.am index 86d1614..344d18d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = bin suites +SUBDIRS = bin suites ossfuzz EXTRA_DIST = scripts run-suites TESTS = run-suites diff --git a/test/ossfuzz/.gitignore b/test/ossfuzz/.gitignore new file mode 100644 index 0000000..7fbb867 --- /dev/null +++ b/test/ossfuzz/.gitignore @@ -0,0 +1 @@ +json_load_dump_fuzzer diff --git a/test/ossfuzz/Makefile.am b/test/ossfuzz/Makefile.am new file mode 100644 index 0000000..a2e802e --- /dev/null +++ b/test/ossfuzz/Makefile.am @@ -0,0 +1,32 @@ +AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src +LDADD = $(top_builddir)/src/libjansson.la + +if USE_OSSFUZZ_FLAG +FUZZ_FLAG = $(LIB_FUZZING_ENGINE) +else +if USE_OSSFUZZ_STATIC +LDADD += $(LIB_FUZZING_ENGINE) +FUZZ_FLAG = +else +LDADD += libstandaloneengine.a +FUZZ_FLAG = +endif +endif + +noinst_PROGRAMS = +noinst_LIBRARIES = + +if USE_OSSFUZZERS +noinst_PROGRAMS += \ + json_load_dump_fuzzer + +noinst_LIBRARIES += \ + libstandaloneengine.a +endif + +json_load_dump_fuzzer_SOURCES = json_load_dump_fuzzer.cc testinput.h +json_load_dump_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG) +json_load_dump_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static + +libstandaloneengine_a_SOURCES = standaloneengine.cc +libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS) diff --git a/test/ossfuzz/json_load_dump_fuzzer.cc b/test/ossfuzz/json_load_dump_fuzzer.cc new file mode 100644 index 0000000..09f52d2 --- /dev/null +++ b/test/ossfuzz/json_load_dump_fuzzer.cc @@ -0,0 +1,47 @@ +#include +#include + +#include "jansson.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + json_error_t error; + + if (size < sizeof(size_t) + sizeof(size_t)) + { + return 0; + } + + // Use the first sizeof(size_t) bytes as load flags. + size_t load_flags = *(const size_t*)data; + data += sizeof(size_t); + size -= sizeof(size_t); + + // Use the next sizeof(size_t) bytes as dump flags. + size_t dump_flags = *(const size_t*)data; + data += sizeof(size_t); + size -= sizeof(size_t); + + // Attempt to load the remainder of the data with the given load flags. + const char* text = reinterpret_cast(data); + json_t* jobj = json_loadb(text, size, load_flags, &error); + + if (jobj == NULL) + { + return 0; + } + + // Attempt to dump the loaded json object with the given dump flags. + char* out = json_dumps(jobj, dump_flags); + if (out) + { + free(out); + } + + if (jobj) + { + json_decref(jobj); + } + + return 0; +} \ No newline at end of file diff --git a/test/ossfuzz/ossfuzz.sh b/test/ossfuzz/ossfuzz.sh new file mode 100755 index 0000000..9d72e79 --- /dev/null +++ b/test/ossfuzz/ossfuzz.sh @@ -0,0 +1,27 @@ +#!/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 + +echo "CC: $CC" +echo "CXX: $CXX" +echo "LIB_FUZZING_ENGINE: $LIB_FUZZING_ENGINE" +echo "CFLAGS: $CFLAGS" +echo "CXXFLAGS: $CXXFLAGS" +echo "OUT: $OUT" + +export MAKEFLAGS+="-j$(nproc)" + +# Install dependencies +apt-get -y install automake libtool + +# Compile the fuzzer. +autoreconf -i +./configure --enable-ossfuzzers +make + +# Copy the fuzzer to the output directory. +cp -v test/ossfuzz/json_load_dump_fuzzer $OUT/ diff --git a/test/ossfuzz/standaloneengine.cc b/test/ossfuzz/standaloneengine.cc new file mode 100644 index 0000000..175360e --- /dev/null +++ b/test/ossfuzz/standaloneengine.cc @@ -0,0 +1,74 @@ +#include +#include +#include + +#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/test/ossfuzz/testinput.h b/test/ossfuzz/testinput.h new file mode 100644 index 0000000..6ab9b51 --- /dev/null +++ b/test/ossfuzz/testinput.h @@ -0,0 +1,3 @@ +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); diff --git a/test/ossfuzz/travisoss.sh b/test/ossfuzz/travisoss.sh new file mode 100755 index 0000000..e99cc6e --- /dev/null +++ b/test/ossfuzz/travisoss.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -ex + +PROJECT_NAME=jansson + +# Clone the oss-fuzz repository +git clone https://github.com/google/oss-fuzz.git /tmp/ossfuzz + +if [[ ! -d /tmp/ossfuzz/projects/${PROJECT_NAME} ]] +then + echo "Could not find the ${PROJECT_NAME} project in ossfuzz" + + # Exit with a success code while the jansson 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/akheron/jansson.git@-b $TRAVIS_BRANCH https://github.com/akheron/jansson.git@" /tmp/ossfuzz/projects/${PROJECT_NAME}/Dockerfile + +# Try and build the fuzzers +pushd /tmp/ossfuzz +python infra/helper.py build_image --pull ${PROJECT_NAME} +python infra/helper.py build_fuzzers ${PROJECT_NAME} +popd -- cgit v1.1