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/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/ossfuzz/ossfuzz.sh b/test/ossfuzz/ossfuzz.sh similarity index 87% rename from ossfuzz/ossfuzz.sh rename to test/ossfuzz/ossfuzz.sh index 897e5a6..9d72e79 100755 --- a/ossfuzz/ossfuzz.sh +++ b/test/ossfuzz/ossfuzz.sh @@ -20,9 +20,8 @@ apt-get -y install automake libtool # Compile the fuzzer. autoreconf -i -./configure +./configure --enable-ossfuzzers make -make json_load_fuzzer # Copy the fuzzer to the output directory. -cp -v json_load_fuzzer $OUT/ +cp -v test/ossfuzz/json_load_dump_fuzzer $OUT/ diff --git a/ossfuzz/standaloneengine.cc b/test/ossfuzz/standaloneengine.cc similarity index 100% rename from ossfuzz/standaloneengine.cc rename to test/ossfuzz/standaloneengine.cc diff --git a/ossfuzz/testinput.h b/test/ossfuzz/testinput.h similarity index 100% rename from ossfuzz/testinput.h rename to test/ossfuzz/testinput.h diff --git a/ossfuzz/travisoss.sh b/test/ossfuzz/travisoss.sh similarity index 100% rename from ossfuzz/travisoss.sh rename to test/ossfuzz/travisoss.sh