]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.fuzz] internal/fuzz: only reconstruct inputs when needed on RPC return
authorJay Conrod <jayconrod@google.com>
Thu, 2 Sep 2021 21:57:43 +0000 (14:57 -0700)
committerJay Conrod <jayconrod@google.com>
Wed, 8 Sep 2021 19:40:25 +0000 (19:40 +0000)
If the fuzz RPC finds no error and no new coverage, there's no point
in reconstructing the last value.

If the minimize RPC does not succeed in minimizing, either because the
error can't be reproduced, or new coverage can't be reproduced, or a
new error is found with the input, don't marshal or unmarshal the
input. Just use the original.

Change-Id: I3b0f89b8656a2b36066d82efefac0fff4a61fbee
Reviewed-on: https://go-review.googlesource.com/c/go/+/347233
Trust: Jay Conrod <jayconrod@google.com>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
src/internal/fuzz/worker.go

index 32b13662c8c0f1907df0760a1a8a368c90e3c81d..344c1b45b76a8a196798c728f27f24b4fcf6d3de 100644 (file)
@@ -775,7 +775,9 @@ func (ws *workerServer) minimize(ctx context.Context, args minimizeArgs) (resp m
        // to shared memory after completing minimization. If the worker terminates
        // unexpectedly before then, the coordinator will use the original input.
        resp.Success, err = ws.minimizeInput(ctx, vals, &mem.header().count, args.Limit, args.KeepCoverage)
-       writeToMem(vals, mem)
+       if resp.Success {
+               writeToMem(vals, mem)
+       }
        if err != nil {
                resp.Err = err.Error()
        } else if resp.Success {
@@ -1008,7 +1010,6 @@ func (wc *workerClient) minimize(ctx context.Context, entryIn CorpusEntry, args
        }
        mem.setValue(inp)
        wc.memMu <- mem
-       defer func() { wc.memMu <- mem }()
 
        c := call{Minimize: &args}
        callErr := wc.callLocked(ctx, c, &resp)
@@ -1016,13 +1017,24 @@ func (wc *workerClient) minimize(ctx context.Context, entryIn CorpusEntry, args
        if !ok {
                return CorpusEntry{}, minimizeResponse{}, errSharedMemClosed
        }
-       entryOut.Data = mem.valueCopy()
-       h := sha256.Sum256(entryOut.Data)
-       name := fmt.Sprintf("%x", h[:4])
-       entryOut.Name = name
-       entryOut.Parent = entryIn.Parent
-       entryOut.Generation = entryIn.Generation
+       defer func() { wc.memMu <- mem }()
        resp.Count = mem.header().count
+       if resp.Success {
+               entryOut.Data = mem.valueCopy()
+               entryOut.Values, err = unmarshalCorpusFile(entryOut.Data)
+               h := sha256.Sum256(entryOut.Data)
+               name := fmt.Sprintf("%x", h[:4])
+               entryOut.Name = name
+               entryOut.Parent = entryIn.Parent
+               entryOut.Generation = entryIn.Generation
+               if err != nil {
+                       panic(fmt.Sprintf("workerClient.minimize unmarshaling minimized value: %v", err))
+               }
+       } else {
+               // Did not minimize, but the original input may still be interesting,
+               // for example, if there was an error.
+               entryOut = entryIn
+       }
 
        return entryOut, resp, callErr
 }
@@ -1056,23 +1068,27 @@ func (wc *workerClient) fuzz(ctx context.Context, entryIn CorpusEntry, args fuzz
        if !bytes.Equal(inp, mem.valueRef()) {
                panic("workerServer.fuzz modified input")
        }
-       valuesOut, err := unmarshalCorpusFile(inp)
-       if err != nil {
-               panic(fmt.Sprintf("unmarshaling fuzz input value after call: %v", err))
-       }
-       wc.m.r.restore(mem.header().randState, mem.header().randInc)
-       for i := int64(0); i < mem.header().count; i++ {
-               wc.m.mutate(valuesOut, cap(mem.valueRef()))
-       }
-       dataOut := marshalCorpusFile(valuesOut...)
-
-       h := sha256.Sum256(dataOut)
-       name := fmt.Sprintf("%x", h[:4])
-       entryOut = CorpusEntry{
-               Name:       name,
-               Parent:     entryIn.Name,
-               Data:       dataOut,
-               Generation: entryIn.Generation + 1,
+       needEntryOut := callErr != nil || resp.Err != "" ||
+               (!args.CoverageOnly && resp.CoverageData != nil)
+       if needEntryOut {
+               valuesOut, err := unmarshalCorpusFile(inp)
+               if err != nil {
+                       panic(fmt.Sprintf("unmarshaling fuzz input value after call: %v", err))
+               }
+               wc.m.r.restore(mem.header().randState, mem.header().randInc)
+               for i := int64(0); i < mem.header().count; i++ {
+                       wc.m.mutate(valuesOut, cap(mem.valueRef()))
+               }
+               dataOut := marshalCorpusFile(valuesOut...)
+
+               h := sha256.Sum256(dataOut)
+               name := fmt.Sprintf("%x", h[:4])
+               entryOut = CorpusEntry{
+                       Name:       name,
+                       Parent:     entryIn.Name,
+                       Data:       dataOut,
+                       Generation: entryIn.Generation + 1,
+               }
        }
 
        return entryOut, resp, callErr