diff options
author | Roland Shoemaker <roland@golang.org> | 2021-10-29 11:21:45 -0700 |
---|---|---|
committer | Roland Shoemaker <roland@golang.org> | 2021-11-01 16:31:02 +0000 |
commit | 2bcf1c0373195724161a9dc287e1dbc26404e4fa (patch) | |
tree | 2937444fbb4df49e07630c0ac8b842cd1bf7db71 /src/internal | |
parent | 80bedb848092c993182f79a946d54776dc251549 (diff) | |
download | go-2bcf1c0373195724161a9dc287e1dbc26404e4fa.tar.gz go-2bcf1c0373195724161a9dc287e1dbc26404e4fa.zip |
internal/fuzz: don't add duplicate corpus entries
If a identical input is already present in the corpus, don't re-add it.
This may happen when the same input produces a different coverage map,
causing the coordinator to think it has found a new input.
This fixes a race between reading/writing cached inputs.
Fixes #48721
Change-Id: I4807602f433c2b99396d25ceaa58b827796b3555
Reviewed-on: https://go-review.googlesource.com/c/go/+/359755
Trust: Roland Shoemaker <roland@golang.org>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Katie Hockman <katie@golang.org>
Diffstat (limited to 'src/internal')
-rw-r--r-- | src/internal/fuzz/fuzz.go | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/internal/fuzz/fuzz.go b/src/internal/fuzz/fuzz.go index 5008927f0e..78319a7496 100644 --- a/src/internal/fuzz/fuzz.go +++ b/src/internal/fuzz/fuzz.go @@ -316,6 +316,23 @@ func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err err // Update the coordinator's coverage mask and save the value. inputSize := len(result.entry.Data) if opts.CacheDir != "" { + // It is possible that the input that was discovered is already + // present in the corpus, but the worker produced a coverage map + // that still expanded our total coverage (this may happen due to + // flakiness in the coverage counters). In order to prevent adding + // duplicate entries to the corpus (and re-writing the file on + // disk), skip it if the on disk file already exists. + // TOOD(roland): this check is limited in that it will only be + // applied if we are using the CacheDir. Another option would be + // to iterate through the corpus and check if it is already present, + // which would catch cases where we are not caching entries. + // A slightly faster approach would be to keep some kind of map of + // entry hashes, which would allow us to avoid iterating through + // all entries. + _, err = os.Stat(result.entry.Path) + if err == nil { + continue + } err := writeToCorpus(&result.entry, opts.CacheDir) if err != nil { stop(err) |