fuzz

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2020 License: Apache-2.0 Imports: 22 Imported by: 3

Documentation

Overview

Package fuzz defines the API used by fzgo (a simple prototype of integrating dvyukov/go-fuzz into 'go test').

See the README at https://github.com/thepudds/fzgo for more details.

Index

Constants

This section is empty.

Variables

View Source
var ErrGoTestFailed = errors.New("go test failed")

ErrGoTestFailed indicates that a 'go test' invocation failed, most likely because the test had a legitimate failure.

View Source
var IncompatibleTestFlags = []string{
	"args",
	"bench",
	"benchmem",
	"benchtime",
	"blockprofile",
	"blockprofilerate",
	"count",
	"cover",
	"covermode",
	"coverpkg",
	"cpu",
	"cpuprofile",
	"exec",
	"failfast",
	"json",
	"list",
	"memprofile",
	"memprofilerate",
	"mutexprofile",
	"mutexprofilefraction",
	"o",
	"outputdir",
	"short",
	"trace",
	"vet",
}

IncompatibleTestFlags is a list of 'go test' flags that might be incompatible with a final 'go test -fuzz' based on the March 2017 proposal document. These currently cause an error if 'fzgo test -fuzz' is also specified. This list likely would change based on more discussion of the proposal.

View Source
var UnimplementedBuildFlags = []string{
	"a",
	"asmflags",
	"buildmode",
	"compiler",
	"gccgoflags",
	"gcflags",
	"installsuffix",
	"ldflags",
	"linkshared",
	"mod",
	"msan",
	"n",
	"p",
	"pkgdir",
	"race",
	"tags",
	"toolexec",
	"work",
	"x",
}

UnimplementedBuildFlags is a list of 'go test' build flags that are not implemented in this simple 'fzgo' prototype; these will cause an error if used with 'fzgo test -fuzz'. (If 'test -fuzz' is not specified, 'fzgo' will pass any of these arguments through to the actual 'go' tool).

View Source
var UnimplementedTestFlags = []string{
	"coverprofile",
	"i",
}

UnimplementedTestFlags is a list of 'go test' flags that are expected to be eventually be compatible with a final 'go test -fuzz' per the March 2017 proposal document, but which are not currently implemented in this simple 'fzgo' prototype. These will currently cause an error if used with 'fzgo test -fuzz'.

Functions

func CacheDir

func CacheDir(hash, pkgName, fuzzName string) string

CacheDir returns <GOPATH>/pkg/fuzz/<GOOS_GOARCH>/<hash>/<package_fuzzfunc>/

func CopyDir

func CopyDir(dst string, src string) error

CopyDir is a simple implementation of recursively copying a directory. The main use case is copying a corpus directory (which does not have symlinks, etc.). Files that already exist in the destination are left alone.

func CopyFile

func CopyFile(dst string, src string) error

CopyFile copies a file. A dst file that already exists is left alone, and is not an error. The main use case is updating a corpus from GOPATH/pkg/fuzz/corpus/..., and we trust the destination if the file already exists.

func ExecGo

func ExecGo(args []string, env []string) error

ExecGo invokes the go command. The intended use case is fzgo operating in pass-through mode, where an invocation like 'fzgo env GOPATH' gets passed to the 'go' tool as 'go env GOPATH'. args typically would be os.Args[1:]

func FindFlag

func FindFlag(args []string, names []string) (string, string, bool)

FindFlag looks for the first matching arg that looks like a flag in the list of flag names, and returns the first flag name found. FindFlag does not stop at non-flag arguments (e.g., it does not stop at a package pattern). This is a simple scan, and not a complete parse of the arguments (and for example does not differentiate between a bool flag vs. a duration flag). A client should do a final valiation pass via fuzz.ParseArgs(), which calls the standard flag.FlagSet.Parse() and which will reject malformed arguments according to the normal rules of the flag package. Returns the found name, and a possible value that is either the value of name=value, or the next arg if there is no '=' immediately after name. It is up to the caller to know if the possible value should be interpreted as the actual value (because, for example, FindFlag has no knowledge of bool flag vs. other flags, etc.).

func FindPkgs

func FindPkgs(args []string) ([]string, []string, error)

FindPkgs looks for args that seem to be package arguments and returns them in a slice.

func FindTestFlag

func FindTestFlag(args []string, names []string) (string, string, bool)

FindTestFlag looks for the first matching arg that looks like a flag in the list of flag names, and returns the first flag name found. If passed flag name 'foo', it looks for both '-foo' and '-test.foo'. See FindFlag for more details.

func FlagSet

func FlagSet(name string, defs []FlagDef, usage Usage) (*flag.FlagSet, error)

FlagSet creates a new flag.FlagSet and registers our flags. Each flag is registered once as "foo" and once as "test.foo"

func Gopath

func Gopath() string

Gopath returns the current effective GOPATH (from the GOPATH env, or the default if env var now set).

func Hash

