xref: /openbmc/libmctp/docs/fuzzing.md (revision 056a6ae95168abc9ac079ed61a0be5343093fadd)
1# Fuzzing libmctp
2
3## Build
4
5From the top level libmctp directory, run `./tests/fuzz/fuzz-build.py`. That
6will produce several build variants required for different fuzz engines/stages.
7
8## Honggfuzz
9
10[Honggfuzz](https://github.com/google/honggfuzz) handles running across multiple
11threads itself with a single corpus directory, which is easy to work with. It
12needs to be built from source.
13
14Run with
15
16```shell
17nice honggfuzz -T -i corpusdir --linux_perf_branch -- ./bhf/tests/fuzz/i2c-fuzz
18```
19
20The `--linux_perf_branch` switch is optional, it requires permissions for perf
21counters:
22
23```shell
24echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid
25```
26
27Optionally a thread count can be given, 24 threads on a 12 core system seems to
28give best utilisation (`--threads 24`).
29
30The corpus directory can be reused between runs with different fuzzers.
31
32## AFL++
33
34Running a single instance (just for testing):
35
36```shell
37afl-fuzz -i fuzzrun/hf11/ -o fuzzrun/out12single ./bfuzz/tests/fuzz/i2c-fuzz
38```
39
40AFL++ requires a separate TUI instantiation for each CPU thread. The helper
41[AFL Runner](https://github.com/0xricksanchez/afl_runner) makes that easier.
42
43Running with 20 threads:
44
45```shell
46nice aflr run  -t bfuzz/tests/fuzz/i2c-fuzz -i workdir/out5/m_i2c-fuzz/queue -o workdir/out6 -c bcmplog/tests/fuzz/i2c-fuzz -s bfuzzasan/tests/fuzz/i2c-fuzz -n 20  --session-name fuzz
47```
48
49Kill it with `aflr kill fuzz`.
50
51`aflr tui workdir/out6` could be used to view progress, though its calculations
52may be inaccurate if some runners are idle. Another option is
53`afl-whatsup workdir/out6`.
54
55## Coverage
56
57The coverage provided by a corpus directory can be reported using
58`tests/fuzz/fuzz-coverage.py`.
59
60It will:
61
62- Run a binary compiled with `--coverage` against each corpus file
63- Use [grcov](https://github.com/mozilla/grcov) to aggregate the coverage traces
64  (much faster than lcov).
65- Use `genhtml` to create a report
66
67Typical usage, with corpus in `fuzzrun/corpus`:
68
69```shell
70./tests/fuzz/fuzz-coverage.py fuzzrun/corpus bnoopt/tests/fuzz/i2c-fuzz . bnoopt/ coverage-output
71```
72
73## Reproducing crashes
74
75When the fuzz run encounters a crash, the testcase can be run against the built
76target manually, and stepped through with GDB etc.
77
78```shell
79./bnoopt/tests/fuzz/i2c-fuzz < crashing.bin
80```
81