diff options
Diffstat (limited to 'kernel/entry')
| -rw-r--r-- | kernel/entry/Makefile | 3 | ||||
| -rw-r--r-- | kernel/entry/syscall-common.c | 21 | ||||
| -rw-r--r-- | kernel/entry/syscall_user_dispatch.c | 38 |
3 files changed, 47 insertions, 15 deletions
diff --git a/kernel/entry/Makefile b/kernel/entry/Makefile index 2333d70802e4..f220bae86b12 100644 --- a/kernel/entry/Makefile +++ b/kernel/entry/Makefile @@ -13,5 +13,6 @@ CFLAGS_REMOVE_common.o = -fstack-protector -fstack-protector-strong CFLAGS_common.o += -fno-stack-protector obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o -obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o syscall_user_dispatch.o +obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o +obj-$(CONFIG_SYSCALL_USER_DISPATCH) += syscall_user_dispatch.o obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o diff --git a/kernel/entry/syscall-common.c b/kernel/entry/syscall-common.c index cd4967a9c53e..b8eac9efb6fd 100644 --- a/kernel/entry/syscall-common.c +++ b/kernel/entry/syscall-common.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/audit.h> #include <linux/entry-common.h> #define CREATE_TRACE_POINTS @@ -7,17 +8,23 @@ /* Out of line to prevent tracepoint code duplication */ -long trace_syscall_enter(struct pt_regs *regs, long syscall) +void trace_syscall_enter(struct pt_regs *regs) { - trace_sys_enter(regs, syscall); - /* - * Probes or BPF hooks in the tracepoint may have changed the - * system call number. Reread it. - */ - return syscall_get_nr(current, regs); + trace_sys_enter(regs, syscall_get_nr(current, regs)); } void trace_syscall_exit(struct pt_regs *regs, long ret) { trace_sys_exit(regs, ret); } + +#ifdef CONFIG_AUDITSYSCALL +void syscall_enter_audit(struct pt_regs *regs) +{ + long syscall = syscall_get_nr(current, regs); + unsigned long args[6]; + + syscall_get_arguments(current, regs, args); + __audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]); +} +#endif diff --git a/kernel/entry/syscall_user_dispatch.c b/kernel/entry/syscall_user_dispatch.c index d89dffcc2d64..59c861866941 100644 --- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -2,21 +2,22 @@ /* * Copyright (C) 2020 Collabora Ltd. */ - +#include <linux/elf.h> #include <linux/entry-common.h> -#include <linux/sched.h> #include <linux/prctl.h> #include <linux/ptrace.h> -#include <linux/syscall_user_dispatch.h> -#include <linux/uaccess.h> -#include <linux/signal.h> -#include <linux/elf.h> - +#include <linux/sched.h> #include <linux/sched/signal.h> #include <linux/sched/task_stack.h> +#include <linux/signal.h> +#include <linux/syscall_user_dispatch.h> +#include <linux/sysctl.h> +#include <linux/uaccess.h> #include <asm/syscall.h> +static bool syscall_user_dispatch_allowed __read_mostly = true; + static void trigger_sigsys(struct pt_regs *regs) { struct kernel_siginfo info; @@ -102,6 +103,10 @@ static int task_set_syscall_user_dispatch(struct task_struct *task, unsigned lon return -EINVAL; } + /* Arming can be denied at runtime via sysctl, disarming is allowed */ + if (mode != PR_SYS_DISPATCH_OFF && !syscall_user_dispatch_allowed) + return -EPERM; + /* * access_ok() will clear memory tags for tagged addresses * if current has memory tagging enabled. @@ -172,3 +177,22 @@ int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long siz return task_set_syscall_user_dispatch(task, cfg.mode, cfg.offset, cfg.len, (char __user *)(uintptr_t)cfg.selector); } + +#ifdef CONFIG_SYSCTL +static const struct ctl_table syscall_user_dispatch_sysctls[] = { + { + .procname = "syscall_user_dispatch", + .data = &syscall_user_dispatch_allowed, + .maxlen = sizeof(syscall_user_dispatch_allowed), + .mode = 0644, + .proc_handler = proc_dobool, + }, +}; + +static int __init syscall_user_dispatch_sysctl_init(void) +{ + register_sysctl_init("kernel", syscall_user_dispatch_sysctls); + return 0; +} +late_initcall(syscall_user_dispatch_sysctl_init); +#endif /* CONFIG_SYSCTL */ |
