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 if (unlikely(get_user(state, untagged_addr(sd->selector)))) { 49 force_exit_sig(SIGSEGV); 50 return true; 51 } 52 53 if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW)) 54 return false; 55 56 if (state != SYSCALL_DISPATCH_FILTER_BLOCK) { 57 force_exit_sig(SIGSYS); 58 return true; 59 } 60 } 61 62 sd->on_dispatch = true; 63 syscall_rollback(current, regs); 64 trigger_sigsys(regs); 65 66 return true; 67 } 68 69 static int task_set_syscall_user_dispatch(struct task_struct *task, unsigned long mode, 70 unsigned long offset, unsigned long len, 71 char __user *selector) 72 { 73 switch (mode) { 74 case PR_SYS_DISPATCH_OFF: 75 if (offset || len || selector) 76 return -EINVAL; 77 break; 78 case PR_SYS_DISPATCH_EXCLUSIVE_ON: 79 /* 80 * Validate the direct dispatcher region just for basic 81 * sanity against overflow and a 0-sized dispatcher 82 * region. If the user is able to submit a syscall from 83 * an address, that address is obviously valid. 84 */ 85 if (offset && offset + len <= offset) 86 return -EINVAL; 87 break; 88 case PR_SYS_DISPATCH_INCLUSIVE_ON: 89 if (len == 0 || offset + len <= offset) 90 return -EINVAL; 91 /* 92 * Invert the range, the check in syscall_user_dispatch() 93 * supports wrap-around. 94 */ 95 offset = offset + len; 96 len = -len; 97 break; 98 default: 99 return -EINVAL; 100 } 101 102 /* Arming can be denied at runtime via sysctl, disarming is allowed */ 103 if (mode != PR_SYS_DISPATCH_OFF && !syscall_user_dispatch_allowed) 104 return -EPERM; 105 106 /* 107 * access_ok() will clear memory tags for tagged addresses 108 * if current has memory tagging enabled. 109 * 110 * To enable a tracer to set a tracees selector the 111 * selector address must be untagged for access_ok(), 112 * otherwise an untagged tracer will always fail to set a 113 * tagged tracees selector. 114 */ 115 if (mode != PR_SYS_DISPATCH_OFF && selector && 116 !access_ok(untagged_addr(selector), sizeof(*selector))) 117 return -EFAULT; 118 119 task->syscall_dispatch.selector = selector; 120 task->syscall_dispatch.offset = offset; 121 task->syscall_dispatch.len = len; 122 task->syscall_dispatch.on_dispatch = false; 123 124 if (mode != PR_SYS_DISPATCH_OFF) 125 set_task_syscall_work(task, SYSCALL_USER_DISPATCH); 126 else 127 clear_task_syscall_work(task, SYSCALL_USER_DISPATCH); 128 129 return 0; 130 } 131 132 int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, 133 unsigned long len, char __user *selector) 134 { 135 return task_set_syscall_user_dispatch(current, mode, offset, len, selector); 136 } 137 138 int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size, 139 void __user *data) 140 { 141 struct syscall_user_dispatch *sd = &task->syscall_dispatch; 142 struct ptrace_sud_config cfg; 143 144 if (size != sizeof(cfg)) 145 return -EINVAL; 146 147 if (test_task_syscall_work(task, SYSCALL_USER_DISPATCH)) 148 cfg.mode = PR_SYS_DISPATCH_ON; 149 else 150 cfg.mode = PR_SYS_DISPATCH_OFF; 151 152 cfg.offset = sd->offset; 153 cfg.len = sd->len; 154 cfg.selector = (__u64)(uintptr_t)sd->selector; 155 156 if (copy_to_user(data, &cfg, sizeof(cfg))) 157 return -EFAULT; 158 159 return 0; 160 } 161 162 int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long size, 163 void __user *data) 164 { 165 struct ptrace_sud_config cfg; 166 167 if (size != sizeof(cfg)) 168 return -EINVAL; 169 170 if (copy_from_user(&cfg, data, sizeof(cfg))) 171 return -EFAULT; 172 173 return task_set_syscall_user_dispatch(task, cfg.mode, cfg.offset, cfg.len, 174 (char __user *)(uintptr_t)cfg.selector); 175 } 176 177 #ifdef CONFIG_SYSCTL 178 static const struct ctl_table syscall_user_dispatch_sysctls[] = { 179 { 180 .procname = "syscall_user_dispatch", 181 .data = &syscall_user_dispatch_allowed, 182 .maxlen = sizeof(syscall_user_dispatch_allowed), 183 .mode = 0644, 184 .proc_handler = proc_dobool, 185 }, 186 }; 187 188 static int __init syscall_user_dispatch_sysctl_init(void) 189 { 190 register_sysctl_init("kernel", syscall_user_dispatch_sysctls); 191 return 0; 192 } 193 late_initcall(syscall_user_dispatch_sysctl_init); 194 #endif /* CONFIG_SYSCTL */ 195