mirror of
https://github.com/golang/go
synced 2024-11-14 20:00:31 -07:00
cmd/link: for asan align coverage counter section to 8 bytes
Fixes #66966 Change-Id: I92777a7d7d8afaa82ffcd605aa3e607289b645f1 Reviewed-on: https://go-review.googlesource.com/c/go/+/622477 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
46b576be72
commit
6dc99aa7eb
@ -7,6 +7,7 @@
|
||||
package sanitizers_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"internal/platform"
|
||||
"internal/testenv"
|
||||
@ -15,34 +16,9 @@ import (
|
||||
)
|
||||
|
||||
func TestASAN(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
testenv.MustHaveCGO(t)
|
||||
goos, err := goEnv("GOOS")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
goarch, err := goEnv("GOARCH")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The asan tests require support for the -asan option.
|
||||
if !platform.ASanSupported(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
|
||||
}
|
||||
// The current implementation is only compatible with the ASan library from version
|
||||
// v7 to v9 (See the description in src/runtime/asan/asan.go). Therefore, using the
|
||||
// -asan option must use a compatible version of ASan library, which requires that
|
||||
// the gcc version is not less than 7 and the clang version is not less than 9,
|
||||
// otherwise a segmentation fault will occur.
|
||||
if !compilerRequiredAsanVersion(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s: too old version of compiler", goos, goarch)
|
||||
}
|
||||
config := mustHaveASAN(t)
|
||||
|
||||
t.Parallel()
|
||||
requireOvercommit(t)
|
||||
config := configure("address")
|
||||
config.skipIfCSanitizerBroken(t)
|
||||
|
||||
mustRun(t, config.goCmd("build", "std"))
|
||||
|
||||
cases := []struct {
|
||||
@ -106,29 +82,10 @@ func TestASAN(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestASANLinkerX(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
testenv.MustHaveCGO(t)
|
||||
// Test ASAN with linker's -X flag (see issue 56175).
|
||||
goos, err := goEnv("GOOS")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
goarch, err := goEnv("GOARCH")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The asan tests require support for the -asan option.
|
||||
if !platform.ASanSupported(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
|
||||
}
|
||||
if !compilerRequiredAsanVersion(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s: too old version of compiler", goos, goarch)
|
||||
}
|
||||
config := mustHaveASAN(t)
|
||||
|
||||
t.Parallel()
|
||||
requireOvercommit(t)
|
||||
config := configure("address")
|
||||
config.skipIfCSanitizerBroken(t)
|
||||
|
||||
dir := newTempDir(t)
|
||||
defer dir.RemoveAll(t)
|
||||
@ -147,3 +104,56 @@ func TestASANLinkerX(t *testing.T) {
|
||||
// run the binary
|
||||
mustRun(t, hangProneCmd(outPath))
|
||||
}
|
||||
|
||||
// Issue 66966.
|
||||
func TestASANFuzz(t *testing.T) {
|
||||
config := mustHaveASAN(t)
|
||||
|
||||
t.Parallel()
|
||||
|
||||
dir := newTempDir(t)
|
||||
defer dir.RemoveAll(t)
|
||||
|
||||
cmd := config.goCmd("test", "-fuzz=Fuzz", srcPath("asan_fuzz_test.go"))
|
||||
t.Logf("%v", cmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
t.Logf("%s", out)
|
||||
if err == nil {
|
||||
t.Error("expected fuzzing failure")
|
||||
}
|
||||
if bytes.Contains(out, []byte("AddressSanitizer")) {
|
||||
t.Error(`output contains "AddressSanitizer", but should not`)
|
||||
}
|
||||
}
|
||||
|
||||
func mustHaveASAN(t *testing.T) *config {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
testenv.MustHaveCGO(t)
|
||||
goos, err := goEnv("GOOS")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
goarch, err := goEnv("GOARCH")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !platform.ASanSupported(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
|
||||
}
|
||||
|
||||
// The current implementation is only compatible with the ASan library from version
|
||||
// v7 to v9 (See the description in src/runtime/asan/asan.go). Therefore, using the
|
||||
// -asan option must use a compatible version of ASan library, which requires that
|
||||
// the gcc version is not less than 7 and the clang version is not less than 9,
|
||||
// otherwise a segmentation fault will occur.
|
||||
if !compilerRequiredAsanVersion(goos, goarch) {
|
||||
t.Skipf("skipping on %s/%s: too old version of compiler", goos, goarch)
|
||||
}
|
||||
|
||||
requireOvercommit(t)
|
||||
|
||||
config := configure("address")
|
||||
config.skipIfCSanitizerBroken(t)
|
||||
|
||||
return config
|
||||
}
|
||||
|
30
src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go
vendored
Normal file
30
src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Reverse(s string) string {
|
||||
runes := []rune(s)
|
||||
slices.Reverse(runes)
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// This fuzz test should quickly fail, because Reverse doesn't
|
||||
// work for strings that are not valid UTF-8.
|
||||
// What we are testing for is whether we see a failure from ASAN;
|
||||
// we should see a fuzzing failure, not an ASAN failure.
|
||||
|
||||
func FuzzReverse(f *testing.F) {
|
||||
f.Add("Go")
|
||||
f.Add("Gopher")
|
||||
f.Add("Hello, 世界")
|
||||
f.Fuzz(func(t *testing.T, s string) {
|
||||
r1 := Reverse(s)
|
||||
r2 := Reverse(r1)
|
||||
if s != r2 {
|
||||
t.Errorf("got %q want %q", r2, s)
|
||||
}
|
||||
})
|
||||
}
|
@ -2981,6 +2981,12 @@ func (ctxt *Link) address() []*sym.Segment {
|
||||
ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
|
||||
|
||||
if fuzzCounters != nil {
|
||||
if *flagAsan {
|
||||
// ASAN requires that the symbol marking the end
|
||||
// of the section be aligned on an 8 byte boundary.
|
||||
// See issue #66966.
|
||||
fuzzCounters.Length = uint64(Rnd(int64(fuzzCounters.Length), 8))
|
||||
}
|
||||
ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
|
||||
ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
|
||||
ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
|
||||
|
Loading…
Reference in New Issue
Block a user