kernel/entry/syscall_user_dispatch.c
Source file repositories/reference/linux-study-clean/kernel/entry/syscall_user_dispatch.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/entry/syscall_user_dispatch.c- Extension
.c- Size
- 4349 bytes
- Lines
- 175
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/entry-common.hlinux/sched.hlinux/prctl.hlinux/ptrace.hlinux/syscall_user_dispatch.hlinux/uaccess.hlinux/signal.hlinux/elf.hlinux/sched/signal.hlinux/sched/task_stack.hasm/syscall.h
Detected Declarations
function Copyrightfunction syscall_user_dispatchfunction task_set_syscall_user_dispatchfunction set_syscall_user_dispatchfunction syscall_user_dispatch_get_configfunction syscall_user_dispatch_set_config
Annotated Snippet
if (unlikely(__get_user(state, sd->selector))) {
force_exit_sig(SIGSEGV);
return true;
}
if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW))
return false;
if (state != SYSCALL_DISPATCH_FILTER_BLOCK) {
force_exit_sig(SIGSYS);
return true;
}
}
sd->on_dispatch = true;
syscall_rollback(current, regs);
trigger_sigsys(regs);
return true;
}
static int task_set_syscall_user_dispatch(struct task_struct *task, unsigned long mode,
unsigned long offset, unsigned long len,
char __user *selector)
{
switch (mode) {
case PR_SYS_DISPATCH_OFF:
if (offset || len || selector)
return -EINVAL;
break;
case PR_SYS_DISPATCH_EXCLUSIVE_ON:
/*
* Validate the direct dispatcher region just for basic
* sanity against overflow and a 0-sized dispatcher
* region. If the user is able to submit a syscall from
* an address, that address is obviously valid.
*/
if (offset && offset + len <= offset)
return -EINVAL;
break;
case PR_SYS_DISPATCH_INCLUSIVE_ON:
if (len == 0 || offset + len <= offset)
return -EINVAL;
/*
* Invert the range, the check in syscall_user_dispatch()
* supports wrap-around.
*/
offset = offset + len;
len = -len;
break;
default:
return -EINVAL;
}
/*
* access_ok() will clear memory tags for tagged addresses
* if current has memory tagging enabled.
*
* To enable a tracer to set a tracees selector the
* selector address must be untagged for access_ok(),
* otherwise an untagged tracer will always fail to set a
* tagged tracees selector.
*/
if (mode != PR_SYS_DISPATCH_OFF && selector &&
!access_ok(untagged_addr(selector), sizeof(*selector)))
return -EFAULT;
task->syscall_dispatch.selector = selector;
task->syscall_dispatch.offset = offset;
task->syscall_dispatch.len = len;
task->syscall_dispatch.on_dispatch = false;
if (mode != PR_SYS_DISPATCH_OFF)
set_task_syscall_work(task, SYSCALL_USER_DISPATCH);
else
clear_task_syscall_work(task, SYSCALL_USER_DISPATCH);
return 0;
}
int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
unsigned long len, char __user *selector)
{
return task_set_syscall_user_dispatch(current, mode, offset, len, selector);
}
int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size,
void __user *data)
{
struct syscall_user_dispatch *sd = &task->syscall_dispatch;
Annotation
- Immediate include surface: `linux/entry-common.h`, `linux/sched.h`, `linux/prctl.h`, `linux/ptrace.h`, `linux/syscall_user_dispatch.h`, `linux/uaccess.h`, `linux/signal.h`, `linux/elf.h`.
- Detected declarations: `function Copyright`, `function syscall_user_dispatch`, `function task_set_syscall_user_dispatch`, `function set_syscall_user_dispatch`, `function syscall_user_dispatch_get_config`, `function syscall_user_dispatch_set_config`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.