psx

package module
v1.2.76 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2025 License: GPL-2.0 Imports: 4 Imported by: 9

README

PSX

The Linux specific Go package, "kernel.org/pub/linux/libs/security/libcap/psx", provides an API for invoking system calls in a way that each system call is mirrored on all OS threads of the combined Go/CGo runtime. Since the Go runtime treats OS threads as interchangeable, a feature like this is needed to meaningfully change process privilege (including dropping privilege) in a Go program running on Linux. This package is required by:

  • "kernel.org/pub/linux/libs/security/libcap/cap"

When compiled CGO_ENABLED=0, the functionality requires go1.16+ to build. That release of Go introduced syscall.AllThreadsSyscall*() APIs. When compiled this way, the PSX package functions psx.Syscall3() and psx.Syscall6() are aliased to syscall.AllThreadsSyscall() and syscall.AllThreadsSyscall6() respectively.

When compiled CGO_ENABLED=1, the functionality is implemented by C code, [lib]psx, which is distributed with libcap.

The official release announcements for libcap and libpsx are on the Fully Capable site.

Like libcap/libpsx, the "psx" package is distributed with a "you choose" License. Specifically: BSD 3-clause, or GPL2. See the License file.

Andrew G. Morgan morgan@kernel.org

Documentation

Overview

Package psx provides support for system calls that are run simultaneously on all threads under Linux. It supports tool chains after go1.16. Earlier toolchains had no reliable way to support this because of Bug 219478.

The package works differently depending on whether or not CGO_ENABLED is 0 or 1.

In the former case, psx is a low overhead wrapper for the two native go calls: syscall.AllThreadsSyscall() and syscall.AllThreadsSyscall6() introduced in go1.16. We provide this package wrapping to minimize client source code changes when compiling with or without CGo enabled.

In the latter case it works via CGo wrappers for system call functions that call the C [lib]psx functions of these names. This ensures that the system calls execute simultaneously on all the threads of the Go (and CGo) combined runtime.

With CGo, the psx support works in the following way: the thread that is first asked to execute the syscall does so, and determines if it succeeds or fails. If it fails, it returns immediately without attempting the syscall on other threads. If the initial attempt succeeds, however, then the runtime is stopped in order for the same system call to be performed on all the remaining threads of the runtime. Once all threads have completed the syscall, the return codes are those obtained by the first thread's invocation of the syscall.

Note, there is no need to use this variant of syscall where the syscalls only read state from the kernel. However, since Go's runtime freely migrates code execution between threads, support of this type is required for any successful attempt to fully drop or modify the privilege of a running Go program under Linux.

More info on how Linux privilege works and examples of using this package can be found on the Fully Capable site.

WARNING: For older go toolchains (prior to go1.16), the code should mostly work as far back as go1.11. However, like support for C.setuid(), this support is fragile and may hang. See the above bug for details.

Copyright (c) 2019,20,24 Andrew G. Morgan <morgan@kernel.org>

The psx package is licensed with a (you choose) BSD 3-clause or GPL2. See LICENSE file for details.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Syscall3

func Syscall3(syscallnr, arg1, arg2, arg3 uintptr) (uintptr, uintptr, syscall.Errno)

Syscall3 performs a 3 argument syscall. Syscall3 differs from syscall.[Raw]Syscall() insofar as it is simultaneously executed on every thread of the combined Go and CGo runtimes. If any of the return values of these sumultaneous system calls differs, the runtime will cause the program to exit.

Syscall3 works differently depending on whether CGO_ENABLED is 1 or 0 at compile time.

If CGO_ENABLED=1 it uses the libpsx function C.psx_syscall3(), with libpsx:psx_set_sensitivity(PSX_ERROR) - which means the program will be signo=33 killed when inconsistent return values are returned for any pthread.

If CGO_ENABLED=0 it redirects to the go1.16+ syscall.AllThreadsSyscall() function. This function panics if inconsistent return values are returned for any pthread.

func Syscall6

func Syscall6(syscallnr, arg1, arg2, arg3, arg4, arg5, arg6 uintptr) (uintptr, uintptr, syscall.Errno)

Syscall6 performs a 6 argument syscall on every thread of the combined Go and CGo runtimes. Other than the number of syscall arguments, its behavior is identical to that of Syscall3() - see above for the full documentation.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL