]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: mlock signal stack on macOS/ARM64
authorCherry Zhang <cherryyz@google.com>
Fri, 27 Nov 2020 05:42:41 +0000 (00:42 -0500)
committerCherry Zhang <cherryyz@google.com>
Mon, 30 Nov 2020 22:14:36 +0000 (22:14 +0000)
Apparently, the macOS ARM64 kernel has a bug where when a signal
arrives and the signal stack is not currently faulted in, it may
kill the program with a SIGILL. Work around it by mlock the
signal stacks.

Fixes #42774.

Change-Id: I99a4b3fdb6d8af1c945725ddc2c25568d81c510a
Reviewed-on: https://go-review.googlesource.com/c/go/+/273686
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/runtime/os_darwin.go
src/runtime/sys_darwin.go
src/runtime/sys_darwin_amd64.s
src/runtime/sys_darwin_arm64.s

index 3f5bb7cf9619ca6174611e242ffc8b50ec48ce05..52f3cd1fefb9cc77d066417fce33cec234b26a61 100644 (file)
@@ -283,6 +283,12 @@ func libpreinit() {
 func mpreinit(mp *m) {
        mp.gsignal = malg(32 * 1024) // OS X wants >= 8K
        mp.gsignal.m = mp
+       if GOOS == "darwin" && GOARCH == "arm64" {
+               // mlock the signal stack to work around a kernel bug where it may
+               // SIGILL when the signal stack is not faulted in while a signal
+               // arrives. See issue 42774.
+               mlock(unsafe.Pointer(mp.gsignal.stack.hi-physPageSize), physPageSize)
+       }
 }
 
 // Called to initialize a new m (including the bootstrap m).
index a7983be2eff29a462fe0f6846baf4772e3b4d767..c63ba8c6cd27c4b436afb80037d20628020aa22f 100644 (file)
@@ -226,6 +226,13 @@ func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
 }
 func madvise_trampoline()
 
+//go:nosplit
+//go:cgo_unsafe_args
+func mlock(addr unsafe.Pointer, n uintptr) {
+       libcCall(unsafe.Pointer(funcPC(mlock_trampoline)), unsafe.Pointer(&addr))
+}
+func mlock_trampoline()
+
 //go:nosplit
 //go:cgo_unsafe_args
 func read(fd int32, p unsafe.Pointer, n int32) int32 {
@@ -465,6 +472,7 @@ func setNonblock(fd int32) {
 //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
 
index 129e1e1a96def25ef543268a554582d3bbf22f1d..9b5b23901dcd9e16861279378668d380c4d09037 100644 (file)
@@ -105,6 +105,9 @@ TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
        POPQ    BP
        RET
 
+TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
+       UNDEF // unimplemented
+
 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
 
 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
index 88cdb281d4c1653774d1db52d28a07fd63d4d01b..9d4d116c507d091c9a2c4b3fd42eb4acee4b61de 100644 (file)
@@ -120,6 +120,12 @@ TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
        BL      libc_madvise(SB)
        RET
 
+TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
+       MOVD    8(R0), R1       // arg 2 len
+       MOVD    0(R0), R0       // arg 1 addr
+       BL      libc_mlock(SB)
+       RET
+
 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
        MOVD    8(R0), R1       // arg 2 new
        MOVD    16(R0), R2      // arg 3 old