From 24468bead67b6a4108e312bc6c65a0a6857bad86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Fri, 17 Jan 2020 17:01:31 +0100 Subject: [PATCH] fuzzing: Initialize This adds a new subdirectory called `fuzzing/` which will contain applications for fuzzing various RIOT network modules in the future. This subdirectory is heavily inspired by the `examples/` subdirectory. The fuzzing applications use AFL as a fuzzer. Each application contains Makefiles, source code, and an input corpus used by AFL to generate input for fuzzing. --- .gitignore | 2 ++ Makefile.include | 5 +++++ dist/tools/fuzzing/afl.sh | 10 ++++++++++ fuzzing/Makefile.fuzzing_common | 21 ++++++++++++++++++++ fuzzing/README.md | 35 +++++++++++++++++++++++++++++++++ makefiles/vars.inc.mk | 2 ++ 6 files changed, 75 insertions(+) create mode 100755 dist/tools/fuzzing/afl.sh create mode 100644 fuzzing/Makefile.fuzzing_common create mode 100644 fuzzing/README.md diff --git a/.gitignore b/.gitignore index b6ed83c55..915686f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ doc/doxygen/*.tmp *bin # Build directory /build +# AFL findings +fuzzing/**/findings/ # Backup files *~ *.orig diff --git a/Makefile.include b/Makefile.include index 2aa7c7647..8f0e05035 100644 --- a/Makefile.include +++ b/Makefile.include @@ -747,6 +747,11 @@ test-input-hash: true endif +.PHONY: fuzz +fuzz: + env FLASHFILE="$(FLASHFILE)" PORT="$(PORT)" TERMFLAGS="$(TERMFLAGS)" \ + "$(RIOTBASE)"/dist/tools/fuzzing/afl.sh $(AFL_FLAGS) + # Default OBJDUMPFLAGS for platforms which do not specify it: OBJDUMPFLAGS ?= -S -D -h diff --git a/dist/tools/fuzzing/afl.sh b/dist/tools/fuzzing/afl.sh new file mode 100755 index 000000000..d0bb7bf6c --- /dev/null +++ b/dist/tools/fuzzing/afl.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ ! -d "${APPDIR}/input" ]; then + echo "${APPDIR}: Doesn't provide a test corpus" 1>&2 + exit 1 +fi + +mkdir -p "${APPDIR}/findings" +exec afl-fuzz -m 800 -i "${APPDIR}/input" -o "${APPDIR}/findings" "$@" -- \ + "${FLASHFILE}" "${PORT}" ${TERMFLAGS} diff --git a/fuzzing/Makefile.fuzzing_common b/fuzzing/Makefile.fuzzing_common new file mode 100644 index 000000000..8766f575f --- /dev/null +++ b/fuzzing/Makefile.fuzzing_common @@ -0,0 +1,21 @@ +RIOTBASE ?= $(CURDIR)/../.. + +# Instrumend code with AFL by default +TOOLCHAIN ?= afl + +# Automatically set application to a sensible default +APPLICATION ?= fuzzing_$(notdir $(patsubst %/,%,$(CURDIR))) + +# Fuzzing is only supported on native +BOARD ?= native +FEATURES_REQUIRED += arch_native + +CFLAGS += -ggdb # Make ASAN output more useful error messages +CFLAGS += -D_FORTIFY_SOURCE=2 # Compiler hardening + +# Various utilitiy modules +USEMODULE += fuzzing +USEMODULE += ssp + +# Enable DEVELHELP by default +DEVELHELP ?= 1 diff --git a/fuzzing/README.md b/fuzzing/README.md new file mode 100644 index 000000000..baad60f05 --- /dev/null +++ b/fuzzing/README.md @@ -0,0 +1,35 @@ +# Fuzzing + +Automated fuzzing tests for RIOT network applications. + +## Setup + +The following additional dependencies are required: + +* [afl][afl homepage] +* [libasan][sanitizers github] (optional but recommended) + +## Invocation + +Before fuzzing an application it needs to be compiled, to ease detection +of unwanted behaviour (e.g. out-of-bounds buffer accesses), compiling +with `all-asan` is highly recommended. For example: + + make -C fuzzing/ all-asan + +Afterwards invoke afl using: + + make -C fuzzing/ fuzz + +### Parallel Fuzzing + +Parallel fuzzing is supported through `AFL_FLAGS`, e.g.: + + # Start first AFL instance + AFL_FLAGS="-M fuzzer01" make -C fuzzing/gnrc_tcp/ fuzz + + # Start second AFL instance in a different terminal + AFL_FLAGS="-M fuzzer02" make -C fuzzing/gnrc_tcp/ fuzz + +[sanitizers github]: https://github.com/google/sanitizers +[afl homepage]: http://lcamtuf.coredump.cx/afl/ diff --git a/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index c96c62645..16b6a7e72 100644 --- a/makefiles/vars.inc.mk +++ b/makefiles/vars.inc.mk @@ -106,4 +106,6 @@ export UNZIP_HERE # Use `cd $(SOME_FOLDER) && $(UNZIP_HERE) $(SOME_FI export LAZYSPONGE # Command saving stdin to a file only on content update. export LAZYSPONGE_FLAGS # Parameters supplied to LAZYSPONGE. +export AFL_FLAGS # Additional command-line flags passed to afl during fuzzing. + # LOG_LEVEL # Logging level as integer (NONE: 0, ERROR: 1, WARNING: 2, INFO: 3, DEBUG: 4, default: 3)