1
0
mirror of https://github.com/golang/go synced 2024-09-30 04:24:29 -06:00

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>
This commit is contained in:
Roland Shoemaker 2021-10-29 11:21:45 -07:00
parent 80bedb8480
commit 2bcf1c0373

View File

@ -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)