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