History

syscall_user_dispatch: Make it configurable in Kconfig

Syscall User Dispatch is presently built under CONFIG_GENERIC_SYSCALL and cannot be disabled independently. Add CONFIG_SYSCALL_USER_DISPATCH to make it an optional feature.

Gregory Price committed 4 months ago

Commit ee935e81 parent 8cdeaa56 files · +42 −9Browse files

Unified · Split

6 files
  1. arch/Kconfig +10 −0
  2. include/linux/entry-common.h +2 −4
  3. include/linux/syscall_user_dispatch.h +26 −2
  4. include/linux/syscall_user_dispatch_types.h +1 −1
  5. kernel/entry/Makefile +2 −1
  6. tools/testing/selftests/syscall_user_dispatch/config +1 −1
arch/Kconfig+10−0
@@ -114,6 +114,16 @@ config GENERIC_ENTRY · 113 unmodified lines
114 select GENERIC_IRQ_ENTRY114 select GENERIC_IRQ_ENTRY
115 select GENERIC_SYSCALL115 select GENERIC_SYSCALL
116 116
117config SYSCALL_USER_DISPATCH
118 bool "Syscall User Dispatch"
119 depends on GENERIC_ENTRY
120 default y
121 help
122 Syscall User Dispatch lets a thread have its own system calls
123 intercepted and redirected to a userspace signal handler based
124 on a prctl() configured instruction pointer range.
125 If unsure, say Y.
126
117config KPROBES127config KPROBES
118 bool "Kprobes"128 bool "Kprobes"
119 depends on HAVE_KPROBES129 depends on HAVE_KPROBES
include/linux/entry-common.h+2−4
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/resume_user_mode.h>9#include <linux/resume_user_mode.h>
10#include <linux/seccomp.h>10#include <linux/seccomp.h>
11#include <linux/sched.h>11#include <linux/sched.h>
12#include <linux/syscall_user_dispatch.h>
12 13
13#include <asm/entry-common.h>14#include <asm/entry-common.h>
14#include <asm/syscall.h>15#include <asm/syscall.h>
@@ -55,7 +56,6 @@ static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs · 40 unmodified lines
55}56}
56#endif57#endif
57 58
58bool syscall_user_dispatch(struct pt_regs *regs);
59long trace_syscall_enter(struct pt_regs *regs, long syscall);59long trace_syscall_enter(struct pt_regs *regs, long syscall);
60void trace_syscall_exit(struct pt_regs *regs, long ret);60void trace_syscall_exit(struct pt_regs *regs, long ret);
61 61
@@ -232,10 +232,8 @@ static __always_inline void syscall_exit_work(struct pt_regs *regs, unsigned lon · 170 unmodified lines
232 * of these syscalls is unknown.232 * of these syscalls is unknown.
233 */233 */
234 if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) {234 if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) {
235 if (unlikely(current->syscall_dispatch.on_dispatch)) {235 if (syscall_user_dispatch_clear_on_dispatch())
236 current->syscall_dispatch.on_dispatch = false;
237 return;236 return;
238 }
239 }237 }
240 238
241 audit_syscall_exit(regs);239 audit_syscall_exit(regs);
include/linux/syscall_user_dispatch.h+26−2
@@ -6,9 +6,23 @@ · 5 unmodified lines
6#define _SYSCALL_USER_DISPATCH_H6#define _SYSCALL_USER_DISPATCH_H
7 7
8#include <linux/thread_info.h>8#include <linux/thread_info.h>
9#include <linux/sched.h>
9#include <linux/syscall_user_dispatch_types.h>10#include <linux/syscall_user_dispatch_types.h>
10 11
11#ifdef CONFIG_GENERIC_ENTRY12struct pt_regs;
13
14#ifdef CONFIG_SYSCALL_USER_DISPATCH
15
16bool syscall_user_dispatch(struct pt_regs *regs);
17
18static __always_inline bool syscall_user_dispatch_clear_on_dispatch(void)
19{
20 if (likely(!current->syscall_dispatch.on_dispatch))
21 return false;
22
23 current->syscall_dispatch.on_dispatch = false;
24 return true;
25}
12 26
13int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,27int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
14 unsigned long len, char __user *selector);28 unsigned long len, char __user *selector);
@@ -24,6 +38,16 @@ int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long siz · 9 unmodified lines
24 38
25#else39#else
26 40
41static __always_inline bool syscall_user_dispatch(struct pt_regs *regs)
42{
43 return false;
44}
45
46static __always_inline bool syscall_user_dispatch_clear_on_dispatch(void)
47{
48 return false;
49}
50
27static inline int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,51static inline int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
28 unsigned long len, char __user *selector)52 unsigned long len, char __user *selector)
29{53{
@@ -46,6 +70,6 @@ static inline int syscall_user_dispatch_set_config(struct task_struct *task, · 16 unmodified lines
46 return -EINVAL;70 return -EINVAL;
47}71}
48 72
49#endif /* CONFIG_GENERIC_ENTRY */73#endif /* CONFIG_SYSCALL_USER_DISPATCH */
50 74
51#endif /* _SYSCALL_USER_DISPATCH_H */75#endif /* _SYSCALL_USER_DISPATCH_H */
include/linux/syscall_user_dispatch_types.h+1−1
@@ -4,7 +4,7 @@ · 3 unmodified lines
4 4
5#include <linux/types.h>5#include <linux/types.h>
6 6
7#ifdef CONFIG_GENERIC_ENTRY7#ifdef CONFIG_SYSCALL_USER_DISPATCH
8 8
9struct syscall_user_dispatch {9struct syscall_user_dispatch {
10 char __user *selector;10 char __user *selector;
kernel/entry/Makefile+2−1
@@ -13,5 +13,6 @@ CFLAGS_REMOVE_common.o = -fstack-protector -fstack-protector-strong · 12 unmodified lines
13CFLAGS_common.o += -fno-stack-protector13CFLAGS_common.o += -fno-stack-protector
14 14
15obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o15obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o
16obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o syscall_user_dispatch.o16obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o
17obj-$(CONFIG_SYSCALL_USER_DISPATCH) += syscall_user_dispatch.o
17obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o18obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o
tools/testing/selftests/syscall_user_dispatch/config+1−1
@@ -1 +1 @@
1CONFIG_GENERIC_ENTRY=y1CONFIG_SYSCALL_USER_DISPATCH=y

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t