From bd562566e479744d89a73cb5ce89ac997d50d9d2 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:39:56 -0400 Subject: [PATCH 1/7] fuzzing_rich_signatures.txt: multiple corpus locations as input to fuzzing, change default dest --- testscripts/fuzzing_rich_signatures.txt | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/testscripts/fuzzing_rich_signatures.txt b/testscripts/fuzzing_rich_signatures.txt index a170d1d..e7ef2a3 100644 --- a/testscripts/fuzzing_rich_signatures.txt +++ b/testscripts/fuzzing_rich_signatures.txt @@ -1,15 +1,12 @@ # Test fuzzing rich sigs. We could assume go-fuzz and go-fuzz-build binaries are in the path, # but we start these tests doing 'go get' on github.com/dvyukov/go-fuzz/... because we need # the go-fuzz-dep source code to be findable by go-fuzz-build (when it invokes 'go list'). - -# TODO: clean up write up, pull in other permutations from fuzzing.txt +# Reminder: the tests here can be run by themselves from the fzgo directory via: +# go test -run=TestScripts/fuzzing_rich_signatures . # Exit early if -short was specified. [short] skip 'skipping building instrumented binary because -short was specified' -# sanity check upfront -exists $WORK/gopath/src/sample/richsignatures - # get our dependencies go get -v -u github.com/thepudds/fzgo/... go get -v -u github.com/google/gofuzz @@ -28,22 +25,23 @@ exists $WORK/gopath/bin/go-fuzz-build$exe # First fuzz test: no fzgo cache, so we build the instrumented binary from scratch. # This also creates our corpus directory in the default location. -fzgo test -fuzz=FuzzWithBasicTypes sample/richsignatures -fuzztime=5s +fzgo test -fuzz=FuzzWithBasicTypes example.com/richsignatures -fuzztime=5s stdout 'building instrumented binary for pkgname.FuzzWithBasicTypes' stderr 'workers: \d+, corpus: ' -exists $WORK/gopath/src/sample/richsignatures/testdata/fuzz/pkgname.FuzzWithBasicTypes/corpus +exists $WORK/gopath/pkg/fuzz/corpus/example.com/richsignatures/FuzzWithBasicTypes/corpus # Second fuzz test: now we use the fzgo cache. -fzgo test -fuzz=FuzzWithBasicTypes sample/richsignatures -fuzztime=5s +# We also specify -parallel=1 to reduce CPU usage for our remaining tests. +fzgo test -fuzz=FuzzWithBasicTypes example.com/richsignatures -parallel=1 -fuzztime=5s stdout 'fzgo: using cached instrumented binary for pkgname.FuzzWithBasicTypes' stderr 'workers: \d+, corpus: ' # Flag -fuzzdir controls where the corpus goes (which could be in a different repo). # This invocation still uses the cache, as do all subsequent invocations in this script. -fzgo test -fuzz=FuzzWithBasicTypes sample/richsignatures -fuzztime=5s -fuzzdir=$WORK/myfuzzdir +fzgo test -fuzz=FuzzWithBasicTypes example.com/richsignatures -parallel=1 -fuzztime=5s -fuzzdir=$WORK/myfuzzdir stdout 'fzgo: using cached instrumented binary for pkgname.FuzzWithBasicTypes' stderr 'workers: \d+, corpus: ' -exists $WORK/myfuzzdir/pkgname.FuzzWithBasicTypes/corpus +exists $WORK/myfuzzdir/example.com/richsignatures/FuzzWithBasicTypes/corpus # Uncomment this next line if you don't want to rely on goimports # [!exec:goimports] stop 'skipping remaining step that currently relies on goimports being in the path' @@ -54,21 +52,21 @@ stderr 'goimports' # Check rich signature from stdlib (uses regexp) # This currently relies on goimports being in the path. -fzgo test -fuzz=FuzzWithStdlibType sample/richsignatures -fuzztime=5s +fzgo test -fuzz=FuzzWithStdlibType example.com/richsignatures -parallel=1 -fuzztime=5s stdout 'building instrumented binary for pkgname.FuzzWithStdlibType' stderr 'workers: \d+, corpus: ' -exists $WORK/gopath/src/sample/richsignatures/testdata/fuzz/pkgname.FuzzWithStdlibType/corpus +exists $WORK/gopath/pkg/fuzz/corpus/example.com/richsignatures/FuzzWithStdlibType/corpus # Check we can get a crasher relatively quickly by finding a 64 bit int via a rich signature, which -# should imply go-fuzz literal injection is working end-to-end with rich signatures. -fzgo test -fuzz=FuzzHardToGuessNumber sample/richsignatures -fuzztime=20s +# should imply go-fuzz literal injection is working end-to-end with fzgo's rich signatures. +fzgo test -fuzz=FuzzHardToGuessNumber example.com/richsignatures -parallel=1 -fuzztime=10s stdout 'building instrumented binary for pkgname.FuzzHardToGuessNumber' stderr 'workers: \d+, corpus: .* crashers: [^0]' -exists $WORK/gopath/src/sample/richsignatures/testdata/fuzz/pkgname.FuzzHardToGuessNumber/corpus +exists $WORK/gopath/pkg/fuzz/corpus/example.com/richsignatures/FuzzHardToGuessNumber/corpus -# TODO: currently this is cloned from examples dir in fzgo repo +# NOTE: currently this is cloned from examples dir in fzgo repo. (Probably good to have locally here?) --- gopath/src/sample/richsignatures/richsignatures.go -- +-- gopath/src/example.com/richsignatures/richsignatures.go -- package pkgname import ( From a212f4448146299d09f30b594bf70bb1730ef986 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:40:57 -0400 Subject: [PATCH 2/7] main.go: multiple corpus locations as input to fuzzing, change default dest --- main.go | 137 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 25 deletions(-) diff --git a/main.go b/main.go index 523d8ff..a95ecbd 100644 --- a/main.go +++ b/main.go @@ -6,9 +6,10 @@ // 1. cacheDir is the location for the instrumented binary, and would typically be something like: // GOPATH/pkg/fuzz/linux_amd64/619f7d77e9cd5d7433f8/fmt.FuzzFmt // 2. fuzzDir is the directory supplied via the -fuzzdir argument, and contains the workDir. -// 3. workDir is passed to go-fuzz as the -workdir argument. -// if -fuzzdir is specified, workDir is fuzzdir/ -// if -fuzzdir is not specified, workDir is pkgpath/testdata/fuzz/ +// 3. workDir is passed to go-fuzz-build and go-fuzz as the -workdir argument. +// if -fuzzdir is not specified: workDir is GOPATH/pkg/fuzz/corpus// +// if -fuzzdir is '/some/path': workDir is /some/path// +// if -fuzzdir is 'testdata': workDir is /testdata/fuzz/ package main import ( @@ -79,7 +80,7 @@ func fzgoMain() int { if os.Args[1] != "test" { // pass through to 'go' command - err := fuzz.ExecGo(os.Args[1:], nil) + err = fuzz.ExecGo(os.Args[1:], nil) if err != nil { // ExecGo prints error if 'go' tool is not in path. // Other than that, we currently rely on the 'go' tool to print any errors itself. @@ -147,7 +148,7 @@ func fzgoMain() int { fmt.Printf("fzgo: found functions %s\n", strings.Join(names, ", ")) } - // build our instrumented code, or find it already built in the fzgo cache + // build our instrumented code, or find if is is already built in the fzgo cache var targets []fuzz.Target for _, function := range functions { target, err := fuzz.Instrument(function, flagVerbose) @@ -168,13 +169,14 @@ func fzgoMain() int { timeQuantum := 5 * time.Second for { for _, target := range targets { - // pull our last bit of info out of our arguments, then start fuzzing. - // TODO: Currently calculating this > 1 time in main.go. - var workDir string - if flagFuzzDir == "" { - workDir = filepath.Join(target.UserFunc.PkgDir, "testdata", "fuzz", target.FuzzName()) - } else { - workDir = filepath.Join(flagFuzzDir, target.FuzzName()) + // pull our last bit of info out of our arguments. + workDir := determineWorkDir(target.UserFunc, flagFuzzDir) + + // seed our workDir with any other corpus that might exist from other known locations. + // see comment for copyCachedCorpus for discussion of current behavior vs. desired behavior. + if err = copyCachedCorpus(target.UserFunc, workDir); err != nil { + fmt.Println("fzgo:", err) + return OtherErr } // determine how long we will execute this particular fuzz invocation. @@ -216,7 +218,7 @@ func fzgoMain() int { // args is os.Args func verifyCorpus(args []string) int { // we do this by first searching for any fuzz func ("." regexp) in our package pattern. - // TODO: move this elsewhere. Taken from fuzz.ParseArgs. + // TODO: move this elsewhere? Taken from fuzz.ParseArgs, but we can't use fuzz.ParseArgs as is. testPkgPatterns, nonPkgArgs, err := fuzz.FindPkgs(args[2:]) if err != nil { fmt.Println("fzgo:", err) @@ -239,29 +241,114 @@ func verifyCorpus(args []string) int { } // TODO: should we get -v? E.g., something like: // _, verbose := fuzz.FindTestFlag(os.Args[2:], []string{"v"}) + status := Success for _, function := range functions { - fuzzName := function.FuzzName() - var workDir string + + // work through how many places we need to check based on + // what the user specified in flagFuzzDir. + var dirsToCheck []string + + // we always check the "testdata" dir if it exists. + testdataWorkDir := determineWorkDir(function, "testdata") + dirsToCheck = append(dirsToCheck, testdataWorkDir) + + // we also always check under GOPATH/pkg/fuzz/corpus/... if it exists. + gopathPkgWorkDir := determineWorkDir(function, "") + dirsToCheck = append(dirsToCheck, gopathPkgWorkDir) + + // see if we need to check elsewhere as well. if flagFuzzDir == "" { - workDir = filepath.Join(function.PkgDir, "testdata", "fuzz", fuzzName) + // nothing else to do; the user did not specify a dir. + } else if flagFuzzDir == "testdata" { + // nothing else to do; we already added testdata dir. } else { - workDir = filepath.Join(flagFuzzDir, fuzzName) + // the user supplied a destination + userWorkDir := determineWorkDir(function, flagFuzzDir) + dirsToCheck = append(dirsToCheck, userWorkDir) } - err := fuzz.VerifyCorpus(function, workDir, nonPkgArgs) - if err == fuzz.ErrGoTestFailed { - // 'go test' itself should have printed an informative error, - // so here we just set a non-zero status code and continue. - status = OtherErr - } else if err != nil { - fmt.Println("fzgo:", err) - return OtherErr + + // we have 2 or 3 places to check + for _, workDir := range dirsToCheck { + if !fuzz.PathExists(workDir) { + // this workDir does not exist, so skip + continue + } + + err := fuzz.VerifyCorpus(function, workDir, nonPkgArgs) + if err == fuzz.ErrGoTestFailed { + // 'go test' itself should have printed an informative error, + // so here we just set a non-zero status code and continue. + status = OtherErr + } else if err != nil { + fmt.Println("fzgo:", err) + return OtherErr + } } } return status } +// determineWorkDir translates from the user's specified -fuzzdir to an actual +// location on disk, including the default location if the user does not specify a -fuzzdir. +func determineWorkDir(function fuzz.Func, requestedFuzzDir string) string { + var workDir string + importPathDirs := filepath.FromSlash(function.PkgPath) // convert import path into filepath + if requestedFuzzDir == "" { + // default to GOPATH/pkg/fuzz/corpus/import/path/ + gp := fuzz.Gopath() + workDir = filepath.Join(gp, "pkg", "fuzz", "corpus", importPathDirs, function.FuncName) + } else if requestedFuzzDir == "testdata" { + // place under the package of interest in the testdata directory. + workDir = filepath.Join(function.PkgDir, "testdata", "fuzz", function.FuncName) + } else { + // requestedFuzzDir was specified to be an actual directory. + // still use the import path to handle fuzzing multiple functions across multiple packages. + workDir = filepath.Join(requestedFuzzDir, importPathDirs, function.FuncName) + } + return workDir +} + +// copyCachedCorpus desired bheavior (or at least proposed-by-me behavior): +// 1. if destination corpus location doesn't exist, seed it from GOPATH/pkg/fuzz/corpus/import/path/ +// 2. related: fuzz while reading from all known locations that exist (e.g,. testdata if it exists, GOPATH/pkg/fuzz/corpus/...) +// +// However, 2. is not possible currently to do directly with dvyukov/go-fuzz for more than 1 corpus. +// +// Therefore, the current behavior of copyCachedCorpus approximates 1. and 2. like so: +// 1'. always copy all known corpus entries to the destination corpus location in all cases. +// +// Also, that current behavior could be reasonable for the proposed behavior in the sense that it is simple. +// Filenames that already exist in the destination are not updated. +// TODO: it is debatable if it should copy crashers and suppressions as well. +// For clarity, it only copies the corpus directory itself, and not crashers and supressions. +// This avoids making sometone think they have a new crasher after copying a crasher to a new location, for example, +// especially at this current prototype phase where the crasher reporting in +// go-fuzz does not know anything about multi-corpus locations. +func copyCachedCorpus(function fuzz.Func, dstWorkDir string) error { + dstCorpusDir := filepath.Join(dstWorkDir, "corpus") + + gopathPkgWorkDir := determineWorkDir(function, "") + testdataWorkDir := determineWorkDir(function, "testdata") + + for _, srcWorkDir := range []string{gopathPkgWorkDir, testdataWorkDir} { + srcCorpusDir := filepath.Join(srcWorkDir, "corpus") + if srcCorpusDir == dstCorpusDir { + // nothing to do + continue + } + if fuzz.PathExists(srcCorpusDir) { + // copyDir will create dstDir if needed, and won't overwrite files + // in dstDir that already exist. + if err := fuzz.CopyDir(dstCorpusDir, srcCorpusDir); err != nil { + return fmt.Errorf("failed seeding destination corpus: %v", err) + } + } + } + return nil +} + func usage(fs *flag.FlagSet) func() { return func() { fmt.Printf("\nfzgo is a simple prototype of integrating dvyukov/go-fuzz into 'go test'.\n\n") From d903c7f1381c9f61ea6646dd9a5c9004397a4b39 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:43:37 -0400 Subject: [PATCH 3/7] cache.go: multiple corpus locations as input to fuzzing, change default dest --- fuzz/cache.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/fuzz/cache.go b/fuzz/cache.go index c83c0de..75b45fa 100644 --- a/fuzz/cache.go +++ b/fuzz/cache.go @@ -19,10 +19,7 @@ import ( // CacheDir returns /pkg/fuzz//// func CacheDir(hash, pkgName, fuzzName string) string { - gp := os.Getenv("GOPATH") - if gp == "" { - gp = build.Default.GOPATH - } + gp := Gopath() s := strings.Split(gp, string(os.PathListSeparator)) if len(s) > 1 { gp = s[0] @@ -31,6 +28,15 @@ func CacheDir(hash, pkgName, fuzzName string) string { hash, fuzzName) } +// Gopath returns the current effective GOPATH (from the GOPATH env, or the default if env var now set). +func Gopath() string { + gp := os.Getenv("GOPATH") + if gp == "" { + gp = build.Default.GOPATH + } + return gp +} + // 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 Hash(pkgPath, funcName, trimPrefix string, env []string, verbose bool) (string, error) { @@ -167,3 +173,68 @@ func goListDeps(pkg string, env []string) ([]string, error) { } return results, nil } + +// 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 CopyDir(dst string, src string) error { + report := func(err error) error { + return fmt.Errorf("copy dir failed from %s to %s: %v", dst, src, err) + } + files, err := ioutil.ReadDir(src) + if err != nil { + return report(err) + } + if err := os.MkdirAll(dst, 0700); err != nil { + return report(err) + } + for _, f := range files { + dstName := filepath.Join(dst, f.Name()) + srcName := filepath.Join(src, f.Name()) + if f.IsDir() { + if err := CopyDir(dstName, srcName); err != nil { + return report(err) + } + } else { + if err := CopyFile(dstName, srcName); err != nil { + return report(err) + } + } + } + return nil +} + +// 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 CopyFile(dst string, src string) error { + report := func(err error) error { + return fmt.Errorf("copy file failed from %s to %s: %v", dst, src, err) + } + if PathExists(dst) { + return nil + } + w, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0700) + if err != nil { + return report(err) + } + defer w.Close() + r, err := os.Open(src) + if err != nil { + return report(err) + } + defer r.Close() + if _, err := io.Copy(w, r); err != nil { + return report(err) + } + return nil +} + +// PathExists reports if a path is exists. +func PathExists(path string) bool { + if _, err := os.Stat(path); os.IsNotExist(err) { + return false + } + return true +} From 78e6cc96f69416b3924a0dc407ec8ed23debfe37 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:45:04 -0400 Subject: [PATCH 4/7] richsig.go: multiple corpus locations as input to fuzzing, change default dest --- fuzz/richsig.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fuzz/richsig.go b/fuzz/richsig.go index 69b19f8..d94aa51 100644 --- a/fuzz/richsig.go +++ b/fuzz/richsig.go @@ -53,9 +53,9 @@ func IsPlainSig(f *types.Func) (bool, error) { return true, nil } -// CreateWrapperFunc creates a temp working directory, then +// CreateRichSigWrapper creates a temp working directory, then // creates a rich signature wrapping fuzz function. -func CreateWrapperFunc(function Func) (t Target, err error) { +func CreateRichSigWrapper(function Func) (t Target, err error) { report := func(err error) (Target, error) { return Target{}, fmt.Errorf("creating wrapper function for %s: %v", function.FuzzName(), err) } @@ -65,11 +65,10 @@ func CreateWrapperFunc(function Func) (t Target, err error) { if err != nil { return report(fmt.Errorf("create staging temp dir: %v", err)) } - // TODO: need to delete temp directory in non-error case. defer func() { // conditionally clean up. (this is a bit of an experiment to use named return err here). if err != nil { - // on our our out, but encountered an error, so delete the temp dir + // on our way out, but encountered an error, so delete the temp dir os.RemoveAll(tempDir) } }() @@ -99,7 +98,10 @@ func CreateWrapperFunc(function Func) (t Target, err error) { // write out temporary richsigwrapper.go file var b bytes.Buffer - createWrapper(&b, function) + err = createWrapper(&b, function) + if err != nil { + return report(fmt.Errorf("failed constructing rich signature wrapper: %v", err)) + } err = ioutil.WriteFile(filepath.Join(wrapperDir, "richsigwrapper.go"), b.Bytes(), 0700) if err != nil { return report(fmt.Errorf("failed to create temporary richsigwrapper.go: %v", err)) @@ -121,8 +123,6 @@ func CreateWrapperFunc(function Func) (t Target, err error) { // TODO: ########### resume finishing up here, also fuzz.Instrument, fuzz.Start ########## // TODO: ################################################################################## - // TODO: need to delete temp directory in non-error case. - // Note: pkg patterns like 'fzgo/...' and 'fzgo/richsigwrapper' don't seem to work, but '.' does. // (We cd'ed above to the working directory. Maybe a go/packages bug, not liking >1 GOPATH entry?) functions, err := FindFunc(".", "FuzzRichSigWrapper", env, false) @@ -149,8 +149,7 @@ func createWrapper(w io.Writer, function Func) error { } // start emitting the wrapper program! - // TODO: add in something like: - // fuzzer := gofuzz.New().NilChance(0.1).NumElements(0, 10).MaxDepth(10) + // TODO: add in something like: fuzzer := gofuzz.New().NilChance(0.1).NumElements(0, 10).MaxDepth(10) fmt.Fprintf(w, "\npackage richsigwrapper\n") fmt.Fprintf(w, "\nimport \"%s\"\n", function.PkgPath) fmt.Fprintf(w, ` From 9245e2570607c7b52f3d9ae077f9d0f43793e253 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:45:46 -0400 Subject: [PATCH 5/7] richsig_test.go: multiple corpus locations as input to fuzzing, change default dest --- fuzz/richsig_test.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/fuzz/richsig_test.go b/fuzz/richsig_test.go index 6073d0b..1cd7f0a 100644 --- a/fuzz/richsig_test.go +++ b/fuzz/richsig_test.go @@ -18,8 +18,6 @@ func TestWrapperGeneration(t *testing.T) { args args wantOutput string wantErr bool - // TODO: delete? update? not use currently. - // want []Func }{ { name: "only basic types: string, []byte, bool", @@ -147,21 +145,17 @@ func fuzzOne (fuzzer *randparam.Fuzzer) { var b bytes.Buffer functions, err := FindFunc(tt.args.pkgPattern, tt.args.funcPattern, nil, tt.args.allowMultiFuzz) if (err != nil) != tt.wantErr { - t.Errorf("FindFunc() error = %v, wantErr %v", err, tt.wantErr) - return + t.Fatalf("FindFunc() error = %v, wantErr %v", err, tt.wantErr) + } + err = createWrapper(&b, functions[0]) + if err != nil { + t.Fatalf("createWrapper() error = %v", err) } - createWrapper(&b, functions[0]) gotOutput := b.String() diff := cmp.Diff(tt.wantOutput, gotOutput) if diff != "" { - t.Fatalf("FindFunc() failed to match function output. diff:\n%s", diff) - } - - /* TODO: delete? update? - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindFunc() = %v, want %v", got, tt.want) + t.Fatalf("createWrapper() failed to match function output. diff:\n%s", diff) } - */ }) } } From 319ebd6bbddc19987479ca070fdf1cd5e9133a86 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:46:27 -0400 Subject: [PATCH 6/7] exec.go: multiple corpus locations as input to fuzzing, change default dest --- fuzz/exec.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fuzz/exec.go b/fuzz/exec.go index cd2fd48..f7b3ebe 100644 --- a/fuzz/exec.go +++ b/fuzz/exec.go @@ -28,21 +28,28 @@ func Instrument(function Func, verbose bool) (Target, error) { return report(fmt.Errorf("unexpected fuzz function: %#v", function)) } + // check if we have a plain data []byte signature, vs. a rich signature plain, err := IsPlainSig(function.TypesFunc) if err != nil { return report(err) } var target Target - if !plain { + if plain { + // create our initial target struct using the actual func supplied by the user. + target = Target{UserFunc: function} + } else { info("detected rich signature for %v.%v", function.PkgName, function.FuncName) - target, err = CreateWrapperFunc(function) + // create a wrapper function to handle the rich signature. + target, err = CreateRichSigWrapper(function) if err != nil { return report(err) } - } else { - // create our initial target struct - target = Target{UserFunc: function} + // CreateRichSigWrapper was succesful, which means it populated the temp dir with the wrapper func. + // By the time we leave our current function, we are done with the temp dir + // that CreateRichSigWrapper created, so delete via a defer. + // (We can't delete it immediately because we haven't yet run go-fuzz-build on it). + defer os.RemoveAll(target.wrapperTempDir) } // Determine where our cacheDir is. @@ -66,7 +73,7 @@ func Instrument(function Func, verbose bool) (Target, error) { if _, err = os.Stat(finalZipPath); os.IsNotExist(err) { // TODO: resume here ########################################################################### // clean up the functions running around. switch to target. - // also, delete the temp dir. probably with a defer just after target returns succesfully + // also, delete the temp dir. probably with a defer just after target returns successfully info("building instrumented binary for %v.%v", function.PkgName, function.FuncName) outFile := filepath.Join(cacheDir, "fuzz.zip.partial") var args []string @@ -182,7 +189,6 @@ func (t *Target) cacheDir(verbose bool) (string, error) { if t.savedCacheDir == "" { // generate a hash covering the package, its dependencies, and some items like go-fuzz-build binary and go version // TODO: pass verbose flag around? - // TODO: update packagedir for trimPrefix if / when target is introduced (want to trim TEMP dir) var err error var h string if !t.hasWrapper { @@ -219,7 +225,6 @@ func ExecGo(args []string, env []string) error { } // A maxDuration of 0 means no max time is enforced. -// TODO: added env. make public? put in fzgo/fuzz package? func execCmd(name string, args []string, env []string, maxDuration time.Duration) error { report := func(err error) error { return fmt.Errorf("exec %v error: %v", name, err) } From 815abbde595f6a5543d89ded59dc76b694f8ae04 Mon Sep 17 00:00:00 2001 From: thepudds <20628140+thepudds@users.noreply.github.com> Date: Sat, 3 Aug 2019 15:47:01 -0400 Subject: [PATCH 7/7] packages.go: multiple corpus locations as input to fuzzing, change default dest --- fuzz/packages.go | 1 - 1 file changed, 1 deletion(-) diff --git a/fuzz/packages.go b/fuzz/packages.go index 8e9abbc..271681e 100644 --- a/fuzz/packages.go +++ b/fuzz/packages.go @@ -40,7 +40,6 @@ func (f *Func) String() string { // suggests not allowing something like 'go test -fuzz=. ./...' to match multiple fuzz functions. // As an experiment, allowMultiFuzz flag allows that. // FindFunc searches for a requested function to visit. -// TODO: from richsig func FindFunc(pkgPattern, funcPattern string, env []string, allowMultiFuzz bool) ([]Func, error) { report := func(err error) error { return fmt.Errorf("error while loading packages for pattern %v: %v", pkgPattern, err)