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