signal32.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. * Copyright (C) 2016, Imagination Technologies Ltd.
  10. */
  11. #include <linux/compat.h>
  12. #include <linux/compiler.h>
  13. #include <linux/errno.h>
  14. #include <linux/kernel.h>
  15. #include <linux/signal.h>
  16. #include <linux/syscalls.h>
  17. #include <asm/compat-signal.h>
  18. #include <linux/uaccess.h>
  19. #include <asm/unistd.h>
  20. #include <asm/syscalls.h>
  21. #include "signal-common.h"
  22. /* 32-bit compatibility types */
  23. typedef unsigned int __sighandler32_t;
  24. typedef void (*vfptr_t)(void);
  25. /*
  26. * Atomically swap in the new signal mask, and wait for a signal.
  27. */
  28. asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
  29. {
  30. return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
  31. }
  32. SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
  33. struct compat_sigaction __user *, oact)
  34. {
  35. struct k_sigaction new_ka, old_ka;
  36. int ret;
  37. int err = 0;
  38. if (act) {
  39. old_sigset_t mask;
  40. s32 handler;
  41. if (!access_ok(act, sizeof(*act)))
  42. return -EFAULT;
  43. err |= __get_user(handler, &act->sa_handler);
  44. new_ka.sa.sa_handler = (void __user *)(s64)handler;
  45. err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
  46. err |= __get_user(mask, &act->sa_mask.sig[0]);
  47. if (err)
  48. return -EFAULT;
  49. siginitset(&new_ka.sa.sa_mask, mask);
  50. }
  51. ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  52. if (!ret && oact) {
  53. if (!access_ok(oact, sizeof(*oact)))
  54. return -EFAULT;
  55. err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  56. err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
  57. &oact->sa_handler);
  58. err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
  59. err |= __put_user(0, &oact->sa_mask.sig[1]);
  60. err |= __put_user(0, &oact->sa_mask.sig[2]);
  61. err |= __put_user(0, &oact->sa_mask.sig[3]);
  62. if (err)
  63. return -EFAULT;
  64. }
  65. return ret;
  66. }