From 4acc63e325fbe0e5b93638073d08f75905f15e63 Mon Sep 17 00:00:00 2001 From: Andrew Chambers Date: Fri, 29 Nov 2019 16:41:27 +1300 Subject: [PATCH] Add afl fuzzing helpers. --- tools/afl/README.md | 14 ++++++++++ tools/afl/aggregate_cases.sh | 13 +++++++++ tools/afl/fuzz.sh | 36 +++++++++++++++++++++++++ tools/afl/parser_runner.janet | 4 +++ tools/afl/parser_testcases/simple.janet | 15 +++++++++++ tools/afl/prepare_to_fuzz.sh | 6 +++++ 6 files changed, 88 insertions(+) create mode 100644 tools/afl/README.md create mode 100644 tools/afl/aggregate_cases.sh create mode 100644 tools/afl/fuzz.sh create mode 100644 tools/afl/parser_runner.janet create mode 100644 tools/afl/parser_testcases/simple.janet create mode 100644 tools/afl/prepare_to_fuzz.sh diff --git a/tools/afl/README.md b/tools/afl/README.md new file mode 100644 index 00000000..f4a8edb9 --- /dev/null +++ b/tools/afl/README.md @@ -0,0 +1,14 @@ +# AFL Fuzzing scripts + +To use these, you need to install afl (of course), and xterm. A tiling window manager helps manage +many concurrent fuzzer instances. + +## Fuzz the parser +``` +$ sh ./tools/afl/prepare_to_fuzz.sh +export NFUZZ=1 +$ sh ./tools/afl/fuzz.sh parser +Ctrl+C when done to close all fuzzer terminals. +$ sh ./tools/afl/aggregate_cases.sh parser +$ ls ./fuzz_out/parser_aggregated/ +``` \ No newline at end of file diff --git a/tools/afl/aggregate_cases.sh b/tools/afl/aggregate_cases.sh new file mode 100644 index 00000000..098ab34a --- /dev/null +++ b/tools/afl/aggregate_cases.sh @@ -0,0 +1,13 @@ +set -eux + +n=0 +for tc in $(echo ./fuzz_out/$1/*/hangs/* ./fuzz_out/$1/*/crashes/*) +do + if ! test -e $tc + then + continue + fi + mkdir -p ./fuzz_out/$1_aggregated/ + cp "$tc" $(printf "./fuzz_out/$1_aggregated/$1-%04d.test" $n) + n=$((n + 1)) +done diff --git a/tools/afl/fuzz.sh b/tools/afl/fuzz.sh new file mode 100644 index 00000000..6cb78fce --- /dev/null +++ b/tools/afl/fuzz.sh @@ -0,0 +1,36 @@ +set -eux + +NFUZZ=${NFUZZ:-1} +children="" + +function finish { + for pid in $children + do + set +e + kill -s INT $pid + done + wait +} +trap finish EXIT + +test -e ./tools/afl/$1_testcases +test -e ./tools/afl/$1_runner.janet + +echo "running fuzz master..." +xterm -e \ + "afl-fuzz -i ./tools/afl/$1_testcases -o ./fuzz_out/$1 -M Fuzz$1_0 -- ./build/janet ./tools/afl/$1_runner.janet @@" & +children="$! $children" +echo "waiting for afl to get started before starting secondary fuzzers" +sleep 10 + +NFUZZ=$((NFUZZ - 1)) + +for N in $(seq $NFUZZ) +do + xterm -e \ + "afl-fuzz -i ./tools/afl/$1_testcases -o ./fuzz_out/$1 -S Fuzz$1_$N -- ./build/janet ./tools/afl/$1_runner.janet @@" & + children="$! $children" +done + +echo "waiting for child terminals to exit." +wait diff --git a/tools/afl/parser_runner.janet b/tools/afl/parser_runner.janet new file mode 100644 index 00000000..f55d320f --- /dev/null +++ b/tools/afl/parser_runner.janet @@ -0,0 +1,4 @@ +(def p (parser/new)) +(parser/consume p (slurp ((dyn :args) 1))) +(while (parser/has-more p) + (pp (parser/produce p))) diff --git a/tools/afl/parser_testcases/simple.janet b/tools/afl/parser_testcases/simple.janet new file mode 100644 index 00000000..d4a7e7e0 --- /dev/null +++ b/tools/afl/parser_testcases/simple.janet @@ -0,0 +1,15 @@ +0 +123.653 +true +:true +{} +` + hello +` +|() +,() +@{:hello "world"} +@[1 "hello"] +nil +(foo 2 3) +([{} @{:k ([""])}]) \ No newline at end of file diff --git a/tools/afl/prepare_to_fuzz.sh b/tools/afl/prepare_to_fuzz.sh new file mode 100644 index 00000000..3eab7259 --- /dev/null +++ b/tools/afl/prepare_to_fuzz.sh @@ -0,0 +1,6 @@ +set -eux + +export CC=afl-clang +make clean +make -j $(nproc) all +mkdir -p "./fuzz_out"