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