]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.fuzz] internal/fuzz: fix bug for -fuzzminimizetime of zero
authorKatie Hockman <katie@golang.org>
Fri, 10 Sep 2021 19:25:30 +0000 (15:25 -0400)
committerKatie Hockman <katie@golang.org>
Fri, 10 Sep 2021 20:17:28 +0000 (20:17 +0000)
Updates golang/go#48321

Change-Id: Ib35388f17580f1244a6eae4e5879f8329b6b44ce
Reviewed-on: https://go-review.googlesource.com/c/go/+/349090
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
src/cmd/go/testdata/script/test_fuzz_minimize.txt
src/internal/fuzz/fuzz.go

index dac11231ef93c81c5371b42a5942648b5c5f6dda..c180890a9b19759d3a95c7acf129ceb4003e9244 100644 (file)
@@ -6,18 +6,6 @@
 # We clean the fuzz cache during this test. Don't clean the user's cache.
 env GOCACHE=$WORK/gocache
 
-# Test that fuzzminimizetime can be zero seconds
-! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=0s minimizer_test.go
-! stdout '^ok'
-stdout 'contains a non-zero byte'
-stdout FAIL
-
-# Test that fuzzminimizetime can be zero times
-! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=0x minimizer_test.go
-! stdout '^ok'
-stdout 'contains a non-zero byte'
-stdout FAIL
-
 # Test that fuzzminimizetime cannot be negative seconds
 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1ms minimizer_test.go
 ! stdout '^ok'
@@ -32,6 +20,20 @@ stdout FAIL
 stdout 'invalid count'
 stdout FAIL
 
+# Test that fuzzminimizetime can be zero seconds, and minimization is disabled
+! go test -fuzz=FuzzMinimizeZeroDurationSet -run=FuzzMinimizeZeroDurationSet -fuzztime=10000x -fuzzminimizetime=0s minimizer_test.go
+! stdout '^ok'
+! stdout 'found a crash, minimizing...'
+stdout 'there was an Error'
+stdout FAIL
+
+# Test that fuzzminimizetime can be zero times, and minimization is disabled
+! go test -fuzz=FuzzMinimizeZeroLimitSet -run=FuzzMinimizeZeroLimitSet -fuzztime=10000x -fuzzminimizetime=0x minimizer_test.go
+! stdout '^ok'
+! stdout 'found a crash, minimizing...'
+stdout 'there was an Error'
+stdout FAIL
+
 # Test that minimization is working for recoverable errors.
 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x minimizer_test.go
 ! stdout '^ok'
@@ -87,6 +89,22 @@ import (
        "testing"
 )
 
+func FuzzMinimizeZeroDurationSet(f *testing.F) {
+       f.Fuzz(func(t *testing.T, b []byte) {
+               if len(b) > 5 {
+                       t.Errorf("there was an Error")
+               }
+       })
+}
+
+func FuzzMinimizeZeroLimitSet(f *testing.F) {
+       f.Fuzz(func(t *testing.T, b []byte) {
+               if len(b) > 5 {
+                       t.Errorf("there was an Error")
+               }
+       })
+}
+
 func FuzzMinimizerRecoverable(f *testing.F) {
        f.Add(make([]byte, 100))
        f.Fuzz(func(t *testing.T, b []byte) {
index 6c07da2dbe43de96b24261ca5ec09d5e7efb5c5a..c19ea35f23191c16bb4ed115b2308dbb1cbbb9cf 100644 (file)
@@ -40,13 +40,16 @@ type CoordinateFuzzingOpts struct {
        Limit int64
 
        // MinimizeTimeout is the amount of wall clock time to spend minimizing
-       // after discovering a crasher. If zero, there will be no time limit.
+       // after discovering a crasher. If zero, there will be no time limit. If
+       // MinimizeTimeout and MinimizeLimit are both zero, then minimization will
+       // be disabled.
        MinimizeTimeout time.Duration
 
        // MinimizeLimit is the maximum number of calls to the fuzz function to be
-       // made while minimizing after finding a crash. If zero, there will be
-       // no limit. Calls to the fuzz function made when minimizing also count
-       // toward Limit.
+       // made while minimizing after finding a crash. If zero, there will be no
+       // limit. Calls to the fuzz function made when minimizing also count toward
+       // Limit. If MinimizeTimeout and MinimizeLimit are both zero, then
+       // minimization will be disabled.
        MinimizeLimit int64
 
        // parallel is the number of worker processes to run in parallel. If zero,
@@ -552,9 +555,10 @@ type coordinator struct {
        // generated values that workers reported as interesting.
        corpus corpus
 
-       // typesAreMinimizable is true if one or more of the types of fuzz function's
-       // parameters can be minimized.
-       typesAreMinimizable bool
+       // minimizationAllowed is true if one or more of the types of fuzz
+       // function's parameters can be minimized, and either the limit or duration
+       // for minimization is non-zero.
+       minimizationAllowed bool
 
        // inputQueue is a queue of inputs that workers should try fuzzing. This is
        // initially populated from the seed corpus and cached inputs. More inputs
@@ -604,10 +608,12 @@ func newCoordinator(opts CoordinateFuzzingOpts) (*coordinator, error) {
                resultC:   make(chan fuzzResult),
                corpus:    corpus,
        }
-       for _, t := range opts.Types {
-               if isMinimizable(t) {
-                       c.typesAreMinimizable = true
-                       break
+       if opts.MinimizeLimit > 0 || opts.MinimizeTimeout > 0 {
+               for _, t := range opts.Types {
+                       if isMinimizable(t) {
+                               c.minimizationAllowed = true
+                               break
+                       }
                }
        }
 
@@ -736,7 +742,7 @@ func (c *coordinator) queueForMinimization(result fuzzResult, keepCoverage []byt
 // peekMinimizeInput returns the next input that should be sent to workers for
 // minimization.
 func (c *coordinator) peekMinimizeInput() (fuzzMinimizeInput, bool) {
-       if c.opts.Limit > 0 && c.count+c.countWaiting >= c.opts.Limit {
+       if !c.canMinimize() {
                // Already making the maximum number of calls to the fuzz function.
                // Don't send more inputs right now.
                return fuzzMinimizeInput{}, false
@@ -810,7 +816,7 @@ func (c *coordinator) updateCoverage(newCoverage []byte) int {
 // canMinimize returns whether the coordinator should attempt to find smaller
 // inputs that reproduce a crash or new coverage.
 func (c *coordinator) canMinimize() bool {
-       return c.typesAreMinimizable &&
+       return c.minimizationAllowed &&
                (c.opts.Limit == 0 || c.count+c.countWaiting < c.opts.Limit)
 }