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/syscall_user_dispatch.h> 8 #include <linux/uaccess.h> 9 #include <linux/signal.h> 10 #include <linux/elf.h> 11 12 #include <linux/sched/signal.h> 13 #include <linux/sched/task_stack.h> 14 15 #include <asm/syscall.h> 16 17 #include "common.h" 18 19 static void trigger_sigsys(struct pt_regs *regs) 20 { 21 struct kernel_siginfo info; 22 23 clear_siginfo(&info); 24 info.si_signo = SIGSYS; 25 info.si_code = SYS_USER_DISPATCH; 26 info.si_call_addr = (void __user *)KSTK_EIP(current); 27 info.si_errno = 0; 28 info.si_arch = syscall_get_arch(current); 29 info.si_syscall = syscall_get_nr(current, regs); 30 31 force_sig_info(&info); 32 } 33 34 bool syscall_user_dispatch(struct pt_regs *regs) 35 { 36 struct syscall_user_dispatch *sd = ¤t->syscall_dispatch; 37 char state; 38 39 if (likely(instruction_pointer(regs) - sd->offset < sd->len)) 40 return false; 41 42 if (unlikely(arch_syscall_is_vdso_sigreturn(regs))) 43 return false; 44 45 if (likely(sd->selector)) { 46 /* 47 * access_ok() is performed once, at prctl time, when 48 * the selector is loaded by userspace. 49 */ 50 if (unlikely(__get_user(state, sd->selector))) { 51 force_exit_sig(SIGSEGV); 52 return true; 53 } 54 55 if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW)) 56 return false; 57 58 if (state != SYSCALL_DISPATCH_FILTER_BLOCK) { 59 force_exit_sig(SIGSYS); 60 return true; 61 } 62 } 63 64 sd->on_dispatch = true; 65 syscall_rollback(current, regs); 66 trigger_sigsys(regs); 67 68 return true; 69 } 70 71 static int task_set_syscall_user_dispatch(struct task_struct *task, unsigned long mode, 72 unsigned long offset, unsigned long len, 73 char __user *selector) 74 { 75 switch (mode) { 76 case PR_SYS_DISPATCH_OFF: 77 if (offset || len || selector) 78 return -EINVAL; 79 break; 80 case PR_SYS_DISPATCH_ON: 81 /* 82 * Validate the direct dispatcher region just for basic 83 * sanity against overflow and a 0-sized dispatcher 84 * region. If the user is able to submit a syscall from 85 * an address, that address is obviously valid. 86 */ 87 if (offset && offset + len <= offset) 88 return -EINVAL; 89 90 /* 91 * access_ok() will clear memory tags for tagged addresses 92 * if current has memory tagging enabled. 93 94 * To enable a tracer to set a tracees selector the 95 * selector address must be untagged for access_ok(), 96 * otherwise an untagged tracer will always fail to set a 97 * tagged tracees selector. 98 */ 99 if (selector && !access_ok(untagged_addr(selector), sizeof(*selector))) 100 return -EFAULT; 101 102 break; 103 default: 104 return -EINVAL; 105 } 106 107 task->syscall_dispatch.selector = selector; 108 task->syscall_dispatch.offset = offset; 109 task->syscall_dispatch.len = len; 110 task->syscall_dispatch.on_dispatch = false; 111 112 if (mode == PR_SYS_DISPATCH_ON) 113 set_task_syscall_work(task, SYSCALL_USER_DISPATCH); 114 else 115 clear_task_syscall_work(task, SYSCALL_USER_DISPATCH); 116 117 return 0; 118 } 119 120 int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, 121 unsigned long len, char __user *selector) 122 { 123 return task_set_syscall_user_dispatch(current, mode, offset, len, selector); 124 } 125