LIBPSX(3)

πŸ“¦
version 2.78 Β· 2 versions
  • 2.78 Β· alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 2.69 Β· centos-stream 10
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– LIBPSX(3) πŸ’– β€” the Linux Programmer's Manual, but make it a group chat

okay bestie, listen. this is libpsx, from the Linux Programmer's Manual, and it's genuinely one of those "wait, why does this need to exist" stories that turns out to be so satisfying once it clicks. sit down, hydrate, let's go 🫢


✨ NAME ✨

psx_syscall3, psx_syscall6, psx_set_sensitivity β€” POSIX semantics for system calls. that's the whole vibe. giving you system calls that behave POSIX-ly across all your threads πŸ’…


πŸŽ€ SYNOPSIS πŸŽ€

#include <sys/psx_syscall.h>

long int psx_syscall3(long int syscall_nr,
                      long int arg1, long int arg2, long int arg3);
long int psx_syscall6(long int syscall_nr,
                      long int arg1, long int arg2, long int arg3,
                      long int arg4, long int arg5, long int arg6);
int psx_set_sensitivity(psx_sensitivity_t sensitivity);
void psx_load_syscalls(long int (**syscall_fn)(long int,
                                    long int, long int, long int),
                       long int (**syscall6_fn)(long int,
                                    long int, long int, long int,
                                    long int, long int, long int));

and like, any code that uses one of the functions above? you link it like this, no cap:

ld ... -lpsx -lpthread
gcc ... -lpsx -lpthread
heads up bestie 🫢 you need special flags to get -lcap to operate with process-wide capabilities when it's linked with -lpsx. specifically, use the pkg-config option file: gcc ... -lcap $(pkg-config --libs --cflags libpsx). more details live in the cap_get_proc(3) man page, go peek πŸ‘€

🌸 DESCRIPTION 🌸

so here's the tea. 🍡

The libpsx library attempts to fill a gap left by the pthreads(7) implementation on Linux. To be compliant POSIX threads, via the nptl(7) setxid mechanism, glibc maintains consistent UID and GID credentials amongst all of the threads associated with the current process. however β€” and this is the plot twist β€” other credential state is not supported by this abstraction.

to support these extended kernel managed security attributes, libpsx provides a more generic pair of wrapping system call functions: psx_syscall3() and psx_syscall6(). iconic behaviour, honestly.

like the setxid mechanism, the coordination of thread state is mediated by a realtime signal. whereas the nptl:setxid mechanism uses signo=33 (which is hidden by glibc below a redefined SIGRTMIN), libpsx inserts itself in the SIGSYS handler stack. it goes to great length to be the first such handler, but acts as a pass-through for other SIGSYS uses. main character energy but polite about it ✨


okay so about the macrology trick. there's an inefficient macrology trick that supports the psx_syscall() pseudo function, which takes 1 to 7 arguments, depending on the needs of the caller. the macrology (which ultimately invokes __psx_syscall()) pads out the call to actually use psx_syscall3() or psx_syscall6() with zeros filling the missing arguments. while using this in source code will make it appear clean, the actual code footprint is larger. so you are encouraged to use the more explicit psx_syscall3() and psx_syscall6() functions as needed. slay responsibly πŸ’…


psx_set_sensitivity() changes the behavior of the mirrored system calls:

  • PSX_IGNORE β€” ensures that differences are ignored (this is the default behavior, btw)
  • PSX_WARNING β€” prints a stderr notification about how the results differ
  • PSX_ERROR β€” prints the error details and generates a SIGSYS signal πŸ’€

psx_load_syscalls() can be used to set caller defined function pointers for invoking 3 and 6 argument syscalls. this function can be used to configure a library, or program to change behavior when linked against libpsx. indeed, libcap uses this function from libpsx to override its thread scoped default system call based API. when linked with libpsx, libcap can operate on all the threads of a multithreaded program to operate with POSIX semantics. that's the whole point, bestie, that's the dream πŸ¦‹


⭐ RETURN VALUE ⭐

The return value for system call functions is generally the value returned by the kernel, or -1 in the case of an error. in such cases errno(3) is set to the detailed error value.

and here's the sequencing you need to know, fr fr: the psx_syscall3() and psx_syscall6() functions attempt a single threaded system call and return immediately in the case of an error. should this call succeed, then the same system calls are executed from a signal handler on each of the other threads of the process. teamwork makes the dream work πŸ˜­πŸ’–


🌈 CONFORMING TO 🌈

The needs of libcap(3) for POSIX semantics of capability manipulation. you can read more about why this is needed here:

https://sites.google.com/site/fullycapable/who-ordered-libpsx

the lore drop: versions of libpsx prior to 2.72 only supported pthreads. since libpsx-2.72 the library works with all Linux thread implementations, because it operates at the lowest level of thread abstraction, LWPs. glow up of the century πŸ‘‘


πŸ’œ REPORTING BUGS πŸ’œ

The libpsx library is distributed from https://sites.google.com/site/fullycapable/ where the release notes may already cover recent issues. so check there first, bestie πŸ™ˆ

please report newly discovered bugs via:

https://bugzilla.kernel.org/buglist.cgi?component=libcap&list_id=1090757


🧚 SEE ALSO 🧚


and that's the whole page, periodt. ✨

okay this one's from 2024-11-09, and it's the Linux Programmer's Manual's LIBPSX(3) β€” go forth and coordinate your threads responsibly, ily, bye πŸŽ€πŸ’–πŸ«Ά

πŸ“¦ where this page comes from