95 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3=====================4Syscall User Dispatch5=====================6 7Background8----------9 10Compatibility layers like Wine need a way to efficiently emulate system11calls of only a part of their process - the part that has the12incompatible code - while being able to execute native syscalls without13a high performance penalty on the native part of the process. Seccomp14falls short on this task, since it has limited support to efficiently15filter syscalls based on memory regions, and it doesn't support removing16filters. Therefore a new mechanism is necessary.17 18Syscall User Dispatch brings the filtering of the syscall dispatcher19address back to userspace. The application is in control of a flip20switch, indicating the current personality of the process. A21multiple-personality application can then flip the switch without22invoking the kernel, when crossing the compatibility layer API23boundaries, to enable/disable the syscall redirection and execute24syscalls directly (disabled) or send them to be emulated in userspace25through a SIGSYS.26 27The goal of this design is to provide very quick compatibility layer28boundary crosses, which is achieved by not executing a syscall to change29personality every time the compatibility layer executes. Instead, a30userspace memory region exposed to the kernel indicates the current31personality, and the application simply modifies that variable to32configure the mechanism.33 34There is a relatively high cost associated with handling signals on most35architectures, like x86, but at least for Wine, syscalls issued by36native Windows code are currently not known to be a performance problem,37since they are quite rare, at least for modern gaming applications.38 39Since this mechanism is designed to capture syscalls issued by40non-native applications, it must function on syscalls whose invocation41ABI is completely unexpected to Linux. Syscall User Dispatch, therefore42doesn't rely on any of the syscall ABI to make the filtering. It uses43only the syscall dispatcher address and the userspace key.44 45As the ABI of these intercepted syscalls is unknown to Linux, these46syscalls are not instrumentable via ptrace or the syscall tracepoints.47 48Interface49---------50 51A thread can setup this mechanism on supported kernels by executing the52following prctl:53 54 prctl(PR_SET_SYSCALL_USER_DISPATCH, <op>, <offset>, <length>, [selector])55 56<op> is either PR_SYS_DISPATCH_ON or PR_SYS_DISPATCH_OFF, to enable and57disable the mechanism globally for that thread. When58PR_SYS_DISPATCH_OFF is used, the other fields must be zero.59 60[<offset>, <offset>+<length>) delimit a memory region interval61from which syscalls are always executed directly, regardless of the62userspace selector. This provides a fast path for the C library, which63includes the most common syscall dispatchers in the native code64applications, and also provides a way for the signal handler to return65without triggering a nested SIGSYS on (rt\_)sigreturn. Users of this66interface should make sure that at least the signal trampoline code is67included in this region. In addition, for syscalls that implement the68trampoline code on the vDSO, that trampoline is never intercepted.69 70[selector] is a pointer to a char-sized region in the process memory71region, that provides a quick way to enable disable syscall redirection72thread-wide, without the need to invoke the kernel directly. selector73can be set to SYSCALL_DISPATCH_FILTER_ALLOW or SYSCALL_DISPATCH_FILTER_BLOCK.74Any other value should terminate the program with a SIGSYS.75 76Additionally, a tasks syscall user dispatch configuration can be peeked77and poked via the PTRACE_(GET|SET)_SYSCALL_USER_DISPATCH_CONFIG ptrace78requests. This is useful for checkpoint/restart software.79 80Security Notes81--------------82 83Syscall User Dispatch provides functionality for compatibility layers to84quickly capture system calls issued by a non-native part of the85application, while not impacting the Linux native regions of the86process. It is not a mechanism for sandboxing system calls, and it87should not be seen as a security mechanism, since it is trivial for a88malicious application to subvert the mechanism by jumping to an allowed89dispatcher region prior to executing the syscall, or to discover the90address and modify the selector value. If the use case requires any91kind of security sandboxing, Seccomp should be used instead.92 93Any fork or exec of the existing process resets the mechanism to94PR_SYS_DISPATCH_OFF.95