diff options
author | Corey Farrell <git@cfware.com> | 2019-07-22 05:29:22 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-22 05:29:22 -0400 |
commit | 3bfa3f1946a8afe0d9ad3082ebfe6a8dd3346814 (patch) | |
tree | 656b714035b67bb5d02779195039cdfbcd1dedb6 /test | |
parent | 813c3e2c47ac716a53d496346d95fbbb14ca1153 (diff) | |
parent | 24cc9dd0789d368861d750e0ebdda8747a0597d0 (diff) | |
download | jansson-3bfa3f1946a8afe0d9ad3082ebfe6a8dd3346814.zip jansson-3bfa3f1946a8afe0d9ad3082ebfe6a8dd3346814.tar.gz jansson-3bfa3f1946a8afe0d9ad3082ebfe6a8dd3346814.tar.bz2 |
Merge pull request #480 from cmeister2/cmeister2/ossfuzz
oss-fuzz: Create a fuzzing target for jansson
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/ossfuzz/.gitignore | 1 | ||||
-rw-r--r-- | test/ossfuzz/Makefile.am | 32 | ||||
-rw-r--r-- | test/ossfuzz/json_load_dump_fuzzer.cc | 47 | ||||
-rwxr-xr-x | test/ossfuzz/ossfuzz.sh | 27 | ||||
-rw-r--r-- | test/ossfuzz/standaloneengine.cc | 74 | ||||
-rw-r--r-- | test/ossfuzz/testinput.h | 3 | ||||
-rwxr-xr-x | test/ossfuzz/travisoss.sh | 26 |
8 files changed, 211 insertions, 1 deletions
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 <stdint.h> +#include <sys/types.h> + +#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<const char *>(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 <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/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 <inttypes.h> + +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 |