Closed
Description
What version of Go are you using (go version
)?
tip (c61d322)
Does this issue reproduce with the latest release?
No
What operating system and processor architecture are you using (go env
)?
linux/amd64
What did you do?
Fuzz a mixed C/Go binary using libFuzzer mode. Both C and Go are instrumented.
f.go
package main
import "C"
import "unsafe"
//export FuzzMe
func FuzzMe(p unsafe.Pointer, sz C.int) {
b := C.GoBytes(p, sz)
b = b[3:]
if len(b) >= 4 && b[0] == 'f' && b[1] == 'u' && b[2] == 'z' && b[3] == 'z' {
panic("found it")
}
}
func main() {}
f.c
#include <stddef.h>
#include "f.h"
int LLVMFuzzerTestOneInput(char *data, size_t size) {
if (size > 0 && data[0] == 'H')
if (size > 1 && data[1] == 'I')
if (size > 2 && data[2] == '!')
FuzzMe(data, size);
return 0;
}
$ go build -buildmode=c-archive -tags=libfuzzer -gcflags=-d=libfuzzer f.go
$ clang -fsanitize=fuzzer -fuse-ld=lld f.c f.a
$ ./a.out
What did you expect to see?
Fuzzing successfully. panic: found it
after a short amount of time.
What did you see instead?
$ ./a.out
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 600643822
INFO: Loaded 2 modules (28 inline 8-bit counters): 18 [0x55f97a904470, 0x55f97a904482), 10 [0x55f97a904478, 0x55f97a904482),
INFO: Loaded 2 PC tables (18 PCs): 8 [0x55f97a904488,0x55f97a904508), 10 [0xc00005e000,0xc00005e0a0),
ERROR: The size of coverage PC tables does not match the
number of instrumented PCs. This might be a compiler bug,
please contact the libFuzzer developers.
This works for Go 1.19, but fails at tip when we switched to use 8-bit counters.
In this case, C part has 8 counters, Go has 10, so there are 18 counters, matching the 18 PCs. But somehow the Go counters are registered twice. This is because currently we put the Go counters in section __sancov_cntrs
(same as the C counters) and the C linker combines them and registers them together. But the Go runtime also registers the Go counters, causing them to be registered twice.
I'll send a CL to fix.