From c7b005bc7864b6109115d4278872152208e78c23 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Tue, 25 Jan 2022 03:45:30 +0100 Subject: fuzz: Add fuzzer for JSON format --- fuzz/Makefile.am | 8 ++++++- fuzz/init-fuzzers.sh | 9 +++++++- fuzz/jplist.dict | 52 ++++++++++++++++++++++++++++++++++++++++++++++ fuzz/jplist_fuzzer.cc | 32 ++++++++++++++++++++++++++++ fuzz/jplist_fuzzer.options | 3 +++ fuzz/test-fuzzers.sh | 10 +++++++-- 6 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 fuzz/jplist.dict create mode 100644 fuzz/jplist_fuzzer.cc create mode 100644 fuzz/jplist_fuzzer.options diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am index 8fb7cc8..da6c8ae 100644 --- a/fuzz/Makefile.am +++ b/fuzz/Makefile.am @@ -21,7 +21,8 @@ CLEANFILES = libFuzzer.a noinst_PROGRAMS = \ xplist_fuzzer \ - bplist_fuzzer + bplist_fuzzer \ + jplist_fuzzer xplist_fuzzer_SOURCES = xplist_fuzzer.cc xplist_fuzzer_LDFLAGS = -static @@ -31,11 +32,16 @@ bplist_fuzzer_SOURCES = bplist_fuzzer.cc bplist_fuzzer_LDFLAGS = -static bplist_fuzzer_LDADD = $(top_builddir)/src/libplist-2.0.la libFuzzer.a +jplist_fuzzer_SOURCES = jplist_fuzzer.cc +jplist_fuzzer_LDFLAGS = -static +jplist_fuzzer_LDADD = $(top_builddir)/src/libplist-2.0.la libFuzzer.a + TESTS = fuzzers.test EXTRA_DIST = \ bplist.dict \ xplist.dict \ + jplist.dict \ init-fuzzers.sh \ test-fuzzers.sh \ fuzzers.test diff --git a/fuzz/init-fuzzers.sh b/fuzz/init-fuzzers.sh index 4d28016..ea2c8cc 100755 --- a/fuzz/init-fuzzers.sh +++ b/fuzz/init-fuzzers.sh @@ -5,7 +5,7 @@ FUZZDIR=`dirname $0` cd ${FUZZDIR} -if ! test -x xplist_fuzzer || ! test -x bplist_fuzzer; then +if ! test -x xplist_fuzzer || ! test -x bplist_fuzzer || ! test -x jplist_fuzzer; then echo "ERROR: you need to build the fuzzers first." cd ${CURDIR} exit 1 @@ -19,5 +19,12 @@ mkdir -p bplist-input cp ../test/data/*.bplist bplist-input/ ./bplist_fuzzer -merge=1 bplist-input bplist-crashes bplist-leaks -dict=bplist.dict +mkdir -p jplist-input +mkdir -p jplist-crashes +mkdir -p jplist-leaks +cp ../test/data/j1.plist jplist-input/ +cp ../test/data/j2.plist jplist-input/ +./jplist_fuzzer -merge=1 jplist-input jplist-crashes jplist-leaks -dict=jplist.dict + cd ${CURDIR} exit 0 diff --git a/fuzz/jplist.dict b/fuzz/jplist.dict new file mode 100644 index 0000000..e08245a --- /dev/null +++ b/fuzz/jplist.dict @@ -0,0 +1,52 @@ +# +# AFL dictionary for JSON +# ----------------------- +# +# Just the very basics. +# +# Inspired by a dictionary by Jakub Wilk +# + +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + +"\"\":0" +"//" +"/**/" diff --git a/fuzz/jplist_fuzzer.cc b/fuzz/jplist_fuzzer.cc new file mode 100644 index 0000000..d2fe8d3 --- /dev/null +++ b/fuzz/jplist_fuzzer.cc @@ -0,0 +1,32 @@ +/* + * xplist_fuzzer.cc + * XML plist fuzz target for libFuzzer + * + * Copyright (c) 2021 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) +{ + plist_t root_node = NULL; + plist_from_json(reinterpret_cast(data), size, &root_node); + plist_free(root_node); + + return 0; +} diff --git a/fuzz/jplist_fuzzer.options b/fuzz/jplist_fuzzer.options new file mode 100644 index 0000000..b22e679 --- /dev/null +++ b/fuzz/jplist_fuzzer.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 4096 +dict = jplist.dict diff --git a/fuzz/test-fuzzers.sh b/fuzz/test-fuzzers.sh index b0a8367..40be74f 100755 --- a/fuzz/test-fuzzers.sh +++ b/fuzz/test-fuzzers.sh @@ -5,13 +5,13 @@ FUZZDIR=`dirname $0` cd ${FUZZDIR} -if ! test -x xplist_fuzzer || ! test -x bplist_fuzzer; then +if ! test -x xplist_fuzzer || ! test -x bplist_fuzzer || ! test -x jplist_fuzzer; then echo "ERROR: you need to build the fuzzers first." cd ${CURDIR} exit 1 fi -if ! test -d xplist-input || ! test -d bplist-input; then +if ! test -d xplist-input || ! test -d bplist-input || ! test -d jplist-input; then echo "ERROR: fuzzer corpora directories are not present. Did you run init-fuzzers.sh ?" cd ${CURDIR} exit 1 @@ -29,5 +29,11 @@ if ! ./bplist_fuzzer bplist-input -dict=bplist.dict -max_len=4096 -runs=10000; t exit 1 fi +echo "### TESTING jplist_fuzzer ###" +if ! ./jplist_fuzzer jplist-input -dict=jplist.dict -max_len=65536 -runs=10000; then + cd ${CURDIR} + exit 1 +fi + cd ${CURDIR} exit 0 -- cgit v1.1-32-gdbae