-
Notifications
You must be signed in to change notification settings - Fork 906
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
doc: add a document about our fuzz testing integration
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
- Loading branch information
Showing
1 changed file
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Fuzz testing | ||
|
||
C-lightning currently supports coverage-guided fuzz testing using [LLVM's libfuzzer](https://www.llvm.org/docs/LibFuzzer.html) | ||
when built with `clang`. | ||
|
||
The goal of fuzzing is to generate mutated -and often unexpected- inputs (`seed`s) to pass | ||
to (parts of) a program (`target`) in order to make sure the codepaths used: | ||
- do not crash | ||
- are valid (if combined with sanitizers) | ||
The generated seeds can be stored and form a `corpus`, which we try to optimise (don't | ||
store two seeds that lead to the same codepath). | ||
|
||
For more info about fuzzing see [here](https://github.com/google/fuzzing/tree/master/docs), | ||
and for more about `libfuzzer` in particular see [here](https://www.llvm.org/docs/LibFuzzer.html). | ||
|
||
|
||
## Build the fuzz targets | ||
|
||
In order to build the C-lightning binaries with code coverage you will need a recent | ||
[clang](http://clang.llvm.org/). The more recent the compiler version the better. | ||
|
||
Then you'll need to enable support at configuration time. You likely want to enable | ||
a few sanitizers for bug detections as well as experimental features for an extended | ||
coverage (not required though). | ||
|
||
``` | ||
DEVELOPER=1 EXPERIMENTAL_FEATURES=1 ASAN=1 UBSAN=1 VALGRIND=0 FUZZING=1 CC=clang ./configure && make | ||
``` | ||
|
||
The targets will be built in `tests/fuzz/` as `fuzz-` binaries. | ||
|
||
|
||
## Run one or more target(s) | ||
|
||
You can run each target independently. Pass `-help=1` to see available options, for | ||
example: | ||
``` | ||
./tests/fuzz/fuzz-addr -help=1 | ||
``` | ||
|
||
Otherwise, you can use the Python runner to either run the targets against a given seed | ||
corpus: | ||
``` | ||
./tests/fuzz/run.py fuzz_corpus -j2 | ||
``` | ||
Or extend this corpus: | ||
``` | ||
./tests/fuzz/run.py fuzz_corpus -j2 --generate --runs 12345 | ||
``` | ||
|
||
The latter will run all targets two by two `12345` times. | ||
|
||
If you want to contribute new seeds, be sure to merge your corpus with the main one: | ||
``` | ||
./tests/fuzz/run.py my_locally_extended_fuzz_corpus -j2 --generate --runs 12345 | ||
./tests/fuzz/run.py main_fuzz_corpus --merge_dir my_locally_extended_fuzz_corpus | ||
``` | ||
|
||
|
||
## Write new fuzzing targets | ||
|
||
In order to write a new target: | ||
- include the `libfuzz.h` header | ||
- fill two functions: `init()` for static stuff and `run()` which will be called | ||
repeatedly with mutated data. | ||
- read about [what makes a good fuzz target](https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md). | ||
|
||
A simple example is [`fuzz-addr`](tests/fuzz/fuzz-addr.c). It setups the chainparams and | ||
context (wally, tmpctx, ..) in `init()` then bruteforces the bech32 encoder in `run()`. |