Skip to content

Commit fa64710

Browse files
committed
os: don't use pidfd on Android < 12
In Android version 11 and earlier, pidfd-related system calls are not allowed by the seccomp policy, which causes crashes due to SIGSYS signals. Fixes #69065
1 parent 1b5ae45 commit fa64710

11 files changed

+154
-4
lines changed

src/cmd/link/internal/ld/data.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"encoding/binary"
4545
"fmt"
4646
"internal/abi"
47+
"internal/buildcfg"
4748
"log"
4849
"math/rand"
4950
"os"
@@ -260,8 +261,8 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
260261
}
261262

262263
// We need to be able to reference dynimport symbols when linking against
263-
// shared libraries, and AIX, Darwin, OpenBSD and Solaris always need it.
264-
if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
264+
// shared libraries, and AIX, Darwin, OpenBSD, Android and Solaris always need it.
265+
if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && buildcfg.GOOS != "android" && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
265266
if !(target.IsPPC64() && target.IsExternal() && ldr.SymName(rs) == ".TOC.") {
266267
st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
267268
}

src/os/pidfd_linux.go

+6
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,11 @@ 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_open and pidfd_send_signal are not allowed by seccomp.
152+
if runtime.GOOS == "android" && androidVersion() < 12 {
153+
return NewSyscallError("pidfd_send_signal", syscall.ENOSYS)
154+
}
155+
150156
// Get a pidfd of the current process (opening of "/proc/self" won't
151157
// work for waitid).
152158
fd, err := unix.PidFDOpen(syscall.Getpid(), 0)

src/os/version_android.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package os
6+
7+
import _ "unsafe" // for go:linkname
8+
9+
//go:linkname androidVersion runtime.androidVersion
10+
func androidVersion() int

src/os/version_other.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !android
6+
7+
package os
8+
9+
func androidVersion() int {
10+
return 0
11+
}

src/runtime/os_android.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@
44

55
package runtime
66

7-
import _ "unsafe" // for go:cgo_export_static and go:cgo_export_dynamic
7+
import (
8+
"unsafe"
9+
)
10+
11+
//go:linkname androidVersion runtime.androidVersion
12+
func androidVersion() int {
13+
const PROP_VALUE_MAX = 92
14+
var value [PROP_VALUE_MAX]byte
15+
name := []byte("ro.build.version.release\x00")
16+
length := __system_property_get(&name[0], &value[0])
17+
version, _ := atoi(unsafe.String(&value[0], length))
18+
return version
19+
}
820

921
// Export the main function.
1022
//

src/runtime/sys_android.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package runtime
6+
7+
import (
8+
"internal/abi"
9+
"unsafe"
10+
)
11+
12+
// The *_trampoline functions convert from the Go calling convention to the C calling convention
13+
// and then call the underlying libc function. These are defined in sys_android_$ARCH.s.
14+
15+
//go:nosplit
16+
//go:cgo_unsafe_args
17+
func __system_property_get(name *byte, value *byte) int32 {
18+
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(__system_property_get_trampoline)), unsafe.Pointer(&name))
19+
KeepAlive(name)
20+
KeepAlive(value)
21+
return ret
22+
}
23+
func __system_property_get_trampoline()
24+
25+
// Tell the linker that the libc_* functions are to be found
26+
// in a system library, with the libc_ prefix missing.
27+
28+
//go:cgo_import_dynamic libc___system_property_get __system_property_get "libc.so"

src/runtime/sys_android_386.s

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
#include "go_asm.h"
6+
#include "textflag.h"
7+
8+
// These trampolines help convert from Go calling convention to C calling convention.
9+
// They should be called with asmcgocall - note that while asmcgocall does
10+
// stack alignment, creation of a frame undoes it again.
11+
// A pointer to the arguments is passed on the stack.
12+
// A single int32 result is returned in AX.
13+
// (For more results, make an args/results structure.)
14+
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
15+
PUSHL BP
16+
MOVL SP, BP
17+
SUBL $8, SP
18+
MOVL 16(SP), DX // pointer to args
19+
MOVL 0(DX), AX
20+
MOVL 4(DX), DX
21+
MOVL AX, 0(SP) // arg 1 - name
22+
MOVL DX, 4(SP) // arg 2 - value
23+
MOVL $_GLOBAL_OFFSET_TABLE_(SB), BX
24+
CALL libc___system_property_get(SB)
25+
MOVL BP, SP
26+
POPL BP
27+
RET

src/runtime/sys_android_amd64.s

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
#include "go_asm.h"
6+
#include "textflag.h"
7+
8+
// These trampolines help convert from Go calling convention to C calling convention.
9+
// They should be called with asmcgocall.
10+
// A pointer to the arguments is passed in DI.
11+
// A single int32 result is returned in AX.
12+
// (For more results, make an args/results structure.)
13+
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
14+
MOVQ 8(DI), SI // arg 2 - value
15+
MOVQ 0(DI), DI // arg 1 - name
16+
CALL libc___system_property_get(SB)
17+
RET

src/runtime/sys_android_arm.s

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
#include "go_asm.h"
6+
#include "textflag.h"
7+
8+
// These trampolines help convert from Go calling convention to C calling convention.
9+
// They should be called with asmcgocall - note that while asmcgocall does
10+
// stack alignment, creation of a frame undoes it again.
11+
// A pointer to the arguments is passed in R0.
12+
// A single int32 result is returned in R0.
13+
// (For more results, make an args/results structure.)
14+
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
15+
MOVW R13, R9
16+
BIC $0x7, R13 // align for ELF ABI
17+
MOVW 4(R0), R1 // arg 2 - value
18+
MOVW 0(R0), R0 // arg 1 - name
19+
CALL libc___system_property_get(SB)
20+
MOVW R9, R13
21+
RET

src/runtime/sys_android_arm64.s

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
#include "go_asm.h"
6+
#include "textflag.h"
7+
8+
// These trampolines help convert from Go calling convention to C calling convention.
9+
// They should be called with asmcgocall.
10+
// A pointer to the arguments is passed in R0.
11+
// A single int32 result is returned in R0.
12+
// (For more results, make an args/results structure.)
13+
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
14+
MOVD 8(R0), R1 // arg 2 - value
15+
MOVD 0(R0), R0 // arg 1 - name
16+
CALL libc___system_property_get(SB)
17+
RET

src/runtime/sys_libc.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build darwin || (openbsd && !mips64)
5+
//go:build darwin || (openbsd && !mips64) || android
66

77
package runtime
88

0 commit comments

Comments
 (0)