Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link, runtime: libFuzzer mode fails in mixed C/Go binary #57449

Closed
cherrymui opened this issue Dec 23, 2022 · 2 comments
Closed

cmd/link, runtime: libFuzzer mode fails in mixed C/Go binary #57449

cherrymui opened this issue Dec 23, 2022 · 2 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge release-blocker
Milestone

Comments

@cherrymui
Copy link
Member

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.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Dec 23, 2022
@cherrymui cherrymui added this to the Go1.20 milestone Dec 23, 2022
@cherrymui cherrymui self-assigned this Dec 23, 2022
@gopherbot
Copy link

Change https://go.dev/cl/459055 mentions this issue: cmd/link, runtime: use a different section for Go libfuzzer counters

@cherrymui cherrymui changed the title cmd/link: libFuzzer mode fails in mixed C/Go binary cmd/link, runtime: libFuzzer mode fails in mixed C/Go binary Dec 23, 2022
@gopherbot
Copy link

Change https://go.dev/cl/459555 mentions this issue: misc/cgo/testsanitizers: add libfuzzer tests

gopherbot pushed a commit that referenced this issue Dec 27, 2022
Apparently we don't have tests for libfuzzer mode. Add some tests.

Updates #57449.

Change-Id: I813da3e71c6d6f15db31914b248db220b0b7041e
Reviewed-on: https://go-review.googlesource.com/c/go/+/459555
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
@golang golang locked and limited conversation to collaborators Dec 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge release-blocker
Projects
None yet
Development

No branches or pull requests

2 participants