|
4 | 4 | */ |
5 | 5 | #include <linux/sched.h> |
6 | 6 | #include <linux/prctl.h> |
| 7 | +#include <linux/ptrace.h> |
7 | 8 | #include <linux/syscall_user_dispatch.h> |
8 | 9 | #include <linux/uaccess.h> |
9 | 10 | #include <linux/signal.h> |
@@ -122,3 +123,42 @@ int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, |
122 | 123 | { |
123 | 124 | return task_set_syscall_user_dispatch(current, mode, offset, len, selector); |
124 | 125 | } |
| 126 | + |
| 127 | +int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size, |
| 128 | + void __user *data) |
| 129 | +{ |
| 130 | + struct syscall_user_dispatch *sd = &task->syscall_dispatch; |
| 131 | + struct ptrace_sud_config cfg; |
| 132 | + |
| 133 | + if (size != sizeof(cfg)) |
| 134 | + return -EINVAL; |
| 135 | + |
| 136 | + if (test_task_syscall_work(task, SYSCALL_USER_DISPATCH)) |
| 137 | + cfg.mode = PR_SYS_DISPATCH_ON; |
| 138 | + else |
| 139 | + cfg.mode = PR_SYS_DISPATCH_OFF; |
| 140 | + |
| 141 | + cfg.offset = sd->offset; |
| 142 | + cfg.len = sd->len; |
| 143 | + cfg.selector = (__u64)(uintptr_t)sd->selector; |
| 144 | + |
| 145 | + if (copy_to_user(data, &cfg, sizeof(cfg))) |
| 146 | + return -EFAULT; |
| 147 | + |
| 148 | + return 0; |
| 149 | +} |
| 150 | + |
| 151 | +int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long size, |
| 152 | + void __user *data) |
| 153 | +{ |
| 154 | + struct ptrace_sud_config cfg; |
| 155 | + |
| 156 | + if (size != sizeof(cfg)) |
| 157 | + return -EINVAL; |
| 158 | + |
| 159 | + if (copy_from_user(&cfg, data, sizeof(cfg))) |
| 160 | + return -EFAULT; |
| 161 | + |
| 162 | + return task_set_syscall_user_dispatch(task, cfg.mode, cfg.offset, cfg.len, |
| 163 | + (char __user *)(uintptr_t)cfg.selector); |
| 164 | +} |
0 commit comments