Fuzzing
We use fuzzing to test the various entrypoints to the library. The fuzzer we use is AFL++. All files related to fuzzing live within the fuzz directory, which has the following structure:
fuzz βββ corpus βΒ Β βββ parse fuzzing corpus for parsing (a symlink to our fixtures) βΒ Β βββ regexp fuzzing corpus for regexp βββ dict a AFL++ dictionary containing various tokens βββ docker βΒ Β βββ Dockerfile for building a container with the fuzzer toolchain βββ fuzz.c generic entrypoint for fuzzing βββ heisenbug.c entrypoint for reproducing a crash or hang βββ parse.c fuzz handler for parsing βββ parse.sh script to run parsing fuzzer βββ regexp.c fuzz handler for regular expression parsing βββ regexp.sh script to run regexp fuzzer βββ tools Β Β βββ backtrace.sh generates backtrace files for a crash directory Β Β βββ minimize.sh generates minimized crash or hang files
Usage
There are currently three fuzzing targets
-
pm_serialize_parse(parse) -
pm_regexp_parse(regexp)
Respectively, fuzzing can be performed with
make fuzz-run-parse make fuzz-run-regexp
To end a fuzzing job, interrupt with CTRL+C. To enter a container with the fuzzing toolchain and debug utilities, run
make fuzz-debug
Out-of-bounds reads
Currently, encoding functionality implementing the pm_encoding_t interface can read outside of inputs. For the time being, ASAN instrumentation is disabled for functions from src/enc. See fuzz/asan.ignore.
To disable ASAN read instrumentation globally, use the FUZZ_FLAGS environment variable e.g.
FUZZ_FLAGS="-mllvm -asan-instrument-reads=false" make fuzz-run-parse
Note, that this may make reproducing bugs difficult as they may depend on memory outside of the input buffer. In that case, try
make fuzz-debug # enter the docker container with build tools make build/fuzz.heisenbug.parse # or .regexp ./build/fuzz.heisenbug.parse path-to-problem-input
Triaging Crashes and Hangs
Triaging crashes and hangs is easier when the inputs are as short as possible. In the fuzz container, an entire crash or hang directory can be minimized using
./fuzz/tools/minimize.sh <directory>
e.g.
./fuzz/tools/minimize.sh fuzz/output/parse/default/crashes
This may take a long time. In the crash/hang directory, for each input file there will appear a minimized version with the extension .min appended.
Backtraces for crashes (not hangs) can be generated en masse with
./fuzz/tools/backtrace.sh <directory>
Files with basename equal to the input file name with extension .bt will be created e.g.
id:000000,sig:06,src:000006+000190,time:8480,execs:18929,op:splice,rep:4 id:000000,sig:06,src:000006+000190,time:8480,execs:18929,op:splice,rep:4.bt