PR_SET_SYSCALL_USER_DISPATCH(2const)
π PR_SET_SYSCALL_USER_DISPATCH π
okay bestie, so this whole thing is a (2const) page from the Linux man pages, which basically means it's one of those fun little constant-flavored pages that got carved out of prctl(2). It's the β¨ protocol β¨ for telling your thread "hey, some of my syscalls should come back to me, not the kernel." iykyk.
πΈ NAME πΈ
PR_SET_SYSCALL_USER_DISPATCH β sets up the system-call user dispatch mechanism for the calling thread π
π LIBRARY π
Standard C library β libc, -lc. yep, the regular one π«Ά
β¨ SYNOPSIS β¨
#include <linux/prctl.h> /* Definition of PR_* constants */
#include <sys/prctl.h>
int prctl(PR_SET_SYSCALL_USER_DISPATCH, long op, ...);
int prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
unsigned long off, unsigned long size, int8_t *switch);
int prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF, 0L, 0L, 0L);
π¦ DESCRIPTION π¦
So this configures the Syscall User Dispatch mechanism for the calling thread. In human terms: it lets your application selectively intercept system calls so you can handle them inside the app itself. The vibe is π« main character energy for your own syscall handler π«.
When it intercepts, it sends a thread-directed SIGSYS signal to the thread right when that thread makes a system call. And no cap β if it's intercepted, the kernel does not execute the system call. periodt.
π PR_SYS_DISPATCH_ON
Turns the whole mechanism on. iconic.
Once it's enabled, further system calls get selectively intercepted, and that depends on a control variable that your user space provides. So here's the deal with the args:
offandsizeare the offset and size of one single contiguous memory region in the process address space. System calls coming from there are always allowed to execute, no matter what the control variable says. (Typically this area would include the memory region holding the C library. π)switchpoints to a variable β a fast switch to allow/block syscall execution without the overhead of making another syscall to re-configure Syscall User Dispatch. Because the way that would be annoying, honestly π. This control variable can be set to either:SYSCALL_DISPATCH_FILTER_BLOCKβ block system calls from executing, orSYSCALL_DISPATCH_FILTER_ALLOWβ temporarily let them execute.
The kernel checks this value on every single syscall entry, and any unexpected value raises an uncatchable SIGSYS right then and there, killing the application. π so like. be normal about it.
When a system call gets intercepted, the kernel sends a thread-directed SIGSYS signal to the triggering thread. And various fields get set in the siginfo_t structure (see sigaction(2)) that comes with the signal:
si_signowill containSIGSYS.si_call_addrwill show the address of the system call instruction.si_syscallandsi_archwill indicate which system call was attempted.si_codewill containSYS_USER_DISPATCH.si_errnowill be set to0.
Also the program counter will be as though the system call happened β meaning the program counter will not point to the system call instruction. sneaky but correct.
When the signal handler returns back to the kernel, the system call completes immediately and returns to the calling thread, without actually being executed. And if necessary β i.e., when emulating the system call on user space β the signal handler should set the system call's return value to a sane value, by modifying the register context stored in the ucontext argument of the signal handler. See sigaction(2), sigreturn(2), and getcontext(3) for more info. bestie homework π
π PR_SYS_DISPATCH_OFF
Syscall User Dispatch is disabled for that thread. simple as that.
β οΈ heads up: this setting is not preserved acrossfork(2),clone(2), orexecve(2). it does not travel. it does not follow you. π
π RETURN VALUE π
On success, 0 is returned, slay. On error, -1 is returned, and errno is set to indicate the error. π
π₯ ERRORS π₯
EFAULTβswitchis an invalid address.EINVALβopisPR_SYS_DISPATCH_ONand the memory range specified is outside the address space of the process.EINVALβopis invalid.
π STANDARDS π
Linux. x86 only. π that's it that's the whole thing.
π HISTORY π
Linux 5.11 (x86). a classic, honestly.
π«Ά SEE ALSO π«Ά
For more information, see the kernel source file Documentation/admin-guide/syscall-user-dispatch.rst πβ¨
and that's the whole page, bestie π this cutie came to you straight from Linux man-pages 6.20, dated 2026-02. go intercept some syscalls responsibly, mwah ππ¦
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- Copyright 2021, Gabriel Krisman Bertazi <krisman@collabora.com>
- Copyright 2021, Michael Kerrisk <mtk.manpages@gmail.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms