xref: /linux/kernel/entry/syscall_user_dispatch.c (revision 59e6295fac26b8e85c1ea859cdd89fa1e47519d7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 Collabora Ltd.
4  */
5 #include <linux/elf.h>
6 #include <linux/entry-common.h>
7 #include <linux/prctl.h>
8 #include <linux/ptrace.h>
9 #include <linux/sched.h>
10 #include <linux/sched/signal.h>
11 #include <linux/sched/task_stack.h>
12 #include <linux/signal.h>
13 #include <linux/syscall_user_dispatch.h>
14 #include <linux/sysctl.h>
15 #include <linux/uaccess.h>
16 
17 #include <asm/syscall.h>
18 
19 static bool syscall_user_dispatch_allowed __read_mostly = true;
20 
21 static void trigger_sigsys(struct pt_regs *regs)
22 {
23 	struct kernel_siginfo info;
24 
25 	clear_siginfo(&info);
26 	info.si_signo = SIGSYS;
27 	info.si_code = SYS_USER_DISPATCH;
28 	info.si_call_addr = (void __user *)KSTK_EIP(current);
29 	info.si_errno = 0;
30 	info.si_arch = syscall_get_arch(current);
31 	info.si_syscall = syscall_get_nr(current, regs);
32 
33 	force_sig_info(&info);
34 }
35 
36 bool syscall_user_dispatch(struct pt_regs *regs)
37 {
38 	struct syscall_user_dispatch *sd = &current->syscall_dispatch;
39 	char state;
40 
41 	if (likely(instruction_pointer(regs) - sd->offset < sd->len))
42 		return false;
43 
44 	if (unlikely(arch_syscall_is_vdso_sigreturn(regs)))
45 		return false;
46 
47 	if (likely(sd->selector)) {
48 		/*
49 		 * access_ok() is performed once, at prctl time, when
50 		 * the selector is loaded by userspace.
51 		 */
52 		if (unlikely(__get_user(state, sd->selector))) {
53 			force_exit_sig(SIGSEGV);
54 			return true;
55 		}
56 
57 		if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW))
58 			return false;
59 
60 		if (state != SYSCALL_DISPATCH_FILTER_BLOCK) {
61 			force_exit_sig(SIGSYS);
62 			return true;
63 		}
64 	}
65 
66 	sd->on_dispatch = true;
67 	syscall_rollback(current, regs);
68 	trigger_sigsys(regs);
69 
70 	return true;
71 }
72 
73 static int task_set_syscall_user_dispatch(struct task_struct *task, unsigned long mode,
74 					  unsigned long offset, unsigned long len,
75 					  char __user *selector)
76 {
77 	switch (mode) {
78 	case PR_SYS_DISPATCH_OFF:
79 		if (offset || len || selector)
80 			return -EINVAL;
81 		break;
82 	case PR_SYS_DISPATCH_EXCLUSIVE_ON:
83 		/*
84 		 * Validate the direct dispatcher region just for basic
85 		 * sanity against overflow and a 0-sized dispatcher
86 		 * region.  If the user is able to submit a syscall from
87 		 * an address, that address is obviously valid.
88 		 */
89 		if (offset && offset + len <= offset)
90 			return -EINVAL;
91 		break;
92 	case PR_SYS_DISPATCH_INCLUSIVE_ON:
93 		if (len == 0 || offset + len <= offset)
94 			return -EINVAL;
95 		/*
96 		 * Invert the range, the check in syscall_user_dispatch()
97 		 * supports wrap-around.
98 		 */
99 		offset = offset + len;
100 		len = -len;
101 		break;
102 	default:
103 		return -EINVAL;
104 	}
105 
106 	/* Arming can be denied at runtime via sysctl, disarming is allowed */
107 	if (mode != PR_SYS_DISPATCH_OFF && !syscall_user_dispatch_allowed)
108 		return -EPERM;
109 
110 	/*
111 	 * access_ok() will clear memory tags for tagged addresses
112 	 * if current has memory tagging enabled.
113 	 *
114 	 * To enable a tracer to set a tracees selector the
115 	 * selector address must be untagged for access_ok(),
116 	 * otherwise an untagged tracer will always fail to set a
117 	 * tagged tracees selector.
118 	 */
119 	if (mode != PR_SYS_DISPATCH_OFF && selector &&
120 		!access_ok(untagged_addr(selector), sizeof(*selector)))
121 		return -EFAULT;
122 
123 	task->syscall_dispatch.selector = selector;
124 	task->syscall_dispatch.offset = offset;
125 	task->syscall_dispatch.len = len;
126 	task->syscall_dispatch.on_dispatch = false;
127 
128 	if (mode != PR_SYS_DISPATCH_OFF)
129 		set_task_syscall_work(task, SYSCALL_USER_DISPATCH);
130 	else
131 		clear_task_syscall_work(task, SYSCALL_USER_DISPATCH);
132 
133 	return 0;
134 }
135 
136 int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
137 			      unsigned long len, char __user *selector)
138 {
139 	return task_set_syscall_user_dispatch(current, mode, offset, len, selector);
140 }
141 
142 int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size,
143 				     void __user *data)
144 {
145 	struct syscall_user_dispatch *sd = &task->syscall_dispatch;
146 	struct ptrace_sud_config cfg;
147 
148 	if (size != sizeof(cfg))
149 		return -EINVAL;
150 
151 	if (test_task_syscall_work(task, SYSCALL_USER_DISPATCH))
152 		cfg.mode = PR_SYS_DISPATCH_ON;
153 	else
154 		cfg.mode = PR_SYS_DISPATCH_OFF;
155 
156 	cfg.offset = sd->offset;
157 	cfg.len = sd->len;
158 	cfg.selector = (__u64)(uintptr_t)sd->selector;
159 
160 	if (copy_to_user(data, &cfg, sizeof(cfg)))
161 		return -EFAULT;
162 
163 	return 0;
164 }
165 
166 int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long size,
167 				     void __user *data)
168 {
169 	struct ptrace_sud_config cfg;
170 
171 	if (size != sizeof(cfg))
172 		return -EINVAL;
173 
174 	if (copy_from_user(&cfg, data, sizeof(cfg)))
175 		return -EFAULT;
176 
177 	return task_set_syscall_user_dispatch(task, cfg.mode, cfg.offset, cfg.len,
178 					      (char __user *)(uintptr_t)cfg.selector);
179 }
180 
181 #ifdef CONFIG_PROC_SYSCTL
182 static const struct ctl_table syscall_user_dispatch_sysctls[] = {
183 	{
184 		.procname	= "syscall_user_dispatch",
185 		.data		= &syscall_user_dispatch_allowed,
186 		.maxlen		= sizeof(syscall_user_dispatch_allowed),
187 		.mode		= 0644,
188 		.proc_handler	= proc_dobool,
189 	},
190 };
191 
192 static int __init syscall_user_dispatch_sysctl_init(void)
193 {
194 	register_sysctl_init("kernel", syscall_user_dispatch_sysctls);
195 	return 0;
196 }
197 late_initcall(syscall_user_dispatch_sysctl_init);
198 #endif /* CONFIG_PROC_SYSCTL */
199