go-fuzz icon indicating copy to clipboard operation
go-fuzz copied to clipboard

Bad parsing and/or generation of instrumented code

Open armfazh opened this issue 4 years ago • 3 comments

Issue: The code of the function times3 produced by instrumentation is wrong.

This is the minimal reproducible example.

File: fuzz.go

package fuzz

func timesN(b []byte, n int) { b[0] *= byte(n) }
func times3(b []byte)        { timesN(b, 3) }

//go:noescape
func times5(b []byte)

func Fuzz(data []byte) int {
	times3(data)
	times5(data)

	return 0
}

File: times.s

#include "textflag.h"

TEXT ·times5(SB), NOSPLIT,$0
    RET

Command

 $ go-fuzz-build

Output:

 $ go-fuzz-build
    fuzz.go:4: can only use //go:noescape with external func implementations
Instrumented code (wrong)
//line /home/user/bug/fuzz.go:1
package fuzz

//line /home/user/bug/fuzz.go:1
import _go_fuzz_dep_ "go-fuzz-dep"

func timesN(b []byte, n int)	{ _go_fuzz_dep_.CoverTab[22588]++; b[0] *= byte(n) }
func times3(b []byte)		{ _go_fuzz_dep_.CoverTab[

//go:noescape
//line /home/user/bug/fuzz.go:4
44810]++; timesN(b, 3) }

//line /home/user/bug/fuzz.go:7
func times5(b []byte)

//line /home/user/bug/fuzz.go:10
func Fuzz(data []byte) int {
//line /home/user/bug/fuzz.go:10
	_go_fuzz_dep_.CoverTab[5262]++
							times3(data)
							times5(data)

							return 0
}

//line /home/user/bug/fuzz.go:15
var _ = _go_fuzz_dep_.CoverTab
Instrumented code (expected/correct)
//line /home/user/bug/fuzz.go:1
package fuzz

//line /home/user/bug/fuzz.go:1
import _go_fuzz_dep_ "go-fuzz-dep"

func timesN(b []byte, n int)	{ _go_fuzz_dep_.CoverTab[22588]++; b[0] *= byte(n) }
func times3(b []byte)		{ _go_fuzz_dep_.CoverTab[44810]++;
//line /home/user/bug/fuzz.go:4
    timesN(b, 3) 
}

//line /home/user/bug/fuzz.go:7
//go:noescape
func times5(b []byte)

//line /home/user/bug/fuzz.go:10
func Fuzz(data []byte) int {
//line /home/user/bug/fuzz.go:10
	_go_fuzz_dep_.CoverTab[5262]++
							times3(data)
							times5(data)

							return 0
}

//line /home/user/bug/fuzz.go:15
var _ = _go_fuzz_dep_.CoverTab

armfazh avatar Sep 11 '19 22:09 armfazh

One quick workaround is to define times3 as:

func times3(b []byte) { 
    timesN(b, 3) 
}

The build completes successfully, but the parsing bug is still there.

armfazh avatar Sep 11 '19 22:09 armfazh

Wonder if it's go/ast bug and affects go tool cover too.

dvyukov avatar Sep 12 '19 07:09 dvyukov

Seems like a corner case go/ast or go/printer bug. Our could have to do with exactly how we insert the coverage statement. Needs investigation.

This doesn't affect go tool cover, since it doesn't use go/ast or go/printer any more. It uses plain text editing (internal package edit). I'd really like to use that for go-fuzz, but we lose handy //line printing. I've described the difficulties here at length somewhere in a go-fuzz issue, don't recall where now.

josharian avatar Sep 15 '19 23:09 josharian