Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
signal32.c
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License. See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1991, 1992 Linus Torvalds
7  * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9  */
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <linux/smp.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/syscalls.h>
18 #include <linux/errno.h>
19 #include <linux/wait.h>
20 #include <linux/ptrace.h>
21 #include <linux/suspend.h>
22 #include <linux/compiler.h>
23 #include <linux/uaccess.h>
24 
25 #include <asm/abi.h>
26 #include <asm/asm.h>
27 #include <asm/compat-signal.h>
28 #include <linux/bitops.h>
29 #include <asm/cacheflush.h>
30 #include <asm/sim.h>
31 #include <asm/ucontext.h>
32 #include <asm/fpu.h>
33 #include <asm/war.h>
34 #include <asm/vdso.h>
35 #include <asm/dsp.h>
36 
37 #include "signal-common.h"
38 
39 static int (*save_fp_context32)(struct sigcontext32 __user *sc);
40 static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
41 
42 extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43 extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44 
45 extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
46 extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
47 
48 /*
49  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
50  */
51 #define __NR_O32_restart_syscall 4253
52 
53 /* 32-bit compatibility types */
54 
55 typedef unsigned int __sighandler32_t;
56 typedef void (*vfptr_t)(void);
57 
58 struct sigaction32 {
59  unsigned int sa_flags;
61  compat_sigset_t sa_mask;
62 };
63 
64 /* IRIX compatible stack_t */
65 typedef struct sigaltstack32 {
68  int ss_flags;
69 } stack32_t;
70 
71 struct ucontext32 {
76  compat_sigset_t uc_sigmask; /* mask last for extensibility */
77 };
78 
79 struct sigframe32 {
80  u32 sf_ass[4]; /* argument save space for o32 */
81  u32 sf_pad[2]; /* Was: signal trampoline */
83  compat_sigset_t sf_mask;
84 };
85 
86 struct rt_sigframe32 {
87  u32 rs_ass[4]; /* argument save space for o32 */
88  u32 rs_pad[2]; /* Was: signal trampoline */
90  struct ucontext32 rs_uc;
91 };
92 
93 /*
94  * sigcontext handlers
95  */
96 static int protected_save_fp_context32(struct sigcontext32 __user *sc)
97 {
98  int err;
99  while (1) {
100  lock_fpu_owner();
101  own_fpu_inatomic(1);
102  err = save_fp_context32(sc); /* this might fail */
104  if (likely(!err))
105  break;
106  /* touch the sigcontext and try again */
107  err = __put_user(0, &sc->sc_fpregs[0]) |
108  __put_user(0, &sc->sc_fpregs[31]) |
109  __put_user(0, &sc->sc_fpc_csr);
110  if (err)
111  break; /* really bad sigcontext */
112  }
113  return err;
114 }
115 
116 static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
117 {
118  int err, tmp __maybe_unused;
119  while (1) {
120  lock_fpu_owner();
121  own_fpu_inatomic(0);
122  err = restore_fp_context32(sc); /* this might fail */
124  if (likely(!err))
125  break;
126  /* touch the sigcontext and try again */
127  err = __get_user(tmp, &sc->sc_fpregs[0]) |
128  __get_user(tmp, &sc->sc_fpregs[31]) |
129  __get_user(tmp, &sc->sc_fpc_csr);
130  if (err)
131  break; /* really bad sigcontext */
132  }
133  return err;
134 }
135 
136 static int setup_sigcontext32(struct pt_regs *regs,
137  struct sigcontext32 __user *sc)
138 {
139  int err = 0;
140  int i;
141  u32 used_math;
142 
143  err |= __put_user(regs->cp0_epc, &sc->sc_pc);
144 
145  err |= __put_user(0, &sc->sc_regs[0]);
146  for (i = 1; i < 32; i++)
147  err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
148 
149  err |= __put_user(regs->hi, &sc->sc_mdhi);
150  err |= __put_user(regs->lo, &sc->sc_mdlo);
151  if (cpu_has_dsp) {
152  err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
153  err |= __put_user(mfhi1(), &sc->sc_hi1);
154  err |= __put_user(mflo1(), &sc->sc_lo1);
155  err |= __put_user(mfhi2(), &sc->sc_hi2);
156  err |= __put_user(mflo2(), &sc->sc_lo2);
157  err |= __put_user(mfhi3(), &sc->sc_hi3);
158  err |= __put_user(mflo3(), &sc->sc_lo3);
159  }
160 
161  used_math = !!used_math();
162  err |= __put_user(used_math, &sc->sc_used_math);
163 
164  if (used_math) {
165  /*
166  * Save FPU state to signal context. Signal handler
167  * will "inherit" current FPU state.
168  */
169  err |= protected_save_fp_context32(sc);
170  }
171  return err;
172 }
173 
174 static int
175 check_and_restore_fp_context32(struct sigcontext32 __user *sc)
176 {
177  int err, sig;
178 
179  err = sig = fpcsr_pending(&sc->sc_fpc_csr);
180  if (err > 0)
181  err = 0;
182  err |= protected_restore_fp_context32(sc);
183  return err ?: sig;
184 }
185 
186 static int restore_sigcontext32(struct pt_regs *regs,
187  struct sigcontext32 __user *sc)
188 {
189  u32 used_math;
190  int err = 0;
191  s32 treg;
192  int i;
193 
194  /* Always make any pending restarted system calls return -EINTR */
195  current_thread_info()->restart_block.fn = do_no_restart_syscall;
196 
197  err |= __get_user(regs->cp0_epc, &sc->sc_pc);
198  err |= __get_user(regs->hi, &sc->sc_mdhi);
199  err |= __get_user(regs->lo, &sc->sc_mdlo);
200  if (cpu_has_dsp) {
201  err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
202  err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
203  err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
204  err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
205  err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
206  err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
207  err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
208  }
209 
210  for (i = 1; i < 32; i++)
211  err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
212 
213  err |= __get_user(used_math, &sc->sc_used_math);
214  conditional_used_math(used_math);
215 
216  if (used_math) {
217  /* restore fpu context if we have used it before */
218  if (!err)
219  err = check_and_restore_fp_context32(sc);
220  } else {
221  /* signal handler may have used FPU. Give it up. */
222  lose_fpu(0);
223  }
224 
225  return err;
226 }
227 
228 /*
229  *
230  */
231 extern void __put_sigset_unknown_nsig(void);
232 extern void __get_sigset_unknown_nsig(void);
233 
234 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
235 {
236  int err = 0;
237 
238  if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
239  return -EFAULT;
240 
241  switch (_NSIG_WORDS) {
242  default:
244  case 2:
245  err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
246  err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
247  case 1:
248  err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
249  err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
250  }
251 
252  return err;
253 }
254 
255 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
256 {
257  int err = 0;
258  unsigned long sig[4];
259 
260  if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
261  return -EFAULT;
262 
263  switch (_NSIG_WORDS) {
264  default:
266  case 2:
267  err |= __get_user(sig[3], &ubuf->sig[3]);
268  err |= __get_user(sig[2], &ubuf->sig[2]);
269  kbuf->sig[1] = sig[2] | (sig[3] << 32);
270  case 1:
271  err |= __get_user(sig[1], &ubuf->sig[1]);
272  err |= __get_user(sig[0], &ubuf->sig[0]);
273  kbuf->sig[0] = sig[0] | (sig[1] << 32);
274  }
275 
276  return err;
277 }
278 
279 /*
280  * Atomically swap in the new signal mask, and wait for a signal.
281  */
282 
283 asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
284 {
285  compat_sigset_t __user *uset;
286  sigset_t newset;
287 
288  uset = (compat_sigset_t __user *) regs.regs[4];
289  if (get_sigset(&newset, uset))
290  return -EFAULT;
291  return sigsuspend(&newset);
292 }
293 
294 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
295 {
296  compat_sigset_t __user *uset;
297  sigset_t newset;
298  size_t sigsetsize;
299 
300  /* XXX Don't preclude handling different sized sigset_t's. */
301  sigsetsize = regs.regs[5];
302  if (sigsetsize != sizeof(compat_sigset_t))
303  return -EINVAL;
304 
305  uset = (compat_sigset_t __user *) regs.regs[4];
306  if (get_sigset(&newset, uset))
307  return -EFAULT;
308  return sigsuspend(&newset);
309 }
310 
311 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
312  struct sigaction32 __user *, oact)
313 {
314  struct k_sigaction new_ka, old_ka;
315  int ret;
316  int err = 0;
317 
318  if (act) {
320  s32 handler;
321 
322  if (!access_ok(VERIFY_READ, act, sizeof(*act)))
323  return -EFAULT;
324  err |= __get_user(handler, &act->sa_handler);
325  new_ka.sa.sa_handler = (void __user *)(s64)handler;
326  err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
327  err |= __get_user(mask, &act->sa_mask.sig[0]);
328  if (err)
329  return -EFAULT;
330 
331  siginitset(&new_ka.sa.sa_mask, mask);
332  }
333 
334  ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
335 
336  if (!ret && oact) {
337  if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
338  return -EFAULT;
339  err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
340  err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
341  &oact->sa_handler);
342  err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
343  err |= __put_user(0, &oact->sa_mask.sig[1]);
344  err |= __put_user(0, &oact->sa_mask.sig[2]);
345  err |= __put_user(0, &oact->sa_mask.sig[3]);
346  if (err)
347  return -EFAULT;
348  }
349 
350  return ret;
351 }
352 
353 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
354 {
355  const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
356  stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
357  unsigned long usp = regs.regs[29];
358  stack_t kss, koss;
359  int ret, err = 0;
360  mm_segment_t old_fs = get_fs();
361  s32 sp;
362 
363  if (uss) {
364  if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
365  return -EFAULT;
366  err |= __get_user(sp, &uss->ss_sp);
367  kss.ss_sp = (void __user *) (long) sp;
368  err |= __get_user(kss.ss_size, &uss->ss_size);
369  err |= __get_user(kss.ss_flags, &uss->ss_flags);
370  if (err)
371  return -EFAULT;
372  }
373 
374  set_fs(KERNEL_DS);
375  ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
376  uoss ? (stack_t __user *)&koss : NULL, usp);
377  set_fs(old_fs);
378 
379  if (!ret && uoss) {
380  if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
381  return -EFAULT;
382  sp = (int) (unsigned long) koss.ss_sp;
383  err |= __put_user(sp, &uoss->ss_sp);
384  err |= __put_user(koss.ss_size, &uoss->ss_size);
385  err |= __put_user(koss.ss_flags, &uoss->ss_flags);
386  if (err)
387  return -EFAULT;
388  }
389  return ret;
390 }
391 
393 {
394  int err;
395 
396  if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
397  return -EFAULT;
398 
399  /* If you change siginfo_t structure, please be sure
400  this code is fixed accordingly.
401  It should never copy any pad contained in the structure
402  to avoid security leaks, but must copy the generic
403  3 ints plus the relevant union member.
404  This routine must convert siginfo from 64bit to 32bit as well
405  at the same time. */
406  err = __put_user(from->si_signo, &to->si_signo);
407  err |= __put_user(from->si_errno, &to->si_errno);
408  err |= __put_user((short)from->si_code, &to->si_code);
409  if (from->si_code < 0)
410  err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
411  else {
412  switch (from->si_code >> 16) {
413  case __SI_TIMER >> 16:
414  err |= __put_user(from->si_tid, &to->si_tid);
415  err |= __put_user(from->si_overrun, &to->si_overrun);
416  err |= __put_user(from->si_int, &to->si_int);
417  break;
418  case __SI_CHLD >> 16:
419  err |= __put_user(from->si_utime, &to->si_utime);
420  err |= __put_user(from->si_stime, &to->si_stime);
421  err |= __put_user(from->si_status, &to->si_status);
422  default:
423  err |= __put_user(from->si_pid, &to->si_pid);
424  err |= __put_user(from->si_uid, &to->si_uid);
425  break;
426  case __SI_FAULT >> 16:
427  err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
428  break;
429  case __SI_POLL >> 16:
430  err |= __put_user(from->si_band, &to->si_band);
431  err |= __put_user(from->si_fd, &to->si_fd);
432  break;
433  case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
434  case __SI_MESGQ >> 16:
435  err |= __put_user(from->si_pid, &to->si_pid);
436  err |= __put_user(from->si_uid, &to->si_uid);
437  err |= __put_user(from->si_int, &to->si_int);
438  break;
439  }
440  }
441  return err;
442 }
443 
445 {
446  memset(to, 0, sizeof *to);
447 
448  if (copy_from_user(to, from, 3*sizeof(int)) ||
450  from->_sifields._pad, SI_PAD_SIZE32))
451  return -EFAULT;
452 
453  return 0;
454 }
455 
456 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
457 {
458  struct sigframe32 __user *frame;
459  sigset_t blocked;
460  int sig;
461 
462  frame = (struct sigframe32 __user *) regs.regs[29];
463  if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
464  goto badframe;
465  if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
466  goto badframe;
467 
468  set_current_blocked(&blocked);
469 
470  sig = restore_sigcontext32(&regs, &frame->sf_sc);
471  if (sig < 0)
472  goto badframe;
473  else if (sig)
474  force_sig(sig, current);
475 
476  /*
477  * Don't let your children do this ...
478  */
479  __asm__ __volatile__(
480  "move\t$29, %0\n\t"
481  "j\tsyscall_exit"
482  :/* no outputs */
483  :"r" (&regs));
484  /* Unreached */
485 
486 badframe:
488 }
489 
490 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
491 {
492  struct rt_sigframe32 __user *frame;
493  mm_segment_t old_fs;
494  sigset_t set;
495  stack_t st;
496  s32 sp;
497  int sig;
498 
499  frame = (struct rt_sigframe32 __user *) regs.regs[29];
500  if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
501  goto badframe;
502  if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
503  goto badframe;
504 
505  set_current_blocked(&set);
506 
507  sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
508  if (sig < 0)
509  goto badframe;
510  else if (sig)
511  force_sig(sig, current);
512 
513  /* The ucontext contains a stack32_t, so we must convert! */
514  if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
515  goto badframe;
516  st.ss_sp = (void __user *)(long) sp;
517  if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
518  goto badframe;
519  if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
520  goto badframe;
521 
522  /* It is more difficult to avoid calling this function than to
523  call it and ignore errors. */
524  old_fs = get_fs();
525  set_fs(KERNEL_DS);
526  do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
527  set_fs(old_fs);
528 
529  /*
530  * Don't let your children do this ...
531  */
532  __asm__ __volatile__(
533  "move\t$29, %0\n\t"
534  "j\tsyscall_exit"
535  :/* no outputs */
536  :"r" (&regs));
537  /* Unreached */
538 
539 badframe:
541 }
542 
543 static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
544  struct pt_regs *regs, int signr, sigset_t *set)
545 {
546  struct sigframe32 __user *frame;
547  int err = 0;
548 
549  frame = get_sigframe(ka, regs, sizeof(*frame));
550  if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
551  goto give_sigsegv;
552 
553  err |= setup_sigcontext32(regs, &frame->sf_sc);
554  err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
555 
556  if (err)
557  goto give_sigsegv;
558 
559  /*
560  * Arguments to signal handler:
561  *
562  * a0 = signal number
563  * a1 = 0 (should be cause)
564  * a2 = pointer to struct sigcontext
565  *
566  * $25 and c0_epc point to the signal handler, $29 points to the
567  * struct sigframe.
568  */
569  regs->regs[ 4] = signr;
570  regs->regs[ 5] = 0;
571  regs->regs[ 6] = (unsigned long) &frame->sf_sc;
572  regs->regs[29] = (unsigned long) frame;
573  regs->regs[31] = (unsigned long) sig_return;
574  regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
575 
576  DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
577  current->comm, current->pid,
578  frame, regs->cp0_epc, regs->regs[31]);
579 
580  return 0;
581 
582 give_sigsegv:
583  force_sigsegv(signr, current);
584  return -EFAULT;
585 }
586 
587 static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
588  struct pt_regs *regs, int signr, sigset_t *set,
589  siginfo_t *info)
590 {
591  struct rt_sigframe32 __user *frame;
592  int err = 0;
593  s32 sp;
594 
595  frame = get_sigframe(ka, regs, sizeof(*frame));
596  if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
597  goto give_sigsegv;
598 
599  /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
600  err |= copy_siginfo_to_user32(&frame->rs_info, info);
601 
602  /* Create the ucontext. */
603  err |= __put_user(0, &frame->rs_uc.uc_flags);
604  err |= __put_user(0, &frame->rs_uc.uc_link);
605  sp = (int) (long) current->sas_ss_sp;
606  err |= __put_user(sp,
607  &frame->rs_uc.uc_stack.ss_sp);
608  err |= __put_user(sas_ss_flags(regs->regs[29]),
609  &frame->rs_uc.uc_stack.ss_flags);
610  err |= __put_user(current->sas_ss_size,
611  &frame->rs_uc.uc_stack.ss_size);
612  err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
613  err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
614 
615  if (err)
616  goto give_sigsegv;
617 
618  /*
619  * Arguments to signal handler:
620  *
621  * a0 = signal number
622  * a1 = 0 (should be cause)
623  * a2 = pointer to ucontext
624  *
625  * $25 and c0_epc point to the signal handler, $29 points to
626  * the struct rt_sigframe32.
627  */
628  regs->regs[ 4] = signr;
629  regs->regs[ 5] = (unsigned long) &frame->rs_info;
630  regs->regs[ 6] = (unsigned long) &frame->rs_uc;
631  regs->regs[29] = (unsigned long) frame;
632  regs->regs[31] = (unsigned long) sig_return;
633  regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
634 
635  DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
636  current->comm, current->pid,
637  frame, regs->cp0_epc, regs->regs[31]);
638 
639  return 0;
640 
641 give_sigsegv:
642  force_sigsegv(signr, current);
643  return -EFAULT;
644 }
645 
646 /*
647  * o32 compatibility on 64-bit kernels, without DSP ASE
648  */
650  .setup_frame = setup_frame_32,
651  .signal_return_offset =
652  offsetof(struct mips_vdso, o32_signal_trampoline),
653  .setup_rt_frame = setup_rt_frame_32,
654  .rt_signal_return_offset =
655  offsetof(struct mips_vdso, o32_rt_signal_trampoline),
656  .restart = __NR_O32_restart_syscall
657 };
658 
659 SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
660  const struct sigaction32 __user *, act,
661  struct sigaction32 __user *, oact, unsigned int, sigsetsize)
662 {
663  struct k_sigaction new_sa, old_sa;
664  int ret = -EINVAL;
665 
666  /* XXX: Don't preclude handling different sized sigset_t's. */
667  if (sigsetsize != sizeof(sigset_t))
668  goto out;
669 
670  if (act) {
671  s32 handler;
672  int err = 0;
673 
674  if (!access_ok(VERIFY_READ, act, sizeof(*act)))
675  return -EFAULT;
676  err |= __get_user(handler, &act->sa_handler);
677  new_sa.sa.sa_handler = (void __user *)(s64)handler;
678  err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
679  err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
680  if (err)
681  return -EFAULT;
682  }
683 
684  ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
685 
686  if (!ret && oact) {
687  int err = 0;
688 
689  if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
690  return -EFAULT;
691 
692  err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
693  &oact->sa_handler);
694  err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
695  err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
696  if (err)
697  return -EFAULT;
698  }
699 out:
700  return ret;
701 }
702 
703 SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
704  compat_sigset_t __user *, oset, unsigned int, sigsetsize)
705 {
706  sigset_t old_set, new_set;
707  int ret;
708  mm_segment_t old_fs = get_fs();
709 
710  if (set && get_sigset(&new_set, set))
711  return -EFAULT;
712 
713  set_fs(KERNEL_DS);
714  ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
715  oset ? (sigset_t __user *)&old_set : NULL,
716  sigsetsize);
717  set_fs(old_fs);
718 
719  if (!ret && oset && put_sigset(&old_set, oset))
720  return -EFAULT;
721 
722  return ret;
723 }
724 
725 SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
726  unsigned int, sigsetsize)
727 {
728  int ret;
729  sigset_t set;
730  mm_segment_t old_fs = get_fs();
731 
732  set_fs(KERNEL_DS);
733  ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
734  set_fs(old_fs);
735 
736  if (!ret && put_sigset(&set, uset))
737  return -EFAULT;
738 
739  return ret;
740 }
741 
742 SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
743  compat_siginfo_t __user *, uinfo)
744 {
745  siginfo_t info;
746  int ret;
747  mm_segment_t old_fs = get_fs();
748 
749  if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
750  copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
751  return -EFAULT;
752  set_fs(KERNEL_DS);
753  ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
754  set_fs(old_fs);
755  return ret;
756 }
757 
758 SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
759  compat_siginfo_t __user *, uinfo, int, options,
760  struct compat_rusage __user *, uru)
761 {
762  siginfo_t info;
763  struct rusage ru;
764  long ret;
765  mm_segment_t old_fs = get_fs();
766 
767  info.si_signo = 0;
768  set_fs(KERNEL_DS);
769  ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
770  uru ? (struct rusage __user *) &ru : NULL);
771  set_fs(old_fs);
772 
773  if (ret < 0 || info.si_signo == 0)
774  return ret;
775 
776  if (uru && (ret = put_compat_rusage(&ru, uru)))
777  return ret;
778 
779  BUG_ON(info.si_code & __SI_MASK);
780  info.si_code |= __SI_CHLD;
781  return copy_siginfo_to_user32(uinfo, &info);
782 }
783 
784 static int signal32_init(void)
785 {
786  if (cpu_has_fpu) {
787  save_fp_context32 = _save_fp_context32;
788  restore_fp_context32 = _restore_fp_context32;
789  } else {
790  save_fp_context32 = fpu_emulator_save_context32;
791  restore_fp_context32 = fpu_emulator_restore_context32;
792  }
793 
794  return 0;
795 }
796 
797 arch_initcall(signal32_init);