func Hash(pkgPath, funcName, trimPrefix string, env []string, verbose bool) (string, error)

Hash returns a string representing the hash of the files in a package, its dependencies, as well as the fuzz func name, the version of go and the go-fuzz-build binary.

func IsPlainSig

func IsPlainSig(f *types.Func) (bool, error)

IsPlainSig reports whether a signature is a classic, plain 'func([]bytes) int' go-fuzz signature.

func ParseArgs

func ParseArgs(args []string, fs *flag.FlagSet) (string, error)

ParseArgs finds the flags we are going to interpret and sets the values in a flag.FlagSet. ParseArgs handles a package pattern that might appear in the middle of args in order to allow the flag.FlagSet.Parse() to find flags after the package pattern. ParseArgs also returns at most one package pattern, or "." if none was specified in args.

func PathExists

func PathExists(path string) bool

PathExists reports if a path is exists.

func Start

func Start(target Target, workDir string, maxDuration time.Duration, parallel int, funcTimeout time.Duration, v bool) error

Start begins fuzzing by invoking 'go-fuzz'. cacheDir contains the instrumented binary, and would typically be something like:

GOPATH/pkg/fuzz/linux_amd64/619f7d77e9cd5d7433f8/fmt.FuzzFmt

workDir contains the corpus, and would typically be something like:

GOPATH/src/github.com/user/proj/testdata/fuzz/fmt.FuzzFmt

func VerifyCorpus

func VerifyCorpus(function Func, workDir string, run string, verbose bool) error

VerifyCorpus runs all of the files in a corpus directory as subtests. The approach is to create a temp dir, then create a synthetic corpus_test.go file with a TestCorpus(t *testing.T) func that loads all the files from the corpus, and passes them to the Fuzz function in a t.Run call. A standard 'go test .' is then invoked within that temporary directory. The inputs used are all deterministic (without generating new fuzzing-based inputs). The names used with t.Run mean a 'fzgo test -run=TestCorpus/<corpus-file-name>' works. One way to see the file names or otherwise verify execution is to run 'fzgo test -v <pkg>'.

Types

type FlagDef

type FlagDef struct {
	Name        string
	Ptr         interface{} // *string, *bool, *int, or *time.Duration
	Description string
}

FlagDef holds the definition of an arg we will interpret.

type Func

type Func struct {
	FuncName  string
	PkgName   string      // package name (should be the same as the package's package statement)
	PkgPath   string      // import path
	PkgDir    string      // local on-disk directory
	TypesFunc *types.Func // auxiliary information about a Func from the go/types package
}

Func represents a discovered function that will be fuzzed.

func FindFunc

func FindFunc(pkgPattern, funcPattern string, env []string, allowMultiFuzz bool) ([]Func, error)

FindFunc searches for a requested function to fuzz. It is not an error to not find any -- in that case, it returns a nil list and nil error. The March 2017 proposal document https://github.com/golang/go/issues/19109#issuecomment-285456008 suggests not allowing something like 'go test -fuzz=. ./...' to match multiple fuzz functions. As an experiment, allowMultiFuzz flag allows that. FindFunc also allows for multiple packages in pkgPattern separated by whitespace.

func (*Func) FuzzName

func (f *Func) FuzzName() string

FuzzName returns the '<pkg>.<OrigFuzzFunc>' string. For example, it might be 'fmt.FuzzFmt'. This is used in messages, as well it is part of the path when creating the corpus location under testdata.

func (*Func) String

func (f *Func) String() string

type Target

type Target struct {
	UserFunc Func // the user's original function
	// contains filtered or unexported fields
}

Target tracks some metadata about each fuzz target, and is responsible for tracking a fuzz.Func found via go/packages and making it useful as a fuzz target, including determining where to cache the fuzz.zip and what the target's fuzzName should be.

func CreateRichSigWrapper

func CreateRichSigWrapper(function Func, printArgs bool) (t Target, err error)

CreateRichSigWrapper creates a temp working directory, then creates a rich signature wrapping fuzz function. Important: don't set printArgs=true when actually fuzzing. (Likely bad for perf, though not yet attempted).

func Instrument

func Instrument(function Func, verbose bool) (Target, error)

Instrument builds the instrumented binary and fuzz.zip if they do not already exist in the fzgo cache. If instead there is a cache hit, Instrument prints to stderr that the cached is being used. cacheDir is the location for the instrumented binary, and would typically be something like:

GOPATH/pkg/fuzz/linux_amd64/619f7d77e9cd5d7433f8/fmt.FuzzFmt

func (*Target) FuzzName

func (t *Target) FuzzName() string

FuzzName returns the '<pkg>.<OrigFuzzFunc>' string. For example, it might be 'fmt.FuzzFmt'. This is used in messages, as well it is part of the path when creating the corpus location under testdata.

type Usage

type Usage func(*flag.FlagSet) func()

Usage is a func that returns a func that can be used as flag.FlagSet.Usage

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL