Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os: don't use pidfd on Android < 12 #69245

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
49 changes: 49 additions & 0 deletions src/internal/syscall/unix/version_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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 unix

import (
"internal/abi"
"runtime"
"strconv"
"unsafe"
)

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, _ := strconv.Atoi(unsafe.String(&value[0], length))
return version
}

// 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))
runtime.KeepAlive(name)
runtime.KeepAlive(value)
return ret
}
func __system_property_get_trampoline()

//go:linkname libcCall runtime.libcCall
//go:noescape
func libcCall(fn, arg unsafe.Pointer) int32

// 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/internal/syscall/unix/version_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 ·__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/internal/syscall/unix/version_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 ·__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/internal/syscall/unix/version_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 ·__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/internal/syscall/unix/version_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 ·__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
11 changes: 11 additions & 0 deletions src/internal/syscall/unix/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 unix

func AndroidVersion() int {
return 0
}
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" && unix.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
5 changes: 4 additions & 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 All @@ -13,7 +13,10 @@ import "unsafe"
// Switches to the system stack, if not already there.
// Preserves the calling point as the location where a profiler traceback will begin.
//
// used by internal/syscall/unix via linkname
//
//go:nosplit
//go:linkname libcCall runtime.libcCall
func libcCall(fn, arg unsafe.Pointer) int32 {
// Leave caller's PC/SP/G around for traceback.
gp := getg()
Expand Down