Golang Fuzzing: A go-fuzz Tutorial and Example

Golang Fuzz Testing Tutorial and Example
go fuzzing


Golang fuzzing is a useful testing technique that provides invalid, unexpected, or random data as inputs to test for crashes. Its primary used for hardening programs that process untrusted input data.

The go-fuzz package uses logic that is based on american fuzzy lop (AFL) which allows you to quickly automate randomized testing. This article will act as a tutorial to identify and fix an example bug.

Overview

Prep Sample Environment
  1. Create package directory:
    mkdir $GOPATH/src/mypackage
  2. Create package source code file:
    touch $GOPATH/src/mypackage/mypackage.go
  3. Add code to the package file:
    vi $GOPATH/src/mypackage/mypackage.go

Integrate Fuzzing
  1. Go get the following packages:
    go get github.com/dvyukov/go-fuzz/go-fuzz
    go get github.com/dvyukov/go-fuzz/go-fuzz-build
    go get -d github.com/dvyukov/go-fuzz-corpus
  2. Create fuzzing Go file:
    touch $GOPATH/src/mypackage/mypackage_fuzz.go
  3. Add code to the fuzzing Go file:
  4. Create fuzzing zip file:
    cd $GOPATH/src && $GOPATH/bin/go-fuzz-build mypackage
  5. Create corpus file (or copy seed files from go-fuzz-corpus):
    echo testing1, testing2, testing3 > $GOPATH/src/mypackage/corpus/mycorpus
  6. Run the fuzzer against the corpus:
    $GOPATH/bin/go-fuzz -bin=./mypackage-fuzz.zip -workdir=mypackage
  7. After running the fuzzer for several seconds, you’ll see the crashers number increment from 0 to 1. At this time you can review the files to understand what caused the crash.

Review Crashers
  1. List crasher files:
    ls -l $GOPATH/src/mypackage/crashers | awk '{ print $9 }'
  2. After reviewing the .output file, you’ll see the error “panic: runtime error: index out of range”. Also the .quoted file highlights the input that caused the crash, "testing3".

Fix Crasher
    1. Now that we’ve identified that the "testing3" string has resulted in our “index out of range” crash, we can add this to a unit test file to replicate it and fix the cause of the crash.
    2. Create the unit test file:
      touch $GOPATH/src/mypackage/mypackage_test.go
    3. Run the test file:
      go test -v $GOPATH/src/mypackage/*.go
    4. You’ll notice that the test crashes using testing3, perfect.
    5. Now, implement the fix to our package and run the test again to ensure that is passes. We’ll add && (strI < len(strs)-1) to ensure that the package isn’t accessing the last list member that results in the crash.
  1. Run the test file again:
    go test -v $GOPATH/src/mypackage/*.go
  2. Now we’ve fixed the issue and have a unit test in place to ensure it doesn’t come back, were good to go.

See also:
Go Column Print Format
Golang Lint: Install Golint and Usage
Golang Command Line Flags: Input Arguments
Golang SSH Client: Crypto & Goexpect Examples
Go IP Address Manipulation: Parse CIDR & Net IP
Golang Regular Expression Match: Regexp Syntax Tutorial