Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | |
dda73d0b | 7 | * Copyright (C) 1994 - 2000, 2006 Ralf Baechle |
1da177e4 | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
d1e63c94 | 9 | * Copyright (C) 2016, Imagination Technologies Ltd. |
1da177e4 | 10 | */ |
0d55303c | 11 | #include <linux/compat.h> |
d1e63c94 HH |
12 | #include <linux/compiler.h> |
13 | #include <linux/errno.h> | |
1da177e4 LT |
14 | #include <linux/kernel.h> |
15 | #include <linux/signal.h> | |
16 | #include <linux/syscalls.h> | |
1da177e4 | 17 | |
431dc804 | 18 | #include <asm/compat-signal.h> |
7c0f6ba6 | 19 | #include <linux/uaccess.h> |
d1e63c94 | 20 | #include <asm/unistd.h> |
be018aaa | 21 | #include <asm/syscalls.h> |
1da177e4 | 22 | |
36a1f2c2 FBH |
23 | #include "signal-common.h" |
24 | ||
1da177e4 LT |
25 | /* 32-bit compatibility types */ |
26 | ||
1da177e4 LT |
27 | typedef unsigned int __sighandler32_t; |
28 | typedef void (*vfptr_t)(void); | |
29 | ||
1da177e4 LT |
30 | /* |
31 | * Atomically swap in the new signal mask, and wait for a signal. | |
32 | */ | |
33 | ||
1910f4ab | 34 | asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset) |
1da177e4 | 35 | { |
1910f4ab | 36 | return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t)); |
1da177e4 LT |
37 | } |
38 | ||
aa584802 AV |
39 | SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act, |
40 | struct compat_sigaction __user *, oact) | |
1da177e4 LT |
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; | |
77c728c2 | 48 | s32 handler; |
1da177e4 | 49 | |
96d4f267 | 50 | if (!access_ok(act, sizeof(*act))) |
1da177e4 | 51 | return -EFAULT; |
77c728c2 | 52 | err |= __get_user(handler, &act->sa_handler); |
9bbf28a3 | 53 | new_ka.sa.sa_handler = (void __user *)(s64)handler; |
1da177e4 LT |
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) { | |
96d4f267 | 65 | if (!access_ok(oact, sizeof(*oact))) |
6254944f | 66 | return -EFAULT; |
1da177e4 LT |
67 | err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
68 | err |= __put_user((u32)(u64)old_ka.sa.sa_handler, | |
70342287 | 69 | &oact->sa_handler); |
1da177e4 | 70 | err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); |
6254944f MM |
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) | |
1da177e4 LT |
75 | return -EFAULT; |
76 | } | |
77 | ||
78 | return ret; | |
79 | } |