1
0
mirror of https://github.com/golang/go synced 2024-11-22 23:50:03 -07:00

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 <emmanuel@orijtech.com>
Trust: Fannie Zhang <Fannie.Zhang@arm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
fanzha02 2021-12-30 11:09:42 +08:00 committed by Fannie Zhang
parent 301db3f5d2
commit 2c58bb2e42
3 changed files with 26 additions and 0 deletions

View File

@ -39,6 +39,7 @@ func TestASAN(t *testing.T) {
{src: "asan2_fail.go", memoryAccessError: "heap-buffer-overflow", errorLocation: "asan2_fail.go:31"}, {src: "asan2_fail.go", memoryAccessError: "heap-buffer-overflow", errorLocation: "asan2_fail.go:31"},
{src: "asan3_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan3_fail.go:13"}, {src: "asan3_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan3_fail.go:13"},
{src: "asan4_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan4_fail.go:13"}, {src: "asan4_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan4_fail.go:13"},
{src: "asan5_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan5_fail.go:18"},
{src: "asan_useAfterReturn.go"}, {src: "asan_useAfterReturn.go"},
} }
for _, tc := range cases { for _, tc := range cases {

View File

@ -0,0 +1,21 @@
package main
import (
"fmt"
"runtime"
"unsafe"
)
func main() {
p := new([1024 * 1000]int)
p[0] = 10
r := bar(&p[1024*1000-1])
fmt.Printf("r value is %d", r)
}
func bar(a *int) int {
p := unsafe.Add(unsafe.Pointer(a), 2*unsafe.Sizeof(int(1)))
runtime.ASanWrite(p, 8) // BOOM
*((*int)(p)) = 10
return *((*int)(p))
}

View File

@ -26,12 +26,16 @@ func ASanWrite(addr unsafe.Pointer, len int) {
// Private interface for the runtime. // Private interface for the runtime.
const asanenabled = true const asanenabled = true
// Mark asan(read, write) as NOSPLIT, because they may run
// on stacks that cannot grow. See issue #50391.
//go:nosplit
func asanread(addr unsafe.Pointer, sz uintptr) { func asanread(addr unsafe.Pointer, sz uintptr) {
sp := getcallersp() sp := getcallersp()
pc := getcallerpc() pc := getcallerpc()
doasanread(addr, sz, sp, pc) doasanread(addr, sz, sp, pc)
} }
//go:nosplit
func asanwrite(addr unsafe.Pointer, sz uintptr) { func asanwrite(addr unsafe.Pointer, sz uintptr) {
sp := getcallersp() sp := getcallersp()
pc := getcallerpc() pc := getcallerpc()