Skip to content

Commit 9563300

Browse files
cionsgopherbot
authored andcommitted
[release-branch.go1.23] os: ignore SIGSYS in checkPidfd
In Android version 11 and earlier, pidfd-related system calls are not allowed by the seccomp policy, which causes crashes due to SIGSYS signals. For #69065 Fixes #69640 Change-Id: Ib29631639a5cf221ac11b4d82390cb79436b8657 GitHub-Last-Rev: aad6b3b GitHub-Pull-Request: #69543 Reviewed-on: https://go-review.googlesource.com/c/go/+/614277 Auto-Submit: Ian Lance Taylor <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> (cherry picked from commit a3a05ed) Reviewed-on: https://go-review.googlesource.com/c/go/+/616077 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Kirill Kolyshkin <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Mauri de Souza Meneguzzo <[email protected]> Auto-Submit: Michael Knyszek <[email protected]>
1 parent f8080ed commit 9563300

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

src/os/pidfd_linux.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package os
1414
import (
1515
"errors"
1616
"internal/syscall/unix"
17+
"runtime"
1718
"sync"
1819
"syscall"
1920
"unsafe"
@@ -147,6 +148,13 @@ var checkPidfdOnce = sync.OnceValue(checkPidfd)
147148
// execution environment in which the above system calls are restricted by
148149
// seccomp or a similar technology.
149150
func checkPidfd() error {
151+
// In Android version < 12, pidfd-related system calls are not allowed
152+
// by seccomp and trigger the SIGSYS signal. See issue #69065.
153+
if runtime.GOOS == "android" {
154+
ignoreSIGSYS()
155+
defer restoreSIGSYS()
156+
}
157+
150158
// Get a pidfd of the current process (opening of "/proc/self" won't
151159
// work for waitid).
152160
fd, err := unix.PidFDOpen(syscall.Getpid(), 0)
@@ -174,3 +182,11 @@ func checkPidfd() error {
174182

175183
return nil
176184
}
185+
186+
// Provided by runtime.
187+
//
188+
//go:linkname ignoreSIGSYS
189+
func ignoreSIGSYS()
190+
191+
//go:linkname restoreSIGSYS
192+
func restoreSIGSYS()

src/runtime/os_linux.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -879,8 +879,9 @@ func runPerThreadSyscall() {
879879
}
880880

881881
const (
882-
_SI_USER = 0
883-
_SI_TKILL = -6
882+
_SI_USER = 0
883+
_SI_TKILL = -6
884+
_SYS_SECCOMP = 1
884885
)
885886

886887
// sigFromUser reports whether the signal was sent because of a call
@@ -892,6 +893,14 @@ func (c *sigctxt) sigFromUser() bool {
892893
return code == _SI_USER || code == _SI_TKILL
893894
}
894895

896+
// sigFromSeccomp reports whether the signal was sent from seccomp.
897+
//
898+
//go:nosplit
899+
func (c *sigctxt) sigFromSeccomp() bool {
900+
code := int32(c.sigcode())
901+
return code == _SYS_SECCOMP
902+
}
903+
895904
//go:nosplit
896905
func mprotect(addr unsafe.Pointer, n uintptr, prot int32) (ret int32, errno int32) {
897906
r, _, err := syscall.Syscall6(syscall.SYS_MPROTECT, uintptr(addr), n, uintptr(prot), 0, 0, 0)

src/runtime/os_unix_nonlinux.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ package runtime
1313
func (c *sigctxt) sigFromUser() bool {
1414
return c.sigcode() == _SI_USER
1515
}
16+
17+
// sigFromSeccomp reports whether the signal was sent from seccomp.
18+
//
19+
//go:nosplit
20+
func (c *sigctxt) sigFromSeccomp() bool {
21+
return false
22+
}

src/runtime/signal_unix.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,19 @@ var crashing atomic.Int32
605605
var testSigtrap func(info *siginfo, ctxt *sigctxt, gp *g) bool
606606
var testSigusr1 func(gp *g) bool
607607

608+
// sigsysIgnored is non-zero if we are currently ignoring SIGSYS. See issue #69065.
609+
var sigsysIgnored uint32
610+
611+
//go:linkname ignoreSIGSYS os.ignoreSIGSYS
612+
func ignoreSIGSYS() {
613+
atomic.Store(&sigsysIgnored, 1)
614+
}
615+
616+
//go:linkname restoreSIGSYS os.restoreSIGSYS
617+
func restoreSIGSYS() {
618+
atomic.Store(&sigsysIgnored, 0)
619+
}
620+
608621
// sighandler is invoked when a signal occurs. The global g will be
609622
// set to a gsignal goroutine and we will be running on the alternate
610623
// signal stack. The parameter gp will be the value of the global g
@@ -715,6 +728,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
715728
return
716729
}
717730

731+
if sig == _SIGSYS && c.sigFromSeccomp() && atomic.Load(&sigsysIgnored) != 0 {
732+
return
733+
}
734+
718735
if flags&_SigKill != 0 {
719736
dieFromSignal(sig)
720737
}

0 commit comments

Comments
 (0)