Skip to content

Commit

Permalink
os: don't use pidfd on Android < 12
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cions committed Sep 5, 2024
1 parent 1b5ae45 commit af8e849
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 4 deletions.
5 changes: 3 additions & 2 deletions src/cmd/link/internal/ld/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"encoding/binary"
"fmt"
"internal/abi"
"internal/buildcfg"
"log"
"math/rand"
"os"
Expand Down Expand Up @@ -260,8 +261,8 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
}

// We need to be able to reference dynimport symbols when linking against
// shared libraries, and AIX, Darwin, OpenBSD and Solaris always need it.
if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
// shared libraries, and AIX, Darwin, OpenBSD, Android and Solaris always need it.
if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && buildcfg.GOOS != "android" && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
if !(target.IsPPC64() && target.IsExternal() && ldr.SymName(rs) == ".TOC.") {
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))
}
Expand Down
6 changes: 6 additions & 0 deletions src/os/pidfd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package os
import (
"errors"
"internal/syscall/unix"
"runtime"
"sync"
"syscall"
"unsafe"
Expand Down Expand Up @@ -147,6 +148,11 @@ var checkPidfdOnce = sync.OnceValue(checkPidfd)
// execution environment in which the above system calls are restricted by
// seccomp or a similar technology.
func checkPidfd() error {
// In Android version < 12, pidfd_open and pidfd_send_signal are not allowed by seccomp.
if runtime.GOOS == "android" && androidVersion() < 12 {
return NewSyscallError("pidfd_send_signal", syscall.ENOSYS)
}

// Get a pidfd of the current process (opening of "/proc/self" won't
// work for waitid).
fd, err := unix.PidFDOpen(syscall.Getpid(), 0)
Expand Down
10 changes: 10 additions & 0 deletions src/os/version_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import _ "unsafe" // for go:linkname

//go:linkname androidVersion runtime.androidVersion
func androidVersion() int
11 changes: 11 additions & 0 deletions src/os/version_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !android

package os

func androidVersion() int {
return 0
}
20 changes: 19 additions & 1 deletion src/runtime/os_android.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,25 @@

package runtime

import _ "unsafe" // for go:cgo_export_static and go:cgo_export_dynamic
import (
"unsafe"
)

//go:linkname androidVersion runtime.androidVersion
func androidVersion() int {
const PROP_VALUE_MAX = 92
var value [PROP_VALUE_MAX]byte
name := []byte("ro.build.version.release\x00")
length := __system_property_get(&name[0], &value[0])
for i := int32(0); i < length; i++ {
if value[i] < '0' || value[i] > '9' {
length = i
break
}
}
version, _ := atoi(unsafe.String(&value[0], length))
return version
}

// Export the main function.
//
Expand Down
28 changes: 28 additions & 0 deletions src/runtime/sys_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
"internal/abi"
"unsafe"
)

// The *_trampoline functions convert from the Go calling convention to the C calling convention
// and then call the underlying libc function. These are defined in sys_android_$ARCH.s.

//go:nosplit
//go:cgo_unsafe_args
func __system_property_get(name *byte, value *byte) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(__system_property_get_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
KeepAlive(value)
return ret
}
func __system_property_get_trampoline()

// Tell the linker that the libc_* functions are to be found
// in a system library, with the libc_ prefix missing.

//go:cgo_import_dynamic libc___system_property_get __system_property_get "libc.so"
27 changes: 27 additions & 0 deletions src/runtime/sys_android_386.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

// These trampolines help convert from Go calling convention to C calling convention.
// They should be called with asmcgocall - note that while asmcgocall does
// stack alignment, creation of a frame undoes it again.
// A pointer to the arguments is passed on the stack.
// A single int32 result is returned in AX.
// (For more results, make an args/results structure.)
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
PUSHL BP
MOVL SP, BP
SUBL $8, SP
MOVL 16(SP), DX // pointer to args
MOVL 0(DX), AX
MOVL 4(DX), DX
MOVL AX, 0(SP) // arg 1 - name
MOVL DX, 4(SP) // arg 2 - value
MOVL $_GLOBAL_OFFSET_TABLE_(SB), BX
CALL libc___system_property_get(SB)
MOVL BP, SP
POPL BP
RET
17 changes: 17 additions & 0 deletions src/runtime/sys_android_amd64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

// These trampolines help convert from Go calling convention to C calling convention.
// They should be called with asmcgocall.
// A pointer to the arguments is passed in DI.
// A single int32 result is returned in AX.
// (For more results, make an args/results structure.)
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
MOVQ 8(DI), SI // arg 2 - value
MOVQ 0(DI), DI // arg 1 - name
CALL libc___system_property_get(SB)
RET
21 changes: 21 additions & 0 deletions src/runtime/sys_android_arm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

// These trampolines help convert from Go calling convention to C calling convention.
// They should be called with asmcgocall - note that while asmcgocall does
// stack alignment, creation of a frame undoes it again.
// A pointer to the arguments is passed in R0.
// A single int32 result is returned in R0.
// (For more results, make an args/results structure.)
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
MOVW R13, R9
BIC $0x7, R13 // align for ELF ABI
MOVW 4(R0), R1 // arg 2 - value
MOVW 0(R0), R0 // arg 1 - name
CALL libc___system_property_get(SB)
MOVW R9, R13
RET
17 changes: 17 additions & 0 deletions src/runtime/sys_android_arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

// These trampolines help convert from Go calling convention to C calling convention.
// They should be called with asmcgocall.
// A pointer to the arguments is passed in R0.
// A single int32 result is returned in R0.
// (For more results, make an args/results structure.)
TEXT runtime·__system_property_get_trampoline(SB),NOSPLIT,$0
MOVD 8(R0), R1 // arg 2 - value
MOVD 0(R0), R0 // arg 1 - name
CALL libc___system_property_get(SB)
RET
2 changes: 1 addition & 1 deletion src/runtime/sys_libc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build darwin || (openbsd && !mips64)
//go:build darwin || (openbsd && !mips64) || android

package runtime

Expand Down

0 comments on commit af8e849

Please sign in to comment.