1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/arch/sh/kernel/signal.c |
4 | * |
5 | * Copyright (C) 1991, 1992 Linus Torvalds |
6 | * |
7 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson |
8 | * |
9 | * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima |
10 | * |
11 | */ |
12 | #include <linux/sched.h> |
13 | #include <linux/sched/task_stack.h> |
14 | #include <linux/mm.h> |
15 | #include <linux/smp.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/signal.h> |
18 | #include <linux/errno.h> |
19 | #include <linux/wait.h> |
20 | #include <linux/ptrace.h> |
21 | #include <linux/unistd.h> |
22 | #include <linux/stddef.h> |
23 | #include <linux/tty.h> |
24 | #include <linux/elf.h> |
25 | #include <linux/personality.h> |
26 | #include <linux/binfmts.h> |
27 | #include <linux/io.h> |
28 | #include <linux/resume_user_mode.h> |
29 | #include <asm/ucontext.h> |
30 | #include <linux/uaccess.h> |
31 | #include <asm/cacheflush.h> |
32 | #include <asm/syscalls.h> |
33 | #include <asm/fpu.h> |
34 | |
35 | struct fdpic_func_descriptor { |
36 | unsigned long text; |
37 | unsigned long GOT; |
38 | }; |
39 | |
40 | /* |
41 | * The following define adds a 64 byte gap between the signal |
42 | * stack frame and previous contents of the stack. This allows |
43 | * frame unwinding in a function epilogue but only if a frame |
44 | * pointer is used in the function. This is necessary because |
45 | * current gcc compilers (<4.3) do not generate unwind info on |
46 | * SH for function epilogues. |
47 | */ |
48 | #define UNWINDGUARD 64 |
49 | |
50 | /* |
51 | * Do a signal return; undo the signal stack. |
52 | */ |
53 | |
54 | #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ |
55 | #if defined(CONFIG_CPU_SH2) |
56 | #define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */ |
57 | #else |
58 | #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */ |
59 | #endif |
60 | #define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */ |
61 | |
62 | struct sigframe |
63 | { |
64 | struct sigcontext sc; |
65 | unsigned long [_NSIG_WORDS-1]; |
66 | u16 retcode[8]; |
67 | }; |
68 | |
69 | struct rt_sigframe |
70 | { |
71 | struct siginfo info; |
72 | struct ucontext uc; |
73 | u16 retcode[8]; |
74 | }; |
75 | |
76 | #ifdef CONFIG_SH_FPU |
77 | static inline int restore_sigcontext_fpu(struct sigcontext __user *sc) |
78 | { |
79 | struct task_struct *tsk = current; |
80 | |
81 | if (!(boot_cpu_data.flags & CPU_HAS_FPU)) |
82 | return 0; |
83 | |
84 | set_used_math(); |
85 | return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0], |
86 | sizeof(long)*(16*2+2)); |
87 | } |
88 | |
89 | static inline int save_sigcontext_fpu(struct sigcontext __user *sc, |
90 | struct pt_regs *regs) |
91 | { |
92 | struct task_struct *tsk = current; |
93 | |
94 | if (!(boot_cpu_data.flags & CPU_HAS_FPU)) |
95 | return 0; |
96 | |
97 | if (!used_math()) |
98 | return __put_user(0, &sc->sc_ownedfp); |
99 | |
100 | if (__put_user(1, &sc->sc_ownedfp)) |
101 | return -EFAULT; |
102 | |
103 | /* This will cause a "finit" to be triggered by the next |
104 | attempted FPU operation by the 'current' process. |
105 | */ |
106 | clear_used_math(); |
107 | |
108 | unlazy_fpu(tsk, regs); |
109 | return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu, |
110 | sizeof(long)*(16*2+2)); |
111 | } |
112 | #endif /* CONFIG_SH_FPU */ |
113 | |
114 | static int |
115 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p) |
116 | { |
117 | unsigned int err = 0; |
118 | unsigned int sr = regs->sr & ~SR_USER_MASK; |
119 | |
120 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) |
121 | COPY(regs[1]); |
122 | COPY(regs[2]); COPY(regs[3]); |
123 | COPY(regs[4]); COPY(regs[5]); |
124 | COPY(regs[6]); COPY(regs[7]); |
125 | COPY(regs[8]); COPY(regs[9]); |
126 | COPY(regs[10]); COPY(regs[11]); |
127 | COPY(regs[12]); COPY(regs[13]); |
128 | COPY(regs[14]); COPY(regs[15]); |
129 | COPY(gbr); COPY(mach); |
130 | COPY(macl); COPY(pr); |
131 | COPY(sr); COPY(pc); |
132 | #undef COPY |
133 | |
134 | regs->sr = (regs->sr & SR_USER_MASK) | sr; |
135 | |
136 | #ifdef CONFIG_SH_FPU |
137 | if (boot_cpu_data.flags & CPU_HAS_FPU) { |
138 | int owned_fp; |
139 | struct task_struct *tsk = current; |
140 | |
141 | regs->sr |= SR_FD; /* Release FPU */ |
142 | clear_fpu(tsk, regs); |
143 | clear_used_math(); |
144 | err |= __get_user (owned_fp, &sc->sc_ownedfp); |
145 | if (owned_fp) |
146 | err |= restore_sigcontext_fpu(sc); |
147 | } |
148 | #endif |
149 | |
150 | regs->tra = -1; /* disable syscall checks */ |
151 | err |= __get_user(*r0_p, &sc->sc_regs[0]); |
152 | return err; |
153 | } |
154 | |
155 | asmlinkage int sys_sigreturn(void) |
156 | { |
157 | struct pt_regs *regs = current_pt_regs(); |
158 | struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15]; |
159 | sigset_t set; |
160 | int r0; |
161 | |
162 | /* Always make any pending restarted system calls return -EINTR */ |
163 | current->restart_block.fn = do_no_restart_syscall; |
164 | |
165 | if (!access_ok(frame, sizeof(*frame))) |
166 | goto badframe; |
167 | |
168 | if (__get_user(set.sig[0], &frame->sc.oldmask) |
169 | || (_NSIG_WORDS > 1 |
170 | && __copy_from_user(to: &set.sig[1], from: &frame->extramask, |
171 | n: sizeof(frame->extramask)))) |
172 | goto badframe; |
173 | |
174 | set_current_blocked(&set); |
175 | |
176 | if (restore_sigcontext(regs, sc: &frame->sc, r0_p: &r0)) |
177 | goto badframe; |
178 | return r0; |
179 | |
180 | badframe: |
181 | force_sig(SIGSEGV); |
182 | return 0; |
183 | } |
184 | |
185 | asmlinkage int sys_rt_sigreturn(void) |
186 | { |
187 | struct pt_regs *regs = current_pt_regs(); |
188 | struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15]; |
189 | sigset_t set; |
190 | int r0; |
191 | |
192 | /* Always make any pending restarted system calls return -EINTR */ |
193 | current->restart_block.fn = do_no_restart_syscall; |
194 | |
195 | if (!access_ok(frame, sizeof(*frame))) |
196 | goto badframe; |
197 | |
198 | if (__copy_from_user(to: &set, from: &frame->uc.uc_sigmask, n: sizeof(set))) |
199 | goto badframe; |
200 | |
201 | set_current_blocked(&set); |
202 | |
203 | if (restore_sigcontext(regs, sc: &frame->uc.uc_mcontext, r0_p: &r0)) |
204 | goto badframe; |
205 | |
206 | if (restore_altstack(&frame->uc.uc_stack)) |
207 | goto badframe; |
208 | |
209 | return r0; |
210 | |
211 | badframe: |
212 | force_sig(SIGSEGV); |
213 | return 0; |
214 | } |
215 | |
216 | /* |
217 | * Set up a signal frame. |
218 | */ |
219 | |
220 | static int |
221 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, |
222 | unsigned long mask) |
223 | { |
224 | int err = 0; |
225 | |
226 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) |
227 | COPY(regs[0]); COPY(regs[1]); |
228 | COPY(regs[2]); COPY(regs[3]); |
229 | COPY(regs[4]); COPY(regs[5]); |
230 | COPY(regs[6]); COPY(regs[7]); |
231 | COPY(regs[8]); COPY(regs[9]); |
232 | COPY(regs[10]); COPY(regs[11]); |
233 | COPY(regs[12]); COPY(regs[13]); |
234 | COPY(regs[14]); COPY(regs[15]); |
235 | COPY(gbr); COPY(mach); |
236 | COPY(macl); COPY(pr); |
237 | COPY(sr); COPY(pc); |
238 | #undef COPY |
239 | |
240 | #ifdef CONFIG_SH_FPU |
241 | err |= save_sigcontext_fpu(sc, regs); |
242 | #endif |
243 | |
244 | /* non-iBCS2 extensions.. */ |
245 | err |= __put_user(mask, &sc->oldmask); |
246 | |
247 | return err; |
248 | } |
249 | |
250 | /* |
251 | * Determine which stack to use.. |
252 | */ |
253 | static inline void __user * |
254 | get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) |
255 | { |
256 | if (ka->sa.sa_flags & SA_ONSTACK) { |
257 | if (sas_ss_flags(sp) == 0) |
258 | sp = current->sas_ss_sp + current->sas_ss_size; |
259 | } |
260 | |
261 | return (void __user *)((sp - (frame_size+UNWINDGUARD)) & -8ul); |
262 | } |
263 | |
264 | /* These symbols are defined with the addresses in the vsyscall page. |
265 | See vsyscall-trapa.S. */ |
266 | extern void __kernel_sigreturn(void); |
267 | extern void __kernel_rt_sigreturn(void); |
268 | |
269 | static int setup_frame(struct ksignal *ksig, sigset_t *set, |
270 | struct pt_regs *regs) |
271 | { |
272 | struct sigframe __user *frame; |
273 | int err = 0, sig = ksig->sig; |
274 | |
275 | frame = get_sigframe(ka: &ksig->ka, sp: regs->regs[15], frame_size: sizeof(*frame)); |
276 | |
277 | if (!access_ok(frame, sizeof(*frame))) |
278 | return -EFAULT; |
279 | |
280 | err |= setup_sigcontext(sc: &frame->sc, regs, mask: set->sig[0]); |
281 | |
282 | if (_NSIG_WORDS > 1) |
283 | err |= __copy_to_user(to: frame->extramask, from: &set->sig[1], |
284 | n: sizeof(frame->extramask)); |
285 | |
286 | /* Set up to return from userspace. If provided, use a stub |
287 | already in userspace. */ |
288 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
289 | regs->pr = (unsigned long) ksig->ka.sa.sa_restorer; |
290 | #ifdef CONFIG_VSYSCALL |
291 | } else if (likely(current->mm->context.vdso)) { |
292 | regs->pr = VDSO_SYM(&__kernel_sigreturn); |
293 | #endif |
294 | } else { |
295 | /* Generate return code (system call to sigreturn) */ |
296 | err |= __put_user(MOVW(7), &frame->retcode[0]); |
297 | err |= __put_user(TRAP_NOARG, &frame->retcode[1]); |
298 | err |= __put_user(OR_R0_R0, &frame->retcode[2]); |
299 | err |= __put_user(OR_R0_R0, &frame->retcode[3]); |
300 | err |= __put_user(OR_R0_R0, &frame->retcode[4]); |
301 | err |= __put_user(OR_R0_R0, &frame->retcode[5]); |
302 | err |= __put_user(OR_R0_R0, &frame->retcode[6]); |
303 | err |= __put_user((__NR_sigreturn), &frame->retcode[7]); |
304 | regs->pr = (unsigned long) frame->retcode; |
305 | flush_icache_range(start: regs->pr, end: regs->pr + sizeof(frame->retcode)); |
306 | } |
307 | |
308 | if (err) |
309 | return -EFAULT; |
310 | |
311 | /* Set up registers for signal handler */ |
312 | regs->regs[15] = (unsigned long) frame; |
313 | regs->regs[4] = sig; /* Arg for signal handler */ |
314 | regs->regs[5] = 0; |
315 | regs->regs[6] = (unsigned long) &frame->sc; |
316 | |
317 | if (current->personality & FDPIC_FUNCPTRS) { |
318 | struct fdpic_func_descriptor __user *funcptr = |
319 | (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler; |
320 | |
321 | err |= __get_user(regs->pc, &funcptr->text); |
322 | err |= __get_user(regs->regs[12], &funcptr->GOT); |
323 | } else |
324 | regs->pc = (unsigned long)ksig->ka.sa.sa_handler; |
325 | |
326 | if (err) |
327 | return -EFAULT; |
328 | |
329 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n" , |
330 | current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); |
331 | |
332 | return 0; |
333 | } |
334 | |
335 | static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, |
336 | struct pt_regs *regs) |
337 | { |
338 | struct rt_sigframe __user *frame; |
339 | int err = 0, sig = ksig->sig; |
340 | |
341 | frame = get_sigframe(ka: &ksig->ka, sp: regs->regs[15], frame_size: sizeof(*frame)); |
342 | |
343 | if (!access_ok(frame, sizeof(*frame))) |
344 | return -EFAULT; |
345 | |
346 | err |= copy_siginfo_to_user(to: &frame->info, from: &ksig->info); |
347 | |
348 | /* Create the ucontext. */ |
349 | err |= __put_user(0, &frame->uc.uc_flags); |
350 | err |= __put_user(NULL, &frame->uc.uc_link); |
351 | err |= __save_altstack(&frame->uc.uc_stack, regs->regs[15]); |
352 | err |= setup_sigcontext(sc: &frame->uc.uc_mcontext, |
353 | regs, mask: set->sig[0]); |
354 | err |= __copy_to_user(to: &frame->uc.uc_sigmask, from: set, n: sizeof(*set)); |
355 | |
356 | /* Set up to return from userspace. If provided, use a stub |
357 | already in userspace. */ |
358 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
359 | regs->pr = (unsigned long) ksig->ka.sa.sa_restorer; |
360 | #ifdef CONFIG_VSYSCALL |
361 | } else if (likely(current->mm->context.vdso)) { |
362 | regs->pr = VDSO_SYM(&__kernel_rt_sigreturn); |
363 | #endif |
364 | } else { |
365 | /* Generate return code (system call to rt_sigreturn) */ |
366 | err |= __put_user(MOVW(7), &frame->retcode[0]); |
367 | err |= __put_user(TRAP_NOARG, &frame->retcode[1]); |
368 | err |= __put_user(OR_R0_R0, &frame->retcode[2]); |
369 | err |= __put_user(OR_R0_R0, &frame->retcode[3]); |
370 | err |= __put_user(OR_R0_R0, &frame->retcode[4]); |
371 | err |= __put_user(OR_R0_R0, &frame->retcode[5]); |
372 | err |= __put_user(OR_R0_R0, &frame->retcode[6]); |
373 | err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]); |
374 | regs->pr = (unsigned long) frame->retcode; |
375 | flush_icache_range(start: regs->pr, end: regs->pr + sizeof(frame->retcode)); |
376 | } |
377 | |
378 | if (err) |
379 | return -EFAULT; |
380 | |
381 | /* Set up registers for signal handler */ |
382 | regs->regs[15] = (unsigned long) frame; |
383 | regs->regs[4] = sig; /* Arg for signal handler */ |
384 | regs->regs[5] = (unsigned long) &frame->info; |
385 | regs->regs[6] = (unsigned long) &frame->uc; |
386 | |
387 | if (current->personality & FDPIC_FUNCPTRS) { |
388 | struct fdpic_func_descriptor __user *funcptr = |
389 | (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler; |
390 | |
391 | err |= __get_user(regs->pc, &funcptr->text); |
392 | err |= __get_user(regs->regs[12], &funcptr->GOT); |
393 | } else |
394 | regs->pc = (unsigned long)ksig->ka.sa.sa_handler; |
395 | |
396 | if (err) |
397 | return -EFAULT; |
398 | |
399 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n" , |
400 | current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); |
401 | |
402 | return 0; |
403 | } |
404 | |
405 | static inline void |
406 | handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, |
407 | struct sigaction *sa) |
408 | { |
409 | /* If we're not from a syscall, bail out */ |
410 | if (regs->tra < 0) |
411 | return; |
412 | |
413 | /* check for system call restart.. */ |
414 | switch (regs->regs[0]) { |
415 | case -ERESTART_RESTARTBLOCK: |
416 | case -ERESTARTNOHAND: |
417 | no_system_call_restart: |
418 | regs->regs[0] = -EINTR; |
419 | break; |
420 | |
421 | case -ERESTARTSYS: |
422 | if (!(sa->sa_flags & SA_RESTART)) |
423 | goto no_system_call_restart; |
424 | fallthrough; |
425 | case -ERESTARTNOINTR: |
426 | regs->regs[0] = save_r0; |
427 | regs->pc -= instruction_size(__raw_readw(addr: regs->pc - 4)); |
428 | break; |
429 | } |
430 | } |
431 | |
432 | /* |
433 | * OK, we're invoking a handler |
434 | */ |
435 | static void |
436 | handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0) |
437 | { |
438 | sigset_t *oldset = sigmask_to_save(); |
439 | int ret; |
440 | |
441 | /* Set up the stack frame */ |
442 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
443 | ret = setup_rt_frame(ksig, set: oldset, regs); |
444 | else |
445 | ret = setup_frame(ksig, set: oldset, regs); |
446 | |
447 | signal_setup_done(failed: ret, ksig, test_thread_flag(TIF_SINGLESTEP)); |
448 | } |
449 | |
450 | /* |
451 | * Note that 'init' is a special process: it doesn't get signals it doesn't |
452 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
453 | * mistake. |
454 | * |
455 | * Note that we go through the signals twice: once to check the signals that |
456 | * the kernel can handle, and then we build all the user-level signal handling |
457 | * stack-frames in one go after that. |
458 | */ |
459 | static void do_signal(struct pt_regs *regs, unsigned int save_r0) |
460 | { |
461 | struct ksignal ksig; |
462 | |
463 | /* |
464 | * We want the common case to go fast, which |
465 | * is why we may in certain cases get here from |
466 | * kernel mode. Just return without doing anything |
467 | * if so. |
468 | */ |
469 | if (!user_mode(regs)) |
470 | return; |
471 | |
472 | if (get_signal(ksig: &ksig)) { |
473 | handle_syscall_restart(save_r0, regs, sa: &ksig.ka.sa); |
474 | |
475 | /* Whee! Actually deliver the signal. */ |
476 | handle_signal(ksig: &ksig, regs, save_r0); |
477 | return; |
478 | } |
479 | |
480 | /* Did we come from a system call? */ |
481 | if (regs->tra >= 0) { |
482 | /* Restart the system call - no handlers present */ |
483 | if (regs->regs[0] == -ERESTARTNOHAND || |
484 | regs->regs[0] == -ERESTARTSYS || |
485 | regs->regs[0] == -ERESTARTNOINTR) { |
486 | regs->regs[0] = save_r0; |
487 | regs->pc -= instruction_size(__raw_readw(addr: regs->pc - 4)); |
488 | } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { |
489 | regs->pc -= instruction_size(__raw_readw(addr: regs->pc - 4)); |
490 | regs->regs[3] = __NR_restart_syscall; |
491 | } |
492 | } |
493 | |
494 | /* |
495 | * If there's no signal to deliver, we just put the saved sigmask |
496 | * back. |
497 | */ |
498 | restore_saved_sigmask(); |
499 | } |
500 | |
501 | asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, |
502 | unsigned long thread_info_flags) |
503 | { |
504 | /* deal with pending signal delivery */ |
505 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) |
506 | do_signal(regs, save_r0); |
507 | |
508 | if (thread_info_flags & _TIF_NOTIFY_RESUME) |
509 | resume_user_mode_work(regs); |
510 | } |
511 | |