diff options
Diffstat (limited to 'json/fuzz/README.md')
| -rw-r--r-- | json/fuzz/README.md | 83 |
1 files changed, 30 insertions, 53 deletions
diff --git a/json/fuzz/README.md b/json/fuzz/README.md index b4d7fd1..7fd0107 100644 --- a/json/fuzz/README.md +++ b/json/fuzz/README.md @@ -1,82 +1,59 @@ # JSON syntax fuzzing utilities -This directory contains helper functions and corpuses that can be used to -fuzz-test the HCL JSON parser using [go-fuzz](https://github.com/dvyukov/go-fuzz). +This directory contains helper functions and corpora that can be used to +fuzz-test the HCL JSON parser using Go's native fuzz testing capabilities. -## Work directory +Please see https://go.dev/doc/fuzz/ for more information on fuzzing. -`go-fuzz` needs a working directory where it can keep state as it works. This -should ideally be in a ramdisk for efficiency, and should probably _not_ be on -an SSD to avoid thrashing it. Here's how to create a ramdisk: +## Prerequisites +* Go 1.18 -### macOS - -``` -$ SIZE_IN_MB=1024 -$ DEVICE=`hdiutil attach -nobrowse -nomount ram://$(($SIZE_IN_MB*2048))` -$ diskutil erasevolume HFS+ RamDisk $DEVICE -$ export RAMDISK=/Volumes/RamDisk -``` +## Running the fuzzer -### Linux +Each exported function in the `json` package has a corresponding fuzz test. +These can be run one at a time via `go test`: ``` -$ mkdir /mnt/ramdisk -$ mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk -$ export RAMDISK=/mnt/ramdisk +$ cd fuzz +$ go test -fuzz FuzzParse ``` -## Running the fuzzer +This command will exit only when a crasher is found (see "Understanding the +result" below). + +## Seed corpus -Next, install `go-fuzz` and its build tool in your `GOPATH`: +The seed corpus for each fuzz test function is stored in the corresponding +directory under `json/fuzz/testdata/fuzz`. For example: ``` -$ make tools FUZZ_WORK_DIR=$RAMDISK +$ ls json/fuzz/testdata/fuzz/FuzzParse +attr-expr.hcl.json +attr-literal.hcl.json +block-attrs.hcl.json +... ``` -Now you can fuzz the parser: +Additional seed inputs can be added to this corpus. Each file must be in the Go 1.18 corpus file format. Files can be converted to this format using the `file2fuzz` tool. To install it: ``` -$ make fuzz-config FUZZ_WORK_DIR=$RAMDISK/json-fuzz-config +$ go install golang.org/x/tools/cmd/file2fuzz@latest +$ file2fuzz -help ``` -~> Note: `go-fuzz` does not interact well with `goenv`. If you encounter build -errors where the package `go.fuzz.main` could not be found, you may need to use -a machine with a direct installation of Go. - ## Understanding the result A small number of subdirectories will be created in the work directory. If you let `go-fuzz` run for a few minutes (the more minutes the better) it -may detect "crashers", which are inputs that caused the parser to panic. Details -about these are written to `$FUZZ_WORK_DIR/crashers`: +may detect "crashers", which are inputs that caused the parser to panic. +These are written to `json/fuzz/testdata/fuzz/<fuzz test name>/`: ``` -$ ls /tmp/hcl2-fuzz-config/crashers -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.output -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.quoted +$ ls json/fuzz/testdata/fuzz/FuzzParseTemplate +582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 ``` -The base file above (with no extension) is the input that caused a crash. The -`.output` file contains the panic stack trace, which you can use as a clue to -figure out what caused the crash. - A good first step to fixing a detected crasher is to copy the failing input -into one of the unit tests in the `hcl/json` package and see it crash there -too. After that, it's easy to re-run the test as you try to fix it. The -file with the `.quoted` extension contains a form of the input that is quoted -in Go syntax for easy copy-paste into a test case, even if the input contains -non-printable characters or other inconvenient symbols. - -## Rebuilding for new Upstream Code - -An archive file is created for `go-fuzz` to use on the first run of each -of the above, as a `.zip` file created in this directory. If upstream code -is changed these will need to be deleted to cause them to be rebuilt with -the latest code: - -``` -$ make clean -``` +into one of the unit tests in the `json` package and see it crash there +too. After that, it's easy to re-run the test as you try to fix it. |
