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 = ¤t->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