Skip to content

Commit 2c58bb2

Browse files
committed
src/runtime: mark asanread and asanwrite functions as NOSPLIT
The asan runtime functions may run on stacks that cannot grow, and they do not have large local variables, so it is safe to mark them as NOSPLIT. Add test case. Fixes #50391 Change-Id: Iadcbf1ae0c837d9b64da5be208c7f424e6ba11de Reviewed-on: https://go-review.googlesource.com/c/go/+/374398 Trust: Emmanuel Odeke <[email protected]> Trust: Fannie Zhang <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 301db3f commit 2c58bb2

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

misc/cgo/testsanitizers/asan_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func TestASAN(t *testing.T) {
3939
{src: "asan2_fail.go", memoryAccessError: "heap-buffer-overflow", errorLocation: "asan2_fail.go:31"},
4040
{src: "asan3_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan3_fail.go:13"},
4141
{src: "asan4_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan4_fail.go:13"},
42+
{src: "asan5_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan5_fail.go:18"},
4243
{src: "asan_useAfterReturn.go"},
4344
}
4445
for _, tc := range cases {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
"unsafe"
7+
)
8+
9+
func main() {
10+
p := new([1024 * 1000]int)
11+
p[0] = 10
12+
r := bar(&p[1024*1000-1])
13+
fmt.Printf("r value is %d", r)
14+
}
15+
16+
func bar(a *int) int {
17+
p := unsafe.Add(unsafe.Pointer(a), 2*unsafe.Sizeof(int(1)))
18+
runtime.ASanWrite(p, 8) // BOOM
19+
*((*int)(p)) = 10
20+
return *((*int)(p))
21+
}

src/runtime/asan.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ func ASanWrite(addr unsafe.Pointer, len int) {
2626
// Private interface for the runtime.
2727
const asanenabled = true
2828

29+
// Mark asan(read, write) as NOSPLIT, because they may run
30+
// on stacks that cannot grow. See issue #50391.
31+
//go:nosplit
2932
func asanread(addr unsafe.Pointer, sz uintptr) {
3033
sp := getcallersp()
3134
pc := getcallerpc()
3235
doasanread(addr, sz, sp, pc)
3336
}
3437

38+
//go:nosplit
3539
func asanwrite(addr unsafe.Pointer, sz uintptr) {
3640
sp := getcallersp()
3741
pc := getcallerpc()

0 commit comments

Comments
 (0)