0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/compat.h>
0012 #include <linux/compiler.h>
0013 #include <linux/errno.h>
0014 #include <linux/kernel.h>
0015 #include <linux/signal.h>
0016 #include <linux/syscalls.h>
0017
0018 #include <asm/compat-signal.h>
0019 #include <linux/uaccess.h>
0020 #include <asm/unistd.h>
0021
0022 #include "signal-common.h"
0023
0024
0025
0026 typedef unsigned int __sighandler32_t;
0027 typedef void (*vfptr_t)(void);
0028
0029
0030
0031
0032
0033 asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
0034 {
0035 return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
0036 }
0037
0038 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
0039 struct compat_sigaction __user *, oact)
0040 {
0041 struct k_sigaction new_ka, old_ka;
0042 int ret;
0043 int err = 0;
0044
0045 if (act) {
0046 old_sigset_t mask;
0047 s32 handler;
0048
0049 if (!access_ok(act, sizeof(*act)))
0050 return -EFAULT;
0051 err |= __get_user(handler, &act->sa_handler);
0052 new_ka.sa.sa_handler = (void __user *)(s64)handler;
0053 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
0054 err |= __get_user(mask, &act->sa_mask.sig[0]);
0055 if (err)
0056 return -EFAULT;
0057
0058 siginitset(&new_ka.sa.sa_mask, mask);
0059 }
0060
0061 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
0062
0063 if (!ret && oact) {
0064 if (!access_ok(oact, sizeof(*oact)))
0065 return -EFAULT;
0066 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
0067 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
0068 &oact->sa_handler);
0069 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
0070 err |= __put_user(0, &oact->sa_mask.sig[1]);
0071 err |= __put_user(0, &oact->sa_mask.sig[2]);
0072 err |= __put_user(0, &oact->sa_mask.sig[3]);
0073 if (err)
0074 return -EFAULT;
0075 }
0076
0077 return ret;
0078 }