signal32.c 2.0 KB

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