Use this skill to fuzz open source Go software projects.
This skill provides the agent with the knowledge and tools to write, build, and
validate fuzz targets for Go projects integrated into OSS-Fuzz. Go fuzzing uses
the native Go fuzzing framework introduced in Go 1.18, which OSS-Fuzz drives
via libFuzzer under the hood using compile_native_go_fuzzer.
Go projects must use the Go base builder image:
FROM gcr.io/oss-fuzz-base/base-builder-go
Set language: go in project.yaml.
Go fuzz targets are standard Go test functions with the prefix Fuzz, placed
in _test.go files (or plain .go files that import the testing package):
package mypkg
import (
"testing"
_ "github.com/AdamKorcz/go-118-fuzz-build/testing" // required for OSS-Fuzz native fuzzing
)
func FuzzMyTarget(f *testing.F) {
// Seed corpus: add representative valid inputs so the fuzzer starts
// from a meaningful state rather than empty bytes.
f.Add([]byte("example input"))
f.Add([]byte("another seed"))
f.Fuzz(func(t *testing.T, data []byte) {
// Call into the target. Ignore expected errors; let unexpected
// panics surface as findings.
_, _ = ParseSomething(data)
})
}
The inner f.Fuzz callback signature can use typed parameters instead of
[]byte when the target expects structured input:
f.Fuzz(func(t *testing.T, s string, n int, b bool) {
_ = ProcessRecord(s, n, b)
})
Use the compile_native_go_fuzzer helper in build.sh. It takes the package
import path, the function name, and the output binary name:
# build.sh
cp $SRC/fuzz_test.go ./ # copy harness into the module if needed
printf "package mypkg\nimport _ \"github.com/AdamKorcz/go-118-fuzz-build/testing\"\n" \
> register.go # required registration shim
go mod tidy
compile_native_go_fuzzer github.com/owner/repo/pkg FuzzMyTarget fuzz_my_target
For projects with multiple packages or multiple fuzz targets repeat the call:
compile_native_go_fuzzer github.com/owner/repo/pkg1 FuzzFoo fuzz_foo
compile_native_go_fuzzer github.com/owner/repo/pkg2 FuzzBar fuzz_bar
$OUT/<fuzzer_name>_seed_corpus/ as individual
files, or as a zip at $OUT/<fuzzer_name>_seed_corpus.zip.$OUT/<fuzzer_name>.dict as plaintext token files.f.Add(...) in the harness — these
are compiled in and used as the initial corpus.string, int, bool, float64, etc. directly.f.Fuzz(...), not inside the inner function.f.Add(...) entries should be valid
representative inputs so coverage grows from the start.import _ "github.com/AdamKorcz/go-118-fuzz-build/testing" blank import is required
for OSS-Fuzz to hook into native Go fuzzing — never omit it.Go is memory-safe, so the focus shifts from memory-corruption bugs to:
panic is a crash.python3 infra/helper.py build_fuzzers <project>
python3 infra/helper.py check_build <project>
python3 infra/helper.py run_fuzzer <project> <fuzzer_name> -- -max_total_time=30
go vet ./... and go build ./... inside the module before wrapping in
an OSS-Fuzz build to catch compile errors early.RUN git clone to COPY to avoid network round-trips.