diff options
author | Cherry Mui <cherryyz@google.com> | 2022-10-12 16:24:34 -0400 |
---|---|---|
committer | Cherry Mui <cherryyz@google.com> | 2022-10-13 18:47:30 +0000 |
commit | 9fe17a0340b1609355aa5ce1828a0cf39e0a8092 (patch) | |
tree | 73f366e6a5047c2d43cc0e71e3a81aeb3c8a465e /misc/cgo | |
parent | 36ca37f3a04aac4b67aa7fe3cfe480c891d0d53f (diff) | |
download | go-9fe17a0340b1609355aa5ce1828a0cf39e0a8092.tar.gz go-9fe17a0340b1609355aa5ce1828a0cf39e0a8092.zip |
cmd/link: don't reset variable size when handling -X flag
The linker's -X flag allows setting/changing a string variable's
content at link time. Currently it resets its size then write a
new string header pointing to the new content. This mostly works.
But under ASAN build the string variable can have larger size
than the usual 2 words, due to the red zone. Resetting the size
can cause the variable to "overlap" (in ASAN's view) with other
variables. Don't reset the size.
Fixes #56175.
Change-Id: Ib364208201a7a2fd7f44f9b1797834198736a405
Reviewed-on: https://go-review.googlesource.com/c/go/+/442635
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'misc/cgo')
-rw-r--r-- | misc/cgo/testsanitizers/asan_test.go | 42 | ||||
-rw-r--r-- | misc/cgo/testsanitizers/testdata/asan_linkerx/main.go | 28 | ||||
-rw-r--r-- | misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go | 12 |
3 files changed, 82 insertions, 0 deletions
diff --git a/misc/cgo/testsanitizers/asan_test.go b/misc/cgo/testsanitizers/asan_test.go index 67d097cf16..932cfb1b60 100644 --- a/misc/cgo/testsanitizers/asan_test.go +++ b/misc/cgo/testsanitizers/asan_test.go @@ -5,6 +5,7 @@ package sanitizers_test import ( + "fmt" "strings" "testing" ) @@ -97,3 +98,44 @@ func TestASAN(t *testing.T) { }) } } + +func TestASANLinkerX(t *testing.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 !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) + } + + t.Parallel() + requireOvercommit(t) + config := configure("address") + config.skipIfCSanitizerBroken(t) + + dir := newTempDir(t) + defer dir.RemoveAll(t) + + var ldflags string + for i := 1; i <= 10; i++ { + ldflags += fmt.Sprintf("-X=main.S%d=%d -X=misc/cgo/testsanitizers/testdata/asan_linkerx/p.S%d=%d ", i, i, i, i) + } + + // build the binary + outPath := dir.Join("main.exe") + cmd := config.goCmd("build", "-ldflags="+ldflags, "-o", outPath) + cmd.Dir = srcPath("asan_linkerx") + mustRun(t, cmd) + + // run the binary + mustRun(t, hangProneCmd(outPath)) +} diff --git a/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go b/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go new file mode 100644 index 0000000000..bbd6127d90 --- /dev/null +++ b/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go @@ -0,0 +1,28 @@ +package main + +import "misc/cgo/testsanitizers/testdata/asan_linkerx/p" + +func pstring(s *string) { + println(*s) +} + +func main() { + all := []*string{ + &S1, &S2, &S3, &S4, &S5, &S6, &S7, &S8, &S9, &S10, + &p.S1, &p.S2, &p.S3, &p.S4, &p.S5, &p.S6, &p.S7, &p.S8, &p.S9, &p.S10, + } + for _, ps := range all { + pstring(ps) + } +} + +var S1 string +var S2 string +var S3 string +var S4 string +var S5 string +var S6 string +var S7 string +var S8 string +var S9 string +var S10 string diff --git a/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go b/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go new file mode 100644 index 0000000000..c31f00109d --- /dev/null +++ b/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go @@ -0,0 +1,12 @@ +package p + +var S1 string +var S2 string +var S3 string +var S4 string +var S5 string +var S6 string +var S7 string +var S8 string +var S9 string +var S10 string |