make+scripts+docs: update fuzzing script and make fuzz

This commit is contained in:
Conner authored and Matt Morehouse committed 2022-11-11 10:30:05 -06:00
1 parent 404e18afab
commit 25a7bb8b86
4 files changed
+39 -109

No files matched your search

+2 -10
View File
@@ -6,17 +6,12 @@ TOOLS_DIR := tools
BTCD_PKG := github.com/btcsuite/btcd BTCD_PKG := github.com/btcsuite/btcd
GOACC_PKG := github.com/ory/go-acc GOACC_PKG := github.com/ory/go-acc
GOIMPORTS_PKG := github.com/rinchsan/gosimports/cmd/gosimports GOIMPORTS_PKG := github.com/rinchsan/gosimports/cmd/gosimports
GOFUZZ_BUILD_PKG := github.com/dvyukov/go-fuzz/go-fuzz-build
GOFUZZ_PKG := github.com/dvyukov/go-fuzz/go-fuzz
GOFUZZ_DEP_PKG := github.com/dvyukov/go-fuzz/go-fuzz-dep
GO_BIN := ${GOPATH}/bin GO_BIN := ${GOPATH}/bin
BTCD_BIN := $(GO_BIN)/btcd BTCD_BIN := $(GO_BIN)/btcd
GOIMPORTS_BIN := $(GO_BIN)/gosimports GOIMPORTS_BIN := $(GO_BIN)/gosimports
GOMOBILE_BIN := GO111MODULE=off $(GO_BIN)/gomobile GOMOBILE_BIN := GO111MODULE=off $(GO_BIN)/gomobile
GOACC_BIN := $(GO_BIN)/go-acc GOACC_BIN := $(GO_BIN)/go-acc
GOFUZZ_BUILD_BIN := $(GO_BIN)/go-fuzz-build
GOFUZZ_BIN := $(GO_BIN)/go-fuzz
MOBILE_BUILD_DIR :=${GOPATH}/src/$(MOBILE_PKG)/build MOBILE_BUILD_DIR :=${GOPATH}/src/$(MOBILE_PKG)/build
IOS_BUILD_DIR := $(MOBILE_BUILD_DIR)/ios IOS_BUILD_DIR := $(MOBILE_BUILD_DIR)/ios
@@ -232,13 +227,10 @@ flakehunter-parallel:
# ============= # =============
# FUZZING # FUZZING
# ============= # =============
fuzz-build: $(GOFUZZ_BUILD_BIN) $(GOFUZZ_DEP_BIN)
@$(call print, "Creating fuzz harnesses for packages '$(FUZZPKG)'.")
scripts/fuzz.sh build "$(FUZZPKG)"
fuzz-run: $(GOFUZZ_BIN) fuzz: $(GOFUZZ_BIN)
@$(call print, "Fuzzing packages '$(FUZZPKG)'.") @$(call print, "Fuzzing packages '$(FUZZPKG)'.")
scripts/fuzz.sh run "$(FUZZPKG)" "$(FUZZ_TEST_RUN_TIME)" "$(FUZZ_TEST_TIMEOUT)" "$(FUZZ_NUM_PROCESSES)" "$(FUZZ_BASE_WORKDIR)" scripts/fuzz.sh run "$(FUZZPKG)" "$(FUZZ_TEST_RUN_TIME)" "$(FUZZ_NUM_PROCESSES)"
# ========= # =========
# UTILITIES # UTILITIES
+25 -28
View File
@@ -1,43 +1,40 @@
# Fuzzing LND # # 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. The following runs all fuzz tests on default settings:
## Setup and Installation ##
This section will cover setup and installation of the fuzzing binaries.
* The following is a command to build all fuzzing harnesses:
```shell ```shell
$ make fuzz-build $ make fuzz
``` ```
The following runs all fuzz tests inside the lnwire package, each for a total of 1 minute, using 4 procs.
* This may take a while since this will create zip files associated with each fuzzing target. It is recommended that processes be set to the number of processor cores in the system:
* The following is a command to run all fuzzing harnesses for 30 seconds:
```shell ```shell
$ make fuzz-run $ make fuzz pkg=lnwire fuzztime=1m parallel=4
```
Alternatively, individual fuzz tests can be ran manually by setting the working directory to the location of the .go file holding the fuzz tests.
The go test command can only test one fuzz test at a time:
```shell
$ cd lnwire
$ go test -fuzz=FuzzAcceptChannel -fuzztime=1m -parallel=4
```
The following can be used to show all fuzz tests in the working directory:
```shell
$ cd lnwire
$ go test -list=Fuzz.*
``` ```
`go-fuzz` will print out log lines every couple of seconds. Example output: Fuzz tests can be ran as normal tests, which only runs the seed corpus:
```text ```shell
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 $ cd lnwire
$ go test -run=FuzzAcceptChannel -parallel=4
``` ```
Corpus is the number of items in the corpus. `go-fuzz` may add valid inputs to The generated corpus values can be found in the $(go env GOCACHE)/fuzz directory.
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 by default 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.
## Options ## ## Options ##
Several parameters can be appended to the end of the make commands to tune the build process or the way the fuzzer runs. Several parameters can be appended to the end of the make commands to tune the build process or the way the fuzzer runs.
- `run_time` specifies how long each fuzz harness runs for. The default is 30 seconds. - `fuzztime` specifies how long each fuzz test runs for, corresponding to the `go test -fuzztime` option. The default is 30s.
- `timeout` specifies how long an individual testcase can run before raising an error. The default is 20 seconds. - `parallel` specifies the number of parallel processes to use while running the harnesses, corresponding to the `go test -parallel` option.
- `processes` specifies the number of parallel processes to use while running the harnesses. - `pkg` specifies the `lnd` packages to build or fuzz. The default is to build and run all available packages (`brontide lnwire watchtower/wtwire zpay32`). This can be changed to build/run against individual packages.
- `pkg` specifies the `lnd` packages to build or fuzz. The default is to build and run all available packages (`brontide lnwire wtwire zpay32`). This can be changed to build/run against individual packages.
- `base_workdir` specifies the workspace of the fuzzer. This folder will contain the corpus, crashers, and suppressions.
## Corpus ## ## Corpus ##
Fuzzing generally works best with a corpus that is of minimal size while achieving the maximum coverage. `go-fuzz` automatically minimizes the corpus in-memory before fuzzing so a large corpus shouldn't make a difference. Fuzzing generally works best with a corpus that is of minimal size while achieving the maximum coverage.
## Disclosure ## ## Disclosure ##
If you find any crashers that affect LND security, please disclose with the information found [here](https://github.com/lightningnetwork/lnd/#security). If you find any crashers that affect LND security, please disclose with the information found [here](https://github.com/lightningnetwork/lnd/#security).
+6 -19
View File
@@ -1,8 +1,6 @@
FUZZPKG = brontide lnwire wtwire zpay32 FUZZPKG = brontide lnwire watchtower/wtwire zpay32
FUZZ_TEST_RUN_TIME = 30 FUZZ_TEST_RUN_TIME = 30s
FUZZ_TEST_TIMEOUT = 20
FUZZ_NUM_PROCESSES = 4 FUZZ_NUM_PROCESSES = 4
FUZZ_BASE_WORKDIR = $(shell pwd)/fuzz
# If specific package is being fuzzed, construct the full name of the # If specific package is being fuzzed, construct the full name of the
# subpackage. # subpackage.
@@ -12,23 +10,12 @@ endif
# The default run time per fuzz test is pretty low and normally will be # The default run time per fuzz test is pretty low and normally will be
# overwritten by a user depending on the time they have available. # overwritten by a user depending on the time they have available.
ifneq ($(run_time),) ifneq ($(fuzztime),)
FUZZ_TEST_RUN_TIME := $(run_time) FUZZ_TEST_RUN_TIME := $(fuzztime)
endif
# If the timeout needs to be increased, overwrite the default value.
ifneq ($(timeout),)
FUZZ_TEST_TIMEOUT := $(timeout)
endif endif
# Overwrites the number of parallel processes. Should be set to the number of # Overwrites the number of parallel processes. Should be set to the number of
# processor cores in a system. # processor cores in a system.
ifneq ($(processes),) ifneq ($(parallel),)
FUZZ_NUM_PROCESSES := $(processes) FUZZ_NUM_PROCESSES := $(parallel)
endif
# Overwrite the base work directory for the fuzz run. Can be used to supply any
# previously generated corpus.
ifneq ($(base_workdir),)
FUZZ_BASE_WORKDIR := $(base_workdir)
endif endif
+6 -52
View File
@@ -2,58 +2,17 @@
set -e set -e
function build_fuzz() {
PACKAGES=$1
for pkg in $PACKAGES; do
pushd fuzz/$pkg
for file in *.go; do
if [[ "$file" == "fuzz_utils.go" ]]; then
continue
fi
NAME=$(echo $file | sed 's/\.go$//1')
echo "Building zip file for $pkg/$NAME"
go-fuzz-build -func "Fuzz_$NAME" -o "$pkg-$NAME-fuzz.zip" "github.com/lightningnetwork/lnd/fuzz/$pkg"
done
popd
done
}
# timeout is a cross platform alternative to the GNU timeout command that
# unfortunately isn't available on macOS by default.
timeout() {
time=$1
$2 &
pid=$!
sleep $time
kill -s SIGINT $pid
}
function run_fuzz() { function run_fuzz() {
PACKAGES=$1 PACKAGES=$1
RUN_TIME=$2 RUN_TIME=$2
TIMEOUT=$3 NUM_WORKERS=$3
PROCS=$4
BASE_WORKDIR=$5
for pkg in $PACKAGES; do for pkg in $PACKAGES; do
pushd fuzz/$pkg pushd $pkg
for file in *.go; do go test -list=Fuzz.* | grep Fuzz | while read line; do
if [[ "$file" == "fuzz_utils.go" ]]; then echo ----- Fuzz testing $pkg:$line for $2 with $3 workers -----
continue go test -fuzz=^$line\$ -fuzztime=$2 -parallel=$3
fi
NAME=$(echo $file | sed 's/\.go$//1')
WORKDIR=$BASE_WORKDIR/$pkg/$NAME
mkdir -p $WORKDIR
echo "Running fuzzer $pkg-$NAME-fuzz.zip with $PROCS processors for $RUN_TIME seconds"
COMMAND="go-fuzz -bin=$pkg-$NAME-fuzz.zip -workdir=$WORKDIR -procs=$PROCS -timeout=$TIMEOUT"
echo "$COMMAND"
timeout "$RUN_TIME" "$COMMAND"
done done
popd popd
@@ -63,8 +22,7 @@ function run_fuzz() {
# usage prints the usage of the whole script. # usage prints the usage of the whole script.
function usage() { function usage() {
echo "Usage: " echo "Usage: "
echo "fuzz.sh build <packages>" echo "fuzz.sh run <packages> <run_time>"
echo "fuzz.sh run <packages> <run_time> <timeout>"
} }
# Extract the sub command and remove it from the list of parameters by shifting # Extract the sub command and remove it from the list of parameters by shifting
@@ -75,10 +33,6 @@ shift
# Call the function corresponding to the specified sub command or print the # Call the function corresponding to the specified sub command or print the
# usage if the sub command was not found. # usage if the sub command was not found.
case $SUBCOMMAND in case $SUBCOMMAND in
build)
echo "Building fuzz packages"
build_fuzz "$@"
;;
run) run)
echo "Running fuzzer" echo "Running fuzzer"
run_fuzz "$@" run_fuzz "$@"