2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
2006-02-18 15:21:30 +00:00
|
|
|
* Copyright (C) 1994 - 2000, 2006 Ralf Baechle
|
2005-04-16 22:20:36 +00:00
|
|
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
2016-06-17 15:03:45 +00:00
|
|
|
* Copyright (C) 2016, Imagination Technologies Ltd.
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
2018-03-14 04:03:25 +00:00
|
|
|
#include <linux/compat.h>
|
2016-06-17 15:03:45 +00:00
|
|
|
#include <linux/compiler.h>
|
|
|
|
#include <linux/errno.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/signal.h>
|
|
|
|
#include <linux/syscalls.h>
|
|
|
|
|
2007-02-13 00:05:11 +00:00
|
|
|
#include <asm/compat-signal.h>
|
2016-12-24 19:46:01 +00:00
|
|
|
#include <linux/uaccess.h>
|
2016-06-17 15:03:45 +00:00
|
|
|
#include <asm/unistd.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-02-05 14:24:22 +00:00
|
|
|
#include "signal-common.h"
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* 32-bit compatibility types */
|
|
|
|
|
|
|
|
typedef unsigned int __sighandler32_t;
|
|
|
|
typedef void (*vfptr_t)(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Atomically swap in the new signal mask, and wait for a signal.
|
|
|
|
*/
|
|
|
|
|
2012-12-25 21:25:18 +00:00
|
|
|
asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2012-12-25 21:25:18 +00:00
|
|
|
return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2012-12-25 23:55:27 +00:00
|
|
|
SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
|
|
|
|
struct compat_sigaction __user *, oact)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct k_sigaction new_ka, old_ka;
|
|
|
|
int ret;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (act) {
|
|
|
|
old_sigset_t mask;
|
2005-03-04 19:36:51 +00:00
|
|
|
s32 handler;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
|
|
|
|
return -EFAULT;
|
2005-03-04 19:36:51 +00:00
|
|
|
err |= __get_user(handler, &act->sa_handler);
|
2006-01-31 16:41:09 +00:00
|
|
|
new_ka.sa.sa_handler = (void __user *)(s64)handler;
|
2005-04-16 22:20:36 +00:00
|
|
|
err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
|
|
|
|
err |= __get_user(mask, &act->sa_mask.sig[0]);
|
|
|
|
if (err)
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
siginitset(&new_ka.sa.sa_mask, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
|
|
|
|
|
|
|
|
if (!ret && oact) {
|
|
|
|
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
|
2006-02-18 20:06:32 +00:00
|
|
|
return -EFAULT;
|
2005-04-16 22:20:36 +00:00
|
|
|
err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
|
|
|
|
err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
|
2013-01-22 11:59:30 +00:00
|
|
|
&oact->sa_handler);
|
2005-04-16 22:20:36 +00:00
|
|
|
err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
|
2006-02-18 20:06:32 +00:00
|
|
|
err |= __put_user(0, &oact->sa_mask.sig[1]);
|
|
|
|
err |= __put_user(0, &oact->sa_mask.sig[2]);
|
|
|
|
err |= __put_user(0, &oact->sa_mask.sig[3]);
|
|
|
|
if (err)
|
2005-04-16 22:20:36 +00:00
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|