Skip to content

testing: fuzzing with float64 can produce errors and unparsable corpus files #51258

Closed
@dchapes

Description

@dchapes

What version of Go are you using (go version)?

$ go version
go version go1.18rc1 freebsd/amd64

Does this issue reproduce with the latest release?

Only relevant for Go1.18 beta and rc. Both beta2 and rc1 reproduce this.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dchapes/go/go-build-cache"
GOENV="/home/dchapes/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS="-trimpath"
GOHOSTARCH="amd64"
GOHOSTOS="freebsd"
GOINSECURE=""
GOMODCACHE="/home/dchapes/go/pkg/mod"
GONOPROXY=""
GONOSUMDB="github.com/dchapes,hg.sr.ht/~dchapes"
GOOS="freebsd"
GOPATH="/home/dchapes/go"
GOPRIVATE=""
GOPROXY=""
GOROOT="/home/dchapes/sdk/go1.18rc1"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/dchapes/sdk/go1.18rc1/pkg/tool/freebsd_amd64"
GOVCS=""
GOVERSION="go1.18rc1"
GCCGO="gccgo"
GOAMD64="v3"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/home/dchapes/go/src/dave-test/fuzz_float/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2272238524=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package fuzz_float

import (
	"math"
	"testing"
)

func FuzzFloat(f *testing.F) {
	f.Add(math.Inf(1))
	f.Fuzz(func(t *testing.T, f float64) {
		f = f + f
	})
}
$ go test -fuzz=. -fuzztime=10s
fuzz: elapsed: 0s, gathering baseline coverage: 0/2 completed
fuzz: elapsed: 0s, gathering baseline coverage: 1/2 completed
--- FAIL: FuzzFloat (0.01s)
    malformed line "float64(+Inf)": expected operation on int or float type
FAIL
exit status 1
FAIL    dave-test/fuzz_float    0.010s
Exit 1

Note: I had this happen with an actual Fuzz function I was writing that took (float64, int, int) and using f.Add(math.MaxFloat64, 0, 0). In that case it took a few fuzzing runs for the error to appear. That code being fuzzed does handle ±Inf specially so fuzzing would find those inputs interesting.

What did you expect to see?

Fuzzing to work and not create corpus files it can't parse.

What did you see instead?

The above error. In the included code since f.Add is used to add +Inf no bad corpus file is written, but in my actual use case I eventually got a corpus file
in ~/go/go-build-cache/fuzz//FuzzFormat/1b137f1e2faea57dd1c14f1c8ffc4bcf7e67ec00693d5f5e7f57ef840a50174a with:

go test fuzz v1
float64(+Inf)
int(-33)
int(82)

Which causes go fuzz to produce the error every time no matter what f.Add calls are then used. Deleting the "bad" corpus file and excluding any f.Add lines with large/infinite values allows go fuzz to run okay until/unless it tries another +Inf.

Edit: I've also seen:

    malformed line "float64(NaN)": literal value required for primitive type

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.fuzzIssues related to native fuzzing support

    Type

    No type

    Projects

    Status

    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions