lnd/docs/fuzz.md
2020-03-03 13:58:07 -05:00

2.5 KiB

Fuzzing LND

The fuzz package is organized into subpackages which are named after the lnd package they test. Each subpackage has its own set of fuzz targets.

Setup and Installation

This section will cover setup and installation of go-fuzz and fuzzing binaries.

  • First, we must get go-fuzz.
$ go get -u github.com/dvyukov/go-fuzz/...
  • The following is a command to build all fuzzing harnesses for a specific package.
$ cd fuzz/<package>
$ find * -maxdepth 1 -regex '[A-Za-z0-9\-_.]'* -not -name fuzz_utils.go | sed 's/\.go$//1' | xargs -I % sh -c 'go-fuzz-build -func Fuzz_% -o <package>-%-fuzz.zip github.com/lightningnetwork/lnd/fuzz/<package>'
  • This may take a while since this will create zip files associated with each fuzzing target.

  • Now, run go-fuzz with workdir set as below!

$ go-fuzz -bin=<.zip archive here> -workdir=<harness> -procs=<num workers>

go-fuzz will print out log lines every couple of seconds. Example output:

2017/09/19 17:44:23 workers: 8, corpus: 23 (3s ago), crashers: 1, restarts: 1/748, execs: 400690 (16694/sec), cover: 394, uptime: 24s

Corpus is the number of items in the corpus. go-fuzz may add valid inputs to the corpus in an attempt to gain more coverage. Crashers is the number of inputs resulting in a crash. The inputs, and their outputs are logged in: fuzz/<package>/<harness>/crashers. go-fuzz also creates a suppressions directory of stacktraces to ignore so that it doesn't create duplicate stacktraces. Cover is a number representing edge coverage of the program being fuzzed.

Brontide

The brontide fuzzers need to be run with a -timeout flag of 20 seconds or greater since there is a lot of machine state that must be printed on panic.

Corpus

Fuzzing generally works best with a corpus that is of minimal size while achieving the maximum coverage. However, go-fuzz automatically minimizes the corpus in-memory before fuzzing so a large corpus shouldn't make a difference - edge coverage is all that really matters.

Test Harness

If you take a look at the test harnesses that are used, you will see that they all consist of one function:

func Fuzz(data []byte) int

If:

  • -1 is returned, the fuzzing input is ignored
  • 0 is returned, go-fuzz will add the input to the corpus and deprioritize it in future mutations.
  • 1 is returned, go-fuzz will add the input to the corpus and prioritize it in future mutations.

Conclusion

Citizens, do your part and go-fuzz lnd today!