You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.8 KiB
75 lines
2.8 KiB
4 months ago
|
/*
|
||
|
* Copyright (c) 2019 Andrew G. Morgan <morgan@kernel.org>
|
||
|
*
|
||
|
* This header, and the -lpsx library, provide a number of things to
|
||
|
* support POSIX semantics for syscalls associated with the pthread
|
||
|
* library. Linking this code is tricky and is done as follows:
|
||
|
*
|
||
|
* ld ... -lpsx -lpthread --wrap=pthread_create
|
||
|
* or, gcc ... -lpsx -lpthread -Wl,-wrap,pthread_create
|
||
|
*
|
||
|
* glibc provides a subset of this functionality natively through the
|
||
|
* nptl:setxid mechanism and could implement psx_syscall() directly
|
||
|
* using that style of functionality but, as of 2019-11-30, the setxid
|
||
|
* mechanism is limited to 9 specific set*() syscalls that do not
|
||
|
* support the syscall6 API (needed for prctl functions and the ambient
|
||
|
* capabilities set for example).
|
||
|
*/
|
||
|
|
||
|
#ifndef _SYS_PSX_SYSCALL_H
|
||
|
#define _SYS_PSX_SYSCALL_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#include <pthread.h>
|
||
|
|
||
|
/*
|
||
|
* psx_syscall performs the specified syscall on all psx registered
|
||
|
* threads. The mechanism by which this occurs is much less efficient
|
||
|
* than a standard system call on Linux, so it should only be used
|
||
|
* when POSIX semantics are required to change process relevant
|
||
|
* security state.
|
||
|
*
|
||
|
* Glibc has native support for POSIX semantics on setgroups() and the
|
||
|
* 8 set*[gu]id() functions. So, there is no need to use psx_syscall()
|
||
|
* for these calls. This call exists for all the other system calls
|
||
|
* that need to maintain parity on all pthreads of a program.
|
||
|
*
|
||
|
* Some macrology is used to allow the caller to provide only as many
|
||
|
* arguments as needed, thus psx_syscall() cannot be used as a
|
||
|
* function pointer. For those situations, we define psx_syscall3()
|
||
|
* and psx_syscall6().
|
||
|
*/
|
||
|
#define psx_syscall(syscall_nr, ...) \
|
||
|
__psx_syscall(syscall_nr, __VA_ARGS__, (long int) 6, (long int) 5, \
|
||
|
(long int) 4, (long int) 3, (long int) 2, \
|
||
|
(long int) 1, (long int) 0)
|
||
|
long int __psx_syscall(long int syscall_nr, ...);
|
||
|
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);
|
||
|
|
||
|
/*
|
||
|
* This function should be used by systems to obtain pointers to the
|
||
|
* two syscall functions provided by the PSX library. A linkage trick
|
||
|
* is to define this function as weak in a library that can optionally
|
||
|
* use libpsx and then, should the caller link -lpsx, that library can
|
||
|
* implicitly use these POSIX semantics syscalls. See libcap for an
|
||
|
* example of this useage.
|
||
|
*/
|
||
|
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));
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* _SYS_PSX_SYSCALL_H */
|