Fuzz testing is a useful technique to detect bugs in unexpected input that may cause errors when processing.
This document aggregates previous notes. While it's not intended to be an exhaustive set of instructions for all cases, it documents what can and has been done with the fuzzing harnesses so far.
AFL provides afl-system-config
, this is the short of it. Some options more strictly required.
- AFL-specific: Fuzzer uses coredumps directly to detect crashes, provide these:
sudo sysctl kernel.core_pattern=core
sudo sysctl kernel.core_uses_pid=0
- Generally applicable: Performance improvements, such as changing the CPU governor:
- If
tlp
is used,sudo tlp ac
will work.
- If
- Miscellaneous performance optimisation:
sudo sysctl kernel.sched_child_runs_first=1
- libFuzzer-specific: Fuzzer's sanitisers attempt ptrace attach, permit this:
sudo sysctl kernel.yama.ptrace_scope=0
- Generally applicable: Performance improvements, such as changing the CPU governor:
- If
tlp
is used,sudo tlp ac
will work
- If
- For "runtime/dpe" and "x509", a seed corpus has been generated from the defaults/tests in
../common_corpus/
- AFL requires a corpus, libFuzzer does not, it's optional. To generate for "image/verify/afl/", I've been running:
for x in $(seq 001 016); do cargo run -j16 --manifest-path=builder/Cargo.toml --release --bin image -- --rom elf2rom_built.rom --fw caliptra-builder_built_fw.bundle; mv caliptra-builder_built_fw.bundle image/verify/afl/corpus/${x}; rm elf2rom_built.rom; cargo clean; done
For libFuzzer, run fuzzing with [new_corpus old_corpus]
and the -merge=1
parameter
For AFL, TODO
Ensure you are in a fuzzing directory!
- Cleanup: Review the output of
git clean -n -d -x
- Then
git clean -f -d -x
- Make directories as required:
mkdir -p corpus/fuzz_target artifacts/fuzz_target_{1,updatereset}
is general enough
- Then
Status: ~/.local/share/afl.rs/rustc-1.70.0-nightly-84dd17b/afl.rs-0.13.3/afl/bin/afl-whatsup artifacts/fuzz_target_1
Only one corpus can be specified, so if a ../common_corpus/
is available for the target, first cp ../common_corpus/* corpus/
Initialise base options:
export CARGO_AFL_BUILD_STANDARD="cargo +nightly-2023-04-15 afl build" && \
export CARGO_AFL_RUN_A_STANDARD="cargo +nightly-2023-04-15 afl fuzz -i corpus -o artifacts/fuzz_target_1 -G [target-specific] -p fast -L 1 -l 2ATR"
-G
:- image/verify/:
23692
seems stable now - runtime/dpe/dpe/:
64
seems okay
- image/verify/:
-L
: Apparently the acceptable default
Workers (TODO: Further parallelisation):
- Standard:
$CARGO_AFL_BUILD_STANDARD && \
cp target/debug/fuzz_target_1 target/debug/fuzz_target_1_standard; \
$CARGO_AFL_RUN_A_STANDARD -M node01 target/debug/fuzz_target_1_standard
- CmpLog:
AFL_LLVM_CMPLOG=1 $CARGO_AFL_BUILD_STANDARD && \
cp target/debug/fuzz_target_1 target/debug/fuzz_target_1_cmplog; \
$CARGO_AFL_RUN_A_STANDARD -c target/debug/fuzz_target_1_cmplog -S node02 target/debug/fuzz_target_1_standard
Coverage: Also afl-plot
?
~/.local/share/afl.rs/rustc-1.70.0-nightly-84dd17b/afl.rs-0.13.3/afl/bin/afl-showmap -C -i artifacts/fuzz_target_1/ -o coverage -- target/debug/fuzz_target_1_standard
Run: cargo +nightly-2023-04-15 fuzz run fuzz_target_1 [corpuses] -- -max_len=[target-specific] -jobs=8
- Optionally, one sanitiser may be specified: Prepend one of
-s [address|leak|memory]
- "thread" is presumed irrelevant. corpuses
for runtime/dpe/dpe/: Specify bothcorpus/fuzz_target_1 ../common_corpus/
-max_len
:- image/verify/:
23692
seems stable now - runtime/dpe/dpe/:
64
seems okay
- image/verify/:
Coverage: cargo +nightly-2023-04-15 fuzz coverage fuzz_target_1 [corpuses] -- -max_len=[target-specific]
- Same arguments as before. Note that
run
->coverage
, and. It seems that might race?-jobs=8
Visualisation: ~/.rustup/toolchains/nightly-2023-04-15-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show target/x86_64-unknown-linux-gnu/coverage/x86_64-unknown-linux-gnu/release/fuzz_target_1 --format=html -instr-profile=coverage/fuzz_target_1/coverage.profdata > index.html