1
2
3
4
5
6
7
8
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/signal.h>
12#include <linux/errno.h>
13#include <linux/wait.h>
14#include <linux/ptrace.h>
15#include <linux/unistd.h>
16#include <linux/mm.h>
17#include <linux/smp.h>
18#include <linux/stddef.h>
19#include <linux/tty.h>
20#include <linux/binfmts.h>
21#include <linux/bitops.h>
22#include <linux/syscalls.h>
23#include <linux/tracehook.h>
24
25#include <asm/uaccess.h>
26#include <asm/sigcontext.h>
27#include <asm/ucontext.h>
28
29#include "proto.h"
30
31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36asmlinkage void ret_from_sys_call(void);
37static void do_signal(struct pt_regs *, struct switch_stack *,
38 unsigned long, unsigned long);
39
40
41
42
43
44
45SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
46{
47 sigset_t oldmask;
48 sigset_t mask;
49 unsigned long res;
50
51 siginitset(&mask, newmask & _BLOCKABLE);
52 res = sigprocmask(how, &mask, &oldmask);
53 if (!res) {
54 force_successful_syscall_return();
55 res = oldmask.sig[0];
56 }
57 return res;
58}
59
60SYSCALL_DEFINE3(osf_sigaction, int, sig,
61 const struct osf_sigaction __user *, act,
62 struct osf_sigaction __user *, oact)
63{
64 struct k_sigaction new_ka, old_ka;
65 int ret;
66
67 if (act) {
68 old_sigset_t mask;
69 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
70 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
71 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
72 __get_user(mask, &act->sa_mask))
73 return -EFAULT;
74 siginitset(&new_ka.sa.sa_mask, mask);
75 new_ka.ka_restorer = NULL;
76 }
77
78 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
79
80 if (!ret && oact) {
81 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
82 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
83 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
84 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
85 return -EFAULT;
86 }
87
88 return ret;
89}
90
91SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
92 struct sigaction __user *, oact,
93 size_t, sigsetsize, void __user *, restorer)
94{
95 struct k_sigaction new_ka, old_ka;
96 int ret;
97
98
99 if (sigsetsize != sizeof(sigset_t))
100 return -EINVAL;
101
102 if (act) {
103 new_ka.ka_restorer = restorer;
104 if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
105 return -EFAULT;
106 }
107
108 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
109
110 if (!ret && oact) {
111 if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
112 return -EFAULT;
113 }
114
115 return ret;
116}
117
118
119
120
121SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
122{
123 mask &= _BLOCKABLE;
124 spin_lock_irq(¤t->sighand->siglock);
125 current->saved_sigmask = current->blocked;
126 siginitset(¤t->blocked, mask);
127 recalc_sigpending();
128 spin_unlock_irq(¤t->sighand->siglock);
129
130 current->state = TASK_INTERRUPTIBLE;
131 schedule();
132 set_thread_flag(TIF_RESTORE_SIGMASK);
133 return -ERESTARTNOHAND;
134}
135
136asmlinkage int
137sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
138{
139 return do_sigaltstack(uss, uoss, rdusp());
140}
141
142
143
144
145
146#if _NSIG_WORDS > 1
147# error "Non SA_SIGINFO frame needs rearranging"
148#endif
149
150struct sigframe
151{
152 struct sigcontext sc;
153 unsigned int retcode[3];
154};
155
156struct rt_sigframe
157{
158 struct siginfo info;
159 struct ucontext uc;
160 unsigned int retcode[3];
161};
162
163
164
165
166extern char compile_time_assert
167 [offsetof(struct rt_sigframe, uc.uc_mcontext) == 176 ? 1 : -1];
168
169#define INSN_MOV_R30_R16 0x47fe0410
170#define INSN_LDI_R0 0x201f0000
171#define INSN_CALLSYS 0x00000083
172
173static long
174restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
175 struct switch_stack *sw)
176{
177 unsigned long usp;
178 long i, err = __get_user(regs->pc, &sc->sc_pc);
179
180 current_thread_info()->restart_block.fn = do_no_restart_syscall;
181
182 sw->r26 = (unsigned long) ret_from_sys_call;
183
184 err |= __get_user(regs->r0, sc->sc_regs+0);
185 err |= __get_user(regs->r1, sc->sc_regs+1);
186 err |= __get_user(regs->r2, sc->sc_regs+2);
187 err |= __get_user(regs->r3, sc->sc_regs+3);
188 err |= __get_user(regs->r4, sc->sc_regs+4);
189 err |= __get_user(regs->r5, sc->sc_regs+5);
190 err |= __get_user(regs->r6, sc->sc_regs+6);
191 err |= __get_user(regs->r7, sc->sc_regs+7);
192 err |= __get_user(regs->r8, sc->sc_regs+8);
193 err |= __get_user(sw->r9, sc->sc_regs+9);
194 err |= __get_user(sw->r10, sc->sc_regs+10);
195 err |= __get_user(sw->r11, sc->sc_regs+11);
196 err |= __get_user(sw->r12, sc->sc_regs+12);
197 err |= __get_user(sw->r13, sc->sc_regs+13);
198 err |= __get_user(sw->r14, sc->sc_regs+14);
199 err |= __get_user(sw->r15, sc->sc_regs+15);
200 err |= __get_user(regs->r16, sc->sc_regs+16);
201 err |= __get_user(regs->r17, sc->sc_regs+17);
202 err |= __get_user(regs->r18, sc->sc_regs+18);
203 err |= __get_user(regs->r19, sc->sc_regs+19);
204 err |= __get_user(regs->r20, sc->sc_regs+20);
205 err |= __get_user(regs->r21, sc->sc_regs+21);
206 err |= __get_user(regs->r22, sc->sc_regs+22);
207 err |= __get_user(regs->r23, sc->sc_regs+23);
208 err |= __get_user(regs->r24, sc->sc_regs+24);
209 err |= __get_user(regs->r25, sc->sc_regs+25);
210 err |= __get_user(regs->r26, sc->sc_regs+26);
211 err |= __get_user(regs->r27, sc->sc_regs+27);
212 err |= __get_user(regs->r28, sc->sc_regs+28);
213 err |= __get_user(regs->gp, sc->sc_regs+29);
214 err |= __get_user(usp, sc->sc_regs+30);
215 wrusp(usp);
216
217 for (i = 0; i < 31; i++)
218 err |= __get_user(sw->fp[i], sc->sc_fpregs+i);
219 err |= __get_user(sw->fp[31], &sc->sc_fpcr);
220
221 return err;
222}
223
224
225
226
227
228asmlinkage void
229do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,
230 struct switch_stack *sw)
231{
232 sigset_t set;
233
234
235 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
236 goto give_sigsegv;
237 if (__get_user(set.sig[0], &sc->sc_mask))
238 goto give_sigsegv;
239
240 sigdelsetmask(&set, ~_BLOCKABLE);
241 spin_lock_irq(¤t->sighand->siglock);
242 current->blocked = set;
243 recalc_sigpending();
244 spin_unlock_irq(¤t->sighand->siglock);
245
246 if (restore_sigcontext(sc, regs, sw))
247 goto give_sigsegv;
248
249
250 if (ptrace_cancel_bpt (current)) {
251 siginfo_t info;
252
253 info.si_signo = SIGTRAP;
254 info.si_errno = 0;
255 info.si_code = TRAP_BRKPT;
256 info.si_addr = (void __user *) regs->pc;
257 info.si_trapno = 0;
258 send_sig_info(SIGTRAP, &info, current);
259 }
260 return;
261
262give_sigsegv:
263 force_sig(SIGSEGV, current);
264}
265
266asmlinkage void
267do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,
268 struct switch_stack *sw)
269{
270 sigset_t set;
271
272
273 if (!access_ok(VERIFY_READ, &frame->uc, sizeof(frame->uc)))
274 goto give_sigsegv;
275 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
276 goto give_sigsegv;
277
278 sigdelsetmask(&set, ~_BLOCKABLE);
279 spin_lock_irq(¤t->sighand->siglock);
280 current->blocked = set;
281 recalc_sigpending();
282 spin_unlock_irq(¤t->sighand->siglock);
283
284 if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
285 goto give_sigsegv;
286
287
288 if (ptrace_cancel_bpt (current)) {
289 siginfo_t info;
290
291 info.si_signo = SIGTRAP;
292 info.si_errno = 0;
293 info.si_code = TRAP_BRKPT;
294 info.si_addr = (void __user *) regs->pc;
295 info.si_trapno = 0;
296 send_sig_info(SIGTRAP, &info, current);
297 }
298 return;
299
300give_sigsegv:
301 force_sig(SIGSEGV, current);
302}
303
304
305
306
307
308
309static inline void __user *
310get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
311{
312 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
313 sp = current->sas_ss_sp + current->sas_ss_size;
314
315 return (void __user *)((sp - frame_size) & -32ul);
316}
317
318static long
319setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
320 struct switch_stack *sw, unsigned long mask, unsigned long sp)
321{
322 long i, err = 0;
323
324 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
325 err |= __put_user(mask, &sc->sc_mask);
326 err |= __put_user(regs->pc, &sc->sc_pc);
327 err |= __put_user(8, &sc->sc_ps);
328
329 err |= __put_user(regs->r0 , sc->sc_regs+0);
330 err |= __put_user(regs->r1 , sc->sc_regs+1);
331 err |= __put_user(regs->r2 , sc->sc_regs+2);
332 err |= __put_user(regs->r3 , sc->sc_regs+3);
333 err |= __put_user(regs->r4 , sc->sc_regs+4);
334 err |= __put_user(regs->r5 , sc->sc_regs+5);
335 err |= __put_user(regs->r6 , sc->sc_regs+6);
336 err |= __put_user(regs->r7 , sc->sc_regs+7);
337 err |= __put_user(regs->r8 , sc->sc_regs+8);
338 err |= __put_user(sw->r9 , sc->sc_regs+9);
339 err |= __put_user(sw->r10 , sc->sc_regs+10);
340 err |= __put_user(sw->r11 , sc->sc_regs+11);
341 err |= __put_user(sw->r12 , sc->sc_regs+12);
342 err |= __put_user(sw->r13 , sc->sc_regs+13);
343 err |= __put_user(sw->r14 , sc->sc_regs+14);
344 err |= __put_user(sw->r15 , sc->sc_regs+15);
345 err |= __put_user(regs->r16, sc->sc_regs+16);
346 err |= __put_user(regs->r17, sc->sc_regs+17);
347 err |= __put_user(regs->r18, sc->sc_regs+18);
348 err |= __put_user(regs->r19, sc->sc_regs+19);
349 err |= __put_user(regs->r20, sc->sc_regs+20);
350 err |= __put_user(regs->r21, sc->sc_regs+21);
351 err |= __put_user(regs->r22, sc->sc_regs+22);
352 err |= __put_user(regs->r23, sc->sc_regs+23);
353 err |= __put_user(regs->r24, sc->sc_regs+24);
354 err |= __put_user(regs->r25, sc->sc_regs+25);
355 err |= __put_user(regs->r26, sc->sc_regs+26);
356 err |= __put_user(regs->r27, sc->sc_regs+27);
357 err |= __put_user(regs->r28, sc->sc_regs+28);
358 err |= __put_user(regs->gp , sc->sc_regs+29);
359 err |= __put_user(sp, sc->sc_regs+30);
360 err |= __put_user(0, sc->sc_regs+31);
361
362 for (i = 0; i < 31; i++)
363 err |= __put_user(sw->fp[i], sc->sc_fpregs+i);
364 err |= __put_user(0, sc->sc_fpregs+31);
365 err |= __put_user(sw->fp[31], &sc->sc_fpcr);
366
367 err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0);
368 err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1);
369 err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2);
370
371 return err;
372}
373
374static int
375setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
376 struct pt_regs *regs, struct switch_stack * sw)
377{
378 unsigned long oldsp, r26, err = 0;
379 struct sigframe __user *frame;
380
381 oldsp = rdusp();
382 frame = get_sigframe(ka, oldsp, sizeof(*frame));
383 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
384 goto give_sigsegv;
385
386 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
387 if (err)
388 goto give_sigsegv;
389
390
391
392 if (ka->ka_restorer) {
393 r26 = (unsigned long) ka->ka_restorer;
394 } else {
395 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
396 err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
397 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
398 imb();
399 r26 = (unsigned long) frame->retcode;
400 }
401
402
403 if (err)
404 goto give_sigsegv;
405
406
407 regs->r26 = r26;
408 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
409 regs->r16 = sig;
410 regs->r17 = 0;
411 regs->r18 = (unsigned long) &frame->sc;
412 wrusp((unsigned long) frame);
413
414#if DEBUG_SIG
415 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
416 current->comm, current->pid, frame, regs->pc, regs->r26);
417#endif
418
419 return 0;
420
421give_sigsegv:
422 force_sigsegv(sig, current);
423 return -EFAULT;
424}
425
426static int
427setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
428 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
429{
430 unsigned long oldsp, r26, err = 0;
431 struct rt_sigframe __user *frame;
432
433 oldsp = rdusp();
434 frame = get_sigframe(ka, oldsp, sizeof(*frame));
435 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
436 goto give_sigsegv;
437
438 err |= copy_siginfo_to_user(&frame->info, info);
439
440
441 err |= __put_user(0, &frame->uc.uc_flags);
442 err |= __put_user(0, &frame->uc.uc_link);
443 err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
444 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
445 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
446 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
447 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
448 set->sig[0], oldsp);
449 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
450 if (err)
451 goto give_sigsegv;
452
453
454
455 if (ka->ka_restorer) {
456 r26 = (unsigned long) ka->ka_restorer;
457 } else {
458 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
459 err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
460 frame->retcode+1);
461 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
462 imb();
463 r26 = (unsigned long) frame->retcode;
464 }
465
466 if (err)
467 goto give_sigsegv;
468
469
470 regs->r26 = r26;
471 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
472 regs->r16 = sig;
473 regs->r17 = (unsigned long) &frame->info;
474 regs->r18 = (unsigned long) &frame->uc;
475 wrusp((unsigned long) frame);
476
477#if DEBUG_SIG
478 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
479 current->comm, current->pid, frame, regs->pc, regs->r26);
480#endif
481
482 return 0;
483
484give_sigsegv:
485 force_sigsegv(sig, current);
486 return -EFAULT;
487}
488
489
490
491
492
493static inline int
494handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
495 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
496{
497 int ret;
498
499 if (ka->sa.sa_flags & SA_SIGINFO)
500 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
501 else
502 ret = setup_frame(sig, ka, oldset, regs, sw);
503
504 if (ret == 0) {
505 spin_lock_irq(¤t->sighand->siglock);
506 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
507 if (!(ka->sa.sa_flags & SA_NODEFER))
508 sigaddset(¤t->blocked,sig);
509 recalc_sigpending();
510 spin_unlock_irq(¤t->sighand->siglock);
511 }
512
513 return ret;
514}
515
516static inline void
517syscall_restart(unsigned long r0, unsigned long r19,
518 struct pt_regs *regs, struct k_sigaction *ka)
519{
520 switch (regs->r0) {
521 case ERESTARTSYS:
522 if (!(ka->sa.sa_flags & SA_RESTART)) {
523 case ERESTARTNOHAND:
524 regs->r0 = EINTR;
525 break;
526 }
527
528 case ERESTARTNOINTR:
529 regs->r0 = r0;
530 regs->r19 = r19;
531 regs->pc -= 4;
532 break;
533 case ERESTART_RESTARTBLOCK:
534 regs->r0 = EINTR;
535 break;
536 }
537}
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553static void
554do_signal(struct pt_regs * regs, struct switch_stack * sw,
555 unsigned long r0, unsigned long r19)
556{
557 siginfo_t info;
558 int signr;
559 unsigned long single_stepping = ptrace_cancel_bpt(current);
560 struct k_sigaction ka;
561 sigset_t *oldset;
562
563 if (test_thread_flag(TIF_RESTORE_SIGMASK))
564 oldset = ¤t->saved_sigmask;
565 else
566 oldset = ¤t->blocked;
567
568
569 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
570
571
572 single_stepping |= ptrace_cancel_bpt(current);
573
574 if (signr > 0) {
575
576 if (r0)
577 syscall_restart(r0, r19, regs, &ka);
578 if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) {
579
580
581
582
583 if (test_thread_flag(TIF_RESTORE_SIGMASK))
584 clear_thread_flag(TIF_RESTORE_SIGMASK);
585 }
586 if (single_stepping)
587 ptrace_set_bpt(current);
588 return;
589 }
590
591 if (r0) {
592 switch (regs->r0) {
593 case ERESTARTNOHAND:
594 case ERESTARTSYS:
595 case ERESTARTNOINTR:
596
597 regs->r0 = r0;
598 regs->r19 = r19;
599 regs->pc -= 4;
600 break;
601 case ERESTART_RESTARTBLOCK:
602
603 regs->r0 = __NR_restart_syscall;
604 regs->pc -= 4;
605 break;
606 }
607 }
608
609
610 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
611 clear_thread_flag(TIF_RESTORE_SIGMASK);
612 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
613 }
614
615 if (single_stepping)
616 ptrace_set_bpt(current);
617}
618
619void
620do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
621 unsigned long thread_info_flags,
622 unsigned long r0, unsigned long r19)
623{
624 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
625 do_signal(regs, sw, r0, r19);
626
627 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
628 clear_thread_flag(TIF_NOTIFY_RESUME);
629 tracehook_notify_resume(regs);
630 if (current->replacement_session_keyring)
631 key_replace_session_keyring();
632 }
633}
634