1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/sched.h>
18#include <linux/mm.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/kernel.h>
22#include <linux/signal.h>
23#include <linux/errno.h>
24#include <linux/wait.h>
25#include <linux/ptrace.h>
26#include <linux/unistd.h>
27#include <linux/stddef.h>
28#include <linux/elf.h>
29#include <asm/ucontext.h>
30#include <asm/uaccess.h>
31#include <asm/pgtable.h>
32
33#define DEBUG_SIG 0
34
35#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
36
37#ifndef MIN
38#define MIN(a,b) (((a) < (b)) ? (a) : (b))
39#endif
40
41#define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
42
43extern void syscall_direct_return(struct pt_regs *regs);
44
45int do_signal(sigset_t *oldset, struct pt_regs *regs);
46
47int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
48{
49 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
50 return -EFAULT;
51 if (from->si_code < 0)
52 return __copy_to_user(to, from, sizeof(siginfo_t));
53 else {
54 int err;
55
56
57
58
59
60
61 err = __put_user(from->si_signo, &to->si_signo);
62 err |= __put_user(from->si_errno, &to->si_errno);
63 err |= __put_user((short)from->si_code, &to->si_code);
64
65 err |= __put_user(from->si_pid, &to->si_pid);
66 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16:
68 break;
69 case __SI_CHLD >> 16:
70 err |= __put_user(from->si_utime, &to->si_utime);
71 err |= __put_user(from->si_stime, &to->si_stime);
72 err |= __put_user(from->si_status, &to->si_status);
73 default:
74 err |= __put_user(from->si_uid, &to->si_uid);
75 break;
76
77 }
78 return err;
79 }
80}
81
82
83
84
85int
86sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
87 struct pt_regs *regs)
88{
89 sigset_t saveset;
90
91 mask &= _BLOCKABLE;
92 spin_lock_irq(¤t->sigmask_lock);
93 saveset = current->blocked;
94 siginitset(¤t->blocked, mask);
95 recalc_sigpending(current);
96 spin_unlock_irq(¤t->sigmask_lock);
97
98 regs->result = -EINTR;
99 regs->gpr[3] = EINTR;
100 regs->ccr |= 0x10000000;
101 while (1) {
102 current->state = TASK_INTERRUPTIBLE;
103 schedule();
104 if (do_signal(&saveset, regs))
105
106
107
108
109
110
111
112
113 return regs->gpr[3];
114 }
115}
116
117int
118sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
119 int p7, struct pt_regs *regs)
120{
121 sigset_t saveset, newset;
122
123
124 if (sigsetsize != sizeof(sigset_t))
125 return -EINVAL;
126
127 if (copy_from_user(&newset, unewset, sizeof(newset)))
128 return -EFAULT;
129 sigdelsetmask(&newset, ~_BLOCKABLE);
130
131 spin_lock_irq(¤t->sigmask_lock);
132 saveset = current->blocked;
133 current->blocked = newset;
134 recalc_sigpending(current);
135 spin_unlock_irq(¤t->sigmask_lock);
136
137 regs->result = -EINTR;
138 regs->gpr[3] = EINTR;
139 regs->ccr |= 0x10000000;
140 while (1) {
141 current->state = TASK_INTERRUPTIBLE;
142 schedule();
143 if (do_signal(&saveset, regs))
144 return regs->gpr[3];
145 }
146}
147
148
149int
150sys_sigaltstack(const stack_t *uss, stack_t *uoss, int r5, int r6,
151 int r7, int r8, struct pt_regs *regs)
152{
153 return do_sigaltstack(uss, uoss, regs->gpr[1]);
154}
155
156int
157sys_sigaction(int sig, const struct old_sigaction *act,
158 struct old_sigaction *oact)
159{
160 struct k_sigaction new_ka, old_ka;
161 int ret;
162
163 if (act) {
164 old_sigset_t mask;
165 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
166 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
167 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
168 return -EFAULT;
169 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
170 __get_user(mask, &act->sa_mask);
171 siginitset(&new_ka.sa.sa_mask, mask);
172 }
173
174 ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
175
176 if (!ret && oact) {
177 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
178 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
179 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
180 return -EFAULT;
181 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
182 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
183 }
184
185 return ret;
186}
187
188
189
190
191
192
193
194
195
196
197
198struct sigregs {
199 struct mcontext mctx;
200
201
202 int abigap[56];
203};
204
205
206#define tramp mc_pad
207
208
209
210
211
212
213
214
215
216
217
218
219struct rt_sigframe
220{
221 struct siginfo info;
222 struct ucontext uc;
223
224
225 int abigap[56];
226};
227
228
229
230
231
232
233static int
234save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
235{
236
237 if (regs->msr & MSR_FP)
238 giveup_fpu(current);
239 if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
240 || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
241 ELF_NFPREG * sizeof(double)))
242 return 1;
243
244 current->thread.fpscr = 0;
245
246#ifdef CONFIG_ALTIVEC
247
248 if (current->thread.used_vr) {
249 if (regs->msr & MSR_VEC)
250 giveup_altivec(current);
251 if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
252 ELF_NVRREG * sizeof(vector128)))
253 return 1;
254
255
256 if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
257 return 1;
258 }
259
260
261
262
263
264
265
266 if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
267 return 1;
268#endif
269
270 if (sigret) {
271
272 if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
273 || __put_user(0x44000002UL, &frame->tramp[1]))
274 return 1;
275 flush_icache_range((unsigned long) &frame->tramp[0],
276 (unsigned long) &frame->tramp[2]);
277 }
278
279 return 0;
280}
281
282
283
284
285
286static int
287restore_user_regs(struct pt_regs *regs, struct mcontext *sr)
288{
289#ifdef CONFIG_ALTIVEC
290 unsigned long msr;
291#endif
292
293
294 if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
295 return 1;
296
297 if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
298 GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
299 return 1;
300
301
302
303 regs->msr &= ~MSR_FP;
304 if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
305 sizeof(sr->mc_fregs)))
306 return 1;
307
308#ifdef CONFIG_ALTIVEC
309
310
311 regs->msr &= ~MSR_VEC;
312 if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
313
314 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
315 sizeof(sr->mc_vregs)))
316 return 1;
317 } else if (current->thread.used_vr)
318 memset(¤t->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
319
320
321 if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
322 return 1;
323#endif
324
325 return 0;
326}
327
328
329
330
331static void
332restore_sigmask(sigset_t *set)
333{
334 sigdelsetmask(set, ~_BLOCKABLE);
335 spin_lock_irq(¤t->sigmask_lock);
336 current->blocked = *set;
337 recalc_sigpending(current);
338 spin_unlock_irq(¤t->sigmask_lock);
339}
340
341
342
343
344
345static void
346handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
347 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
348 unsigned long newsp)
349{
350 struct rt_sigframe *rt_sf;
351 struct mcontext *frame;
352 unsigned long origsp = newsp;
353
354
355
356 newsp -= sizeof(*rt_sf);
357 rt_sf = (struct rt_sigframe *) newsp;
358
359
360 newsp -= __SIGNAL_FRAMESIZE + 16;
361
362 if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
363 goto badframe;
364
365
366 if (__copy_to_user(&rt_sf->info, info, sizeof(*info))
367 || __put_user(0, &rt_sf->uc.uc_flags)
368 || __put_user(0, &rt_sf->uc.uc_link)
369 || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
370 || __put_user(sas_ss_flags(regs->gpr[1]),
371 &rt_sf->uc.uc_stack.ss_flags)
372 || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
373 || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
374 || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
375 goto badframe;
376
377
378 frame = &rt_sf->uc.uc_mcontext;
379 if (save_user_regs(regs, frame, 0x6666))
380 goto badframe;
381
382 if (put_user(regs->gpr[1], (unsigned long *)newsp))
383 goto badframe;
384 regs->gpr[1] = newsp;
385 regs->gpr[3] = sig;
386 regs->gpr[4] = (unsigned long) &rt_sf->info;
387 regs->gpr[5] = (unsigned long) &rt_sf->uc;
388 regs->gpr[6] = (unsigned long) rt_sf;
389 regs->nip = (unsigned long) ka->sa.sa_handler;
390 regs->link = (unsigned long) frame->tramp;
391
392 return;
393
394badframe:
395#if DEBUG_SIG
396 printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
397 regs, frame, newsp);
398#endif
399 if (sig == SIGSEGV)
400 ka->sa.sa_handler = SIG_DFL;
401 force_sig(SIGSEGV, current);
402}
403
404static int do_setcontext(struct ucontext *ucp, struct pt_regs *regs)
405{
406 sigset_t set;
407 struct mcontext *mcp;
408
409 if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
410 || __get_user(mcp, &ucp->uc_regs))
411 return -EFAULT;
412 restore_sigmask(&set);
413 if (restore_user_regs(regs, mcp))
414 return -EFAULT;
415
416 return 0;
417}
418
419int sys_swapcontext(struct ucontext *old_ctx, struct ucontext *new_ctx,
420 int r5, int r6, int r7, int r8, struct pt_regs *regs)
421{
422 unsigned char tmp;
423
424 if (old_ctx != NULL) {
425 if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
426 || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
427 || __copy_to_user(&old_ctx->uc_sigmask,
428 ¤t->blocked, sizeof(sigset_t))
429 || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
430 return -EFAULT;
431 }
432 if (new_ctx == NULL)
433 return 0;
434 if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
435 || __get_user(tmp, (u8 *) new_ctx)
436 || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
437 return -EFAULT;
438
439
440
441
442
443
444
445
446
447
448
449
450 if (do_setcontext(new_ctx, regs))
451 do_exit(SIGSEGV);
452 syscall_direct_return(regs);
453
454 return 0;
455}
456
457int sys_rt_sigreturn(struct pt_regs *regs)
458{
459 struct rt_sigframe *rt_sf;
460 stack_t st;
461
462 rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
463 if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
464 goto bad;
465 if (do_setcontext(&rt_sf->uc, regs))
466 goto bad;
467
468
469
470
471
472
473
474
475 if (__copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
476 goto bad;
477 do_sigaltstack(&st, NULL, regs->gpr[1]);
478
479 return regs->result;
480
481 bad:
482 force_sig(SIGSEGV, current);
483 return 0;
484}
485
486
487
488
489static void
490handle_signal(unsigned long sig, struct k_sigaction *ka,
491 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
492 unsigned long newsp)
493{
494 struct sigcontext *sc;
495 struct sigregs *frame;
496 unsigned long origsp = newsp;
497
498
499 newsp -= sizeof(struct sigregs);
500 frame = (struct sigregs *) newsp;
501
502
503 newsp -= sizeof(*sc);
504 sc = (struct sigcontext *) newsp;
505
506
507 newsp -= __SIGNAL_FRAMESIZE;
508
509 if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
510 goto badframe;
511
512#if _NSIG != 64
513#error "Please adjust handle_signal()"
514#endif
515 if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
516 || __put_user(oldset->sig[0], &sc->oldmask)
517 || __put_user(oldset->sig[1], &sc->_unused[3])
518 || __put_user((struct pt_regs *)frame, &sc->regs)
519 || __put_user(sig, &sc->signal))
520 goto badframe;
521
522 if (save_user_regs(regs, &frame->mctx, 0x7777))
523 goto badframe;
524
525 if (put_user(regs->gpr[1], (unsigned long *)newsp))
526 goto badframe;
527 regs->gpr[1] = newsp;
528 regs->gpr[3] = sig;
529 regs->gpr[4] = (unsigned long) sc;
530 regs->nip = (unsigned long) ka->sa.sa_handler;
531 regs->link = (unsigned long) frame->mctx.tramp;
532
533 return;
534
535badframe:
536#if DEBUG_SIG
537 printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
538 regs, frame, *newspp);
539#endif
540 if (sig == SIGSEGV)
541 ka->sa.sa_handler = SIG_DFL;
542 force_sig(SIGSEGV, current);
543}
544
545
546
547
548int sys_sigreturn(struct pt_regs *regs)
549{
550 struct sigcontext *sc, sigctx;
551 struct mcontext *sr;
552 int ret;
553 sigset_t set;
554
555 sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
556 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
557 goto badframe;
558
559 set.sig[0] = sigctx.oldmask;
560 set.sig[1] = sigctx._unused[3];
561 restore_sigmask(&set);
562
563 sr = (struct mcontext *) sigctx.regs;
564 if (verify_area(VERIFY_READ, sr, sizeof(*sr))
565 || restore_user_regs(regs, sr))
566 goto badframe;
567
568 ret = regs->result;
569
570 return ret;
571
572badframe:
573 force_sig(SIGSEGV, current);
574 return 0;
575}
576
577static int get_signal_to_deliver(struct siginfo *infop, struct pt_regs *regs)
578{
579 struct k_sigaction *ka;
580 int signr;
581
582 for (;;) {
583 spin_lock_irq(¤t->sigmask_lock);
584 signr = dequeue_signal(¤t->blocked, infop);
585 spin_unlock_irq(¤t->sigmask_lock);
586
587 if (!signr)
588 return 0;
589
590 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
591
592 current->exit_code = signr;
593 current->state = TASK_STOPPED;
594 notify_parent(current, SIGCHLD);
595 schedule();
596
597
598 if (!(signr = current->exit_code))
599 continue;
600 current->exit_code = 0;
601
602
603 if (signr == SIGSTOP)
604 continue;
605
606
607 if (signr != infop->si_signo) {
608 infop->si_signo = signr;
609 infop->si_errno = 0;
610 infop->si_code = SI_USER;
611 infop->si_pid = current->p_pptr->pid;
612 infop->si_uid = current->p_pptr->uid;
613 }
614
615
616 if (sigismember(¤t->blocked, signr)) {
617 send_sig_info(signr, infop, current);
618 continue;
619 }
620 }
621
622 ka = ¤t->sig->action[signr-1];
623 if (ka->sa.sa_handler == SIG_IGN) {
624 if (signr != SIGCHLD)
625 continue;
626
627 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
628 ;
629 continue;
630 }
631
632 if (ka->sa.sa_handler == SIG_DFL) {
633 int exit_code = signr;
634
635
636 if (current->pid == 1)
637 continue;
638
639 switch (signr) {
640 case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
641 continue;
642
643 case SIGTSTP: case SIGTTIN: case SIGTTOU:
644 if (is_orphaned_pgrp(current->pgrp))
645 continue;
646
647
648 case SIGSTOP:
649 current->state = TASK_STOPPED;
650 current->exit_code = signr;
651 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
652 notify_parent(current, SIGCHLD);
653 schedule();
654 continue;
655
656 case SIGQUIT: case SIGILL: case SIGTRAP:
657 case SIGABRT: case SIGFPE: case SIGSEGV:
658 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
659 if (do_coredump(signr, regs))
660 exit_code |= 0x80;
661
662
663 default:
664 sig_exit(signr, exit_code, infop);
665
666 }
667 }
668 return signr;
669 }
670}
671
672
673
674
675
676
677int do_signal(sigset_t *oldset, struct pt_regs *regs)
678{
679 siginfo_t info;
680 struct k_sigaction *ka;
681 unsigned long frame, newsp;
682 int signr;
683
684 if (!oldset)
685 oldset = ¤t->blocked;
686
687 newsp = frame = 0;
688
689 signr = get_signal_to_deliver(&info, regs);
690
691 ka = (signr == 0)? NULL: ¤t->sig->action[signr-1];
692
693 if (regs->trap == 0xc00) {
694 switch ((int) regs->result) {
695 case -ERESTARTSYS:
696 if (signr == 0 || (ka->sa.sa_flags & SA_RESTART))
697 goto retry;
698
699 case -ERESTARTNOHAND:
700 if (signr > 0) {
701
702 regs->result = -EINTR;
703 break;
704 }
705
706 case -ERESTARTNOINTR:
707 retry:
708
709 regs->gpr[3] = regs->orig_gpr3;
710 regs->nip -= 4;
711 regs->result = 0;
712 break;
713 }
714 }
715
716 if (signr == 0)
717 return 0;
718
719 if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
720 && !on_sig_stack(regs->gpr[1]))
721 newsp = current->sas_ss_sp + current->sas_ss_size;
722 else
723 newsp = regs->gpr[1];
724 newsp &= ~0xfUL;
725
726
727 if (ka->sa.sa_flags & SA_SIGINFO)
728 handle_rt_signal(signr, ka, &info, oldset, regs, newsp);
729 else
730 handle_signal(signr, ka, &info, oldset, regs, newsp);
731
732 if (ka->sa.sa_flags & SA_ONESHOT)
733 ka->sa.sa_handler = SIG_DFL;
734
735 if (!(ka->sa.sa_flags & SA_NODEFER)) {
736 spin_lock_irq(¤t->sigmask_lock);
737 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
738 sigaddset(¤t->blocked, signr);
739 recalc_sigpending(current);
740 spin_unlock_irq(¤t->sigmask_lock);
741 }
742
743 return 1;
744}
745
746