1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/*
* Copyright (c) 2019,24 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. For any code that references the psx_syscall{3,6}
* functions, linking this code is as follows:
*
* ld ... -lpsx -lpthread
* or,
* gcc ... -lpsx -lpthread
*
* NOTE: linking with -lcap to make it silently aware of the psx
* mechanism is tricky. You have to envelope the -lpsx part with
* the following linker flags:
*
* ld ... --no-as-needed --whole-archive -lpsx --no-whole-archive --as-needed -lpthread
* or,
* gcc ... -Wl,--no-as-needed -Wl,--whole-archive -lpsx -Wl,--no-whole-archive -Wl,--as-needed -lpthread
*
* These options are provided in the
* https://en.wikipedia.org/wiki/Pkg-config libpsx.pc file
* distributed with the library.
*
* FYI Earlier versions of libpsx relied on gcc
* ... -Wl,--wrap=pthread_create linkage in all cases, but since
* libpsx-2.72 the library can work with non pthread threads (LWP)
* under Linux and such wrapping is no longer needed. That being
* said, for compatibility reasons such linking is still supported.
*
* 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
/*
* Programmatic way to recognize feature set.
*/
#define LIBPSX_MAJOR 2
#define LIBPSX_MINOR 75
/*
* 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 usage.
*/
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));
/*
* psx_sensitivity_t holds the level of paranoia for non-POSIX syscall
* behavior. The default is PSX_IGNORE: which is best effort - no
* enforcement; PSX_WARNING will dump to stderr a warning when a
* syscall's results differ; PSX_ERROR will dump info as per
* PSX_WARNING and generate a SIGSYS. The current mode can be set with
* psx_set_sensitivity().
*/
typedef enum {
PSX_IGNORE = 0,
PSX_WARNING = 1,
PSX_ERROR = 2,
} psx_sensitivity_t;
/*
* psx_set_sensitivity sets the current sensitivity of the PSX
* mechanism. The function returns 0 on success and -1 if the
* requested level is invalid.
*/
int psx_set_sensitivity(psx_sensitivity_t level);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PSX_SYSCALL_H */
|