mirror of
https://git.netfilter.org/nftables
synced 2026-01-26 02:27:52 +00:00
This means some loss of functionality since you can no longer combine --fuzzer with options like --debug, --define, --include. On the upside, this adds new --random-outflags mode which will randomly switch --terse, --numeric, --echo ... on/off. Update README to reflect this change. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
121 lines
4.0 KiB
Plaintext
121 lines
4.0 KiB
Plaintext
First you need to install afl++. If your distro doesn't package it, you can
|
|
get it from https://github.com/AFLplusplus/AFLplusplus
|
|
|
|
Next build and install afl++, this needs llvm/clang installed.
|
|
|
|
Nftables configue + compile steps:
|
|
|
|
To get the best results, build nftables with the following options:
|
|
|
|
CC=afl-clang-lto LD=afl-clang-lto CFLAGS+=-fsanitize=address ./configure \
|
|
--disable-shared --with-json --without-xtables \
|
|
--with-cli=readline --enable-fuzzer --disable-man-doc
|
|
|
|
[ you might want to enable xtables or use a different cli, your choice ].
|
|
|
|
Important options are:
|
|
--disable-shared, so that libnftables is instrumented too.
|
|
--enable-fuzzer
|
|
|
|
--enable-fuzzer provides tools/nft-afl that allows more fine-grained control
|
|
nft-afl provides a few options to guide the fuzzing process, some are shared
|
|
with nft binary:
|
|
|
|
--check
|
|
|
|
Prevents the fuzzer-generated rulesets from being committed to the kernel.
|
|
|
|
--random-outflags
|
|
|
|
Periodically alter output behaviour by enabling or disabling --terse,
|
|
--numeric, --echo and so on.
|
|
|
|
--json
|
|
|
|
Format output in JSON
|
|
|
|
--fuzzer <stage>
|
|
|
|
Instruct nft-afl to stop fuzzing after reaching the given stage. Stages are:
|
|
|
|
1: 'parser':
|
|
Only run / exercise the flex/bison parser.
|
|
|
|
2: 'eval': stop after the evaluation phase.
|
|
This attempts to build a complete ruleset in memory, does
|
|
symbol resolution, adds needed shift/masks to payload instructions
|
|
etc.
|
|
|
|
3: 'netlink-ro':
|
|
Also build/serialize the ruleset into netlink-commands to send to the
|
|
kernel, but omit the final write so the kernel will not see the message.
|
|
This is the default mode.
|
|
|
|
4: 'netlink-rw':
|
|
Same as 3 but the message will be sent to the kernel.
|
|
You can combine this option with the '--check' option to send data to the
|
|
kernel but without committing any changes.
|
|
Unlike 3), even when combined with '--check', this option can still trigger
|
|
a kernel crash if there are bugs in the kernel, e.g. during the
|
|
valiation / transaction / abort stages.
|
|
When using this without '--check', remember to lauch nft in its own network
|
|
namespace to prevent VM connectivity loss due to committed 'drop' rules.
|
|
|
|
Use 'netlink-ro' if you want to prevent nft from ever submitting any
|
|
changes to the kernel or if you are only interested in fuzzing nftables
|
|
and its libraries.
|
|
|
|
All --fuzzer modes EXCEPT 'netlink-rw' do imply --check as these modes never
|
|
alter state in the kernel.
|
|
|
|
Before each input, nft-afl checks the kernel "taint" status as provided
|
|
by "/proc/sys/kernel/tainted". If this is non-zero, fuzzing stops.
|
|
|
|
To run libnftables under afl++, run nft-afl like this:
|
|
|
|
unshare -n \
|
|
afl-fuzz -g 16 -G 2000 -t 5000 -i tests/afl++/in -o tests/afl++/out \
|
|
-- tools/nft-afl
|
|
|
|
arg should be either "netlink-ro" (if you only want to exercise libnftables
|
|
userspace) or "netlink-rw" (if you want to test kernel code paths too).
|
|
|
|
Its also a good idea to do this from tmux/screen so you can disconnect/reattach
|
|
later. You can also spawn multiple instances.
|
|
In that case, add the '-M' option to afl-fuzz for the first instance you start,
|
|
and '-S' for subsequent secondary instances.
|
|
|
|
This expects a unique directory name as argument, so interesting findings
|
|
from the different instances are cleary separated.
|
|
|
|
With above default options, outputs will be in 'tests/afl++/out/<variantname>'.
|
|
Please see the afl++ docs for more information about this.
|
|
|
|
You can use tests/afl++/run-afl.sh script to autogenerate an initial set of valid
|
|
inputs that the fuzzer can start from.
|
|
|
|
Use
|
|
|
|
sysctl -f tests/afl++/afl-sysctl.conf
|
|
|
|
to enable some fuzzer-beneficial sysctl options.
|
|
|
|
Kernel config:
|
|
When using the 'netlink-rw' option it is best to also use a debug kernel
|
|
with at least:
|
|
|
|
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
|
|
CONFIG_KASAN=y
|
|
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
|
CONFIG_DEBUG_LOCKDEP=y
|
|
CONFIG_FAULT_INJECTION=y
|
|
CONFIG_FAILSLAB=y
|
|
CONFIG_DEBUG_KMEMLEAK=y
|
|
|
|
If you want to sample test coverage, then set
|
|
CONFIG_GCOV_KERNEL=y
|
|
|
|
echo GCOV_PROFILE := y > net/netfilter/Makefile
|
|
|
|
or enable CONFIG_GCOV_PROFILE_ALL=y.
|