aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 21:50:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 21:50:11 -0500
commit9e2d59ad580d590134285f361a0e80f0e98c0207 (patch)
treef3232be75781484193413f32ec82c21f6d8eb76e /kernel
parent5ce1a70e2f00f0bce0cab57f798ca354b9496169 (diff)
parent235b80226b986dabcbba844968f7807866bd0bfe (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro: "This is the first pile; another one will come a bit later and will contain SYSCALL_DEFINE-related patches. - a bunch of signal-related syscalls (both native and compat) unified. - a bunch of compat syscalls switched to COMPAT_SYSCALL_DEFINE (fixing several potential problems with missing argument validation, while we are at it) - a lot of now-pointless wrappers killed - a couple of architectures (cris and hexagon) forgot to save altstack settings into sigframe, even though they used the (uninitialized) values in sigreturn; fixed. - microblaze fixes for delivery of multiple signals arriving at once - saner set of helpers for signal delivery introduced, several architectures switched to using those." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (143 commits) x86: convert to ksignal sparc: convert to ksignal arm: switch to struct ksignal * passing alpha: pass k_sigaction and siginfo_t using ksignal pointer burying unused conditionals make do_sigaltstack() static arm64: switch to generic old sigaction() (compat-only) arm64: switch to generic compat rt_sigaction() arm64: switch compat to generic old sigsuspend arm64: switch to generic compat rt_sigqueueinfo() arm64: switch to generic compat rt_sigpending() arm64: switch to generic compat rt_sigprocmask() arm64: switch to generic sigaltstack sparc: switch to generic old sigsuspend sparc: COMPAT_SYSCALL_DEFINE does all sign-extension as well as SYSCALL_DEFINE sparc: kill sign-extending wrappers for native syscalls kill sparc32_open() sparc: switch to use of generic old sigaction sparc: switch sys_compat_rt_sigaction() to COMPAT_SYSCALL_DEFINE mips: switch to generic sys_fork() and sys_clone() ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/compat.c72
-rw-r--r--kernel/futex_compat.c19
-rw-r--r--kernel/signal.c332
3 files changed, 329 insertions, 94 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index f4bddb900186..19971d8c7299 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -290,8 +290,8 @@ static inline long put_compat_itimerval(struct compat_itimerval __user *o,
290 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec))); 290 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
291} 291}
292 292
293asmlinkage long compat_sys_getitimer(int which, 293COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
294 struct compat_itimerval __user *it) 294 struct compat_itimerval __user *, it)
295{ 295{
296 struct itimerval kit; 296 struct itimerval kit;
297 int error; 297 int error;
@@ -302,9 +302,9 @@ asmlinkage long compat_sys_getitimer(int which,
302 return error; 302 return error;
303} 303}
304 304
305asmlinkage long compat_sys_setitimer(int which, 305COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
306 struct compat_itimerval __user *in, 306 struct compat_itimerval __user *, in,
307 struct compat_itimerval __user *out) 307 struct compat_itimerval __user *, out)
308{ 308{
309 struct itimerval kin, kout; 309 struct itimerval kin, kout;
310 int error; 310 int error;
@@ -381,9 +381,9 @@ static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
381 memcpy(blocked->sig, &set, sizeof(set)); 381 memcpy(blocked->sig, &set, sizeof(set));
382} 382}
383 383
384asmlinkage long compat_sys_sigprocmask(int how, 384COMPAT_SYSCALL_DEFINE3(sigprocmask, int, how,
385 compat_old_sigset_t __user *nset, 385 compat_old_sigset_t __user *, nset,
386 compat_old_sigset_t __user *oset) 386 compat_old_sigset_t __user *, oset)
387{ 387{
388 old_sigset_t old_set, new_set; 388 old_sigset_t old_set, new_set;
389 sigset_t new_blocked; 389 sigset_t new_blocked;
@@ -971,7 +971,7 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
971} 971}
972 972
973void 973void
974sigset_from_compat (sigset_t *set, compat_sigset_t *compat) 974sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
975{ 975{
976 switch (_NSIG_WORDS) { 976 switch (_NSIG_WORDS) {
977 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 ); 977 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
@@ -982,10 +982,20 @@ sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
982} 982}
983EXPORT_SYMBOL_GPL(sigset_from_compat); 983EXPORT_SYMBOL_GPL(sigset_from_compat);
984 984
985asmlinkage long 985void
986compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, 986sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
987 struct compat_siginfo __user *uinfo, 987{
988 struct compat_timespec __user *uts, compat_size_t sigsetsize) 988 switch (_NSIG_WORDS) {
989 case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3];
990 case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2];
991 case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1];
992 case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0];
993 }
994}
995
996COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
997 struct compat_siginfo __user *, uinfo,
998 struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
989{ 999{
990 compat_sigset_t s32; 1000 compat_sigset_t s32;
991 sigset_t s; 1001 sigset_t s;
@@ -1013,18 +1023,6 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
1013 } 1023 }
1014 1024
1015 return ret; 1025 return ret;
1016
1017}
1018
1019asmlinkage long
1020compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
1021 struct compat_siginfo __user *uinfo)
1022{
1023 siginfo_t info;
1024
1025 if (copy_siginfo_from_user32(&info, uinfo))
1026 return -EFAULT;
1027 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
1028} 1026}
1029 1027
1030#ifdef __ARCH_WANT_COMPAT_SYS_TIME 1028#ifdef __ARCH_WANT_COMPAT_SYS_TIME
@@ -1067,23 +1065,6 @@ asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
1067 1065
1068#endif /* __ARCH_WANT_COMPAT_SYS_TIME */ 1066#endif /* __ARCH_WANT_COMPAT_SYS_TIME */
1069 1067
1070#ifdef __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
1071asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize)
1072{
1073 sigset_t newset;
1074 compat_sigset_t newset32;
1075
1076 /* XXX: Don't preclude handling different sized sigset_t's. */
1077 if (sigsetsize != sizeof(sigset_t))
1078 return -EINVAL;
1079
1080 if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
1081 return -EFAULT;
1082 sigset_from_compat(&newset, &newset32);
1083 return sigsuspend(&newset);
1084}
1085#endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
1086
1087asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) 1068asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
1088{ 1069{
1089 struct timex txc; 1070 struct timex txc;
@@ -1222,9 +1203,9 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
1222 return 0; 1203 return 0;
1223} 1204}
1224 1205
1225#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL 1206COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
1226asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, 1207 compat_pid_t, pid,
1227 struct compat_timespec __user *interval) 1208 struct compat_timespec __user *, interval)
1228{ 1209{
1229 struct timespec t; 1210 struct timespec t;
1230 int ret; 1211 int ret;
@@ -1237,7 +1218,6 @@ asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
1237 return -EFAULT; 1218 return -EFAULT;
1238 return ret; 1219 return ret;
1239} 1220}
1240#endif /* __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL */
1241 1221
1242/* 1222/*
1243 * Allocate user-space memory for the duration of a single system call, 1223 * Allocate user-space memory for the duration of a single system call,
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index a9642d528630..f9f44fd4d34d 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -11,6 +11,7 @@
11#include <linux/nsproxy.h> 11#include <linux/nsproxy.h>
12#include <linux/futex.h> 12#include <linux/futex.h>
13#include <linux/ptrace.h> 13#include <linux/ptrace.h>
14#include <linux/syscalls.h>
14 15
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
16 17
@@ -116,9 +117,9 @@ void compat_exit_robust_list(struct task_struct *curr)
116 } 117 }
117} 118}
118 119
119asmlinkage long 120COMPAT_SYSCALL_DEFINE2(set_robust_list,
120compat_sys_set_robust_list(struct compat_robust_list_head __user *head, 121 struct compat_robust_list_head __user *, head,
121 compat_size_t len) 122 compat_size_t, len)
122{ 123{
123 if (!futex_cmpxchg_enabled) 124 if (!futex_cmpxchg_enabled)
124 return -ENOSYS; 125 return -ENOSYS;
@@ -131,9 +132,9 @@ compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
131 return 0; 132 return 0;
132} 133}
133 134
134asmlinkage long 135COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid,
135compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, 136 compat_uptr_t __user *, head_ptr,
136 compat_size_t __user *len_ptr) 137 compat_size_t __user *, len_ptr)
137{ 138{
138 struct compat_robust_list_head __user *head; 139 struct compat_robust_list_head __user *head;
139 unsigned long ret; 140 unsigned long ret;
@@ -170,9 +171,9 @@ err_unlock:
170 return ret; 171 return ret;
171} 172}
172 173
173asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, 174COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
174 struct compat_timespec __user *utime, u32 __user *uaddr2, 175 struct compat_timespec __user *, utime, u32 __user *, uaddr2,
175 u32 val3) 176 u32, val3)
176{ 177{
177 struct timespec ts; 178 struct timespec ts;
178 ktime_t t, *tp = NULL; 179 ktime_t t, *tp = NULL;
diff --git a/kernel/signal.c b/kernel/signal.c
index 7f82adbad480..2a7ae2963185 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2399,6 +2399,15 @@ void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
2399 tracehook_signal_handler(sig, info, ka, regs, stepping); 2399 tracehook_signal_handler(sig, info, ka, regs, stepping);
2400} 2400}
2401 2401
2402void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
2403{
2404 if (failed)
2405 force_sigsegv(ksig->sig, current);
2406 else
2407 signal_delivered(ksig->sig, &ksig->info, &ksig->ka,
2408 signal_pt_regs(), stepping);
2409}
2410
2402/* 2411/*
2403 * It could be that complete_signal() picked us to notify about the 2412 * It could be that complete_signal() picked us to notify about the
2404 * group-wide signal. Other threads should be notified now to take 2413 * group-wide signal. Other threads should be notified now to take
@@ -2616,28 +2625,58 @@ SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset,
2616 return 0; 2625 return 0;
2617} 2626}
2618 2627
2619long do_sigpending(void __user *set, unsigned long sigsetsize) 2628#ifdef CONFIG_COMPAT
2629COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
2630 compat_sigset_t __user *, oset, compat_size_t, sigsetsize)
2620{ 2631{
2621 long error = -EINVAL; 2632#ifdef __BIG_ENDIAN
2622 sigset_t pending; 2633 sigset_t old_set = current->blocked;
2634
2635 /* XXX: Don't preclude handling different sized sigset_t's. */
2636 if (sigsetsize != sizeof(sigset_t))
2637 return -EINVAL;
2638
2639 if (nset) {
2640 compat_sigset_t new32;
2641 sigset_t new_set;
2642 int error;
2643 if (copy_from_user(&new32, nset, sizeof(compat_sigset_t)))
2644 return -EFAULT;
2645
2646 sigset_from_compat(&new_set, &new32);
2647 sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
2648
2649 error = sigprocmask(how, &new_set, NULL);
2650 if (error)
2651 return error;
2652 }
2653 if (oset) {
2654 compat_sigset_t old32;
2655 sigset_to_compat(&old32, &old_set);
2656 if (copy_to_user(oset, &old_set, sizeof(sigset_t)))
2657 return -EFAULT;
2658 }
2659 return 0;
2660#else
2661 return sys_rt_sigprocmask(how, (sigset_t __user *)nset,
2662 (sigset_t __user *)oset, sigsetsize);
2663#endif
2664}
2665#endif
2623 2666
2667static int do_sigpending(void *set, unsigned long sigsetsize)
2668{
2624 if (sigsetsize > sizeof(sigset_t)) 2669 if (sigsetsize > sizeof(sigset_t))
2625 goto out; 2670 return -EINVAL;
2626 2671
2627 spin_lock_irq(&current->sighand->siglock); 2672 spin_lock_irq(&current->sighand->siglock);
2628 sigorsets(&pending, &current->pending.signal, 2673 sigorsets(set, &current->pending.signal,
2629 &current->signal->shared_pending.signal); 2674 &current->signal->shared_pending.signal);
2630 spin_unlock_irq(&current->sighand->siglock); 2675 spin_unlock_irq(&current->sighand->siglock);
2631 2676
2632 /* Outside the lock because only this thread touches it. */ 2677 /* Outside the lock because only this thread touches it. */
2633 sigandsets(&pending, &current->blocked, &pending); 2678 sigandsets(set, &current->blocked, set);
2634 2679 return 0;
2635 error = -EFAULT;
2636 if (!copy_to_user(set, &pending, sigsetsize))
2637 error = 0;
2638
2639out:
2640 return error;
2641} 2680}
2642 2681
2643/** 2682/**
@@ -2646,10 +2685,35 @@ out:
2646 * @set: stores pending signals 2685 * @set: stores pending signals
2647 * @sigsetsize: size of sigset_t type or larger 2686 * @sigsetsize: size of sigset_t type or larger
2648 */ 2687 */
2649SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) 2688SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
2650{ 2689{
2651 return do_sigpending(set, sigsetsize); 2690 sigset_t set;
2691 int err = do_sigpending(&set, sigsetsize);
2692 if (!err && copy_to_user(uset, &set, sigsetsize))
2693 err = -EFAULT;
2694 return err;
2695}
2696
2697#ifdef CONFIG_COMPAT
2698COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
2699 compat_size_t, sigsetsize)
2700{
2701#ifdef __BIG_ENDIAN
2702 sigset_t set;
2703 int err = do_sigpending(&set, sigsetsize);
2704 if (!err) {
2705 compat_sigset_t set32;
2706 sigset_to_compat(&set32, &set);
2707 /* we can get here only if sigsetsize <= sizeof(set) */
2708 if (copy_to_user(uset, &set32, sigsetsize))
2709 err = -EFAULT;
2710 }
2711 return err;
2712#else
2713 return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
2714#endif
2652} 2715}
2716#endif
2653 2717
2654#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER 2718#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
2655 2719
@@ -2927,6 +2991,22 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig)
2927 return do_tkill(0, pid, sig); 2991 return do_tkill(0, pid, sig);
2928} 2992}
2929 2993
2994static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
2995{
2996 /* Not even root can pretend to send signals from the kernel.
2997 * Nor can they impersonate a kill()/tgkill(), which adds source info.
2998 */
2999 if (info->si_code >= 0 || info->si_code == SI_TKILL) {
3000 /* We used to allow any < 0 si_code */
3001 WARN_ON_ONCE(info->si_code < 0);
3002 return -EPERM;
3003 }
3004 info->si_signo = sig;
3005
3006 /* POSIX.1b doesn't mention process groups. */
3007 return kill_proc_info(sig, info, pid);
3008}
3009
2930/** 3010/**
2931 * sys_rt_sigqueueinfo - send signal information to a signal 3011 * sys_rt_sigqueueinfo - send signal information to a signal
2932 * @pid: the PID of the thread 3012 * @pid: the PID of the thread
@@ -2937,25 +3017,26 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
2937 siginfo_t __user *, uinfo) 3017 siginfo_t __user *, uinfo)
2938{ 3018{
2939 siginfo_t info; 3019 siginfo_t info;
2940
2941 if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) 3020 if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
2942 return -EFAULT; 3021 return -EFAULT;
3022 return do_rt_sigqueueinfo(pid, sig, &info);
3023}
2943 3024
2944 /* Not even root can pretend to send signals from the kernel. 3025#ifdef CONFIG_COMPAT
2945 * Nor can they impersonate a kill()/tgkill(), which adds source info. 3026COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo,
2946 */ 3027 compat_pid_t, pid,
2947 if (info.si_code >= 0 || info.si_code == SI_TKILL) { 3028 int, sig,
2948 /* We used to allow any < 0 si_code */ 3029 struct compat_siginfo __user *, uinfo)
2949 WARN_ON_ONCE(info.si_code < 0); 3030{
2950 return -EPERM; 3031 siginfo_t info;
2951 } 3032 int ret = copy_siginfo_from_user32(&info, uinfo);
2952 info.si_signo = sig; 3033 if (unlikely(ret))
2953 3034 return ret;
2954 /* POSIX.1b doesn't mention process groups. */ 3035 return do_rt_sigqueueinfo(pid, sig, &info);
2955 return kill_proc_info(sig, &info, pid);
2956} 3036}
3037#endif
2957 3038
2958long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) 3039static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
2959{ 3040{
2960 /* This is only valid for single tasks */ 3041 /* This is only valid for single tasks */
2961 if (pid <= 0 || tgid <= 0) 3042 if (pid <= 0 || tgid <= 0)
@@ -2985,6 +3066,21 @@ SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig,
2985 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); 3066 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
2986} 3067}
2987 3068
3069#ifdef CONFIG_COMPAT
3070COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo,
3071 compat_pid_t, tgid,
3072 compat_pid_t, pid,
3073 int, sig,
3074 struct compat_siginfo __user *, uinfo)
3075{
3076 siginfo_t info;
3077
3078 if (copy_siginfo_from_user32(&info, uinfo))
3079 return -EFAULT;
3080 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
3081}
3082#endif
3083
2988int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) 3084int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
2989{ 3085{
2990 struct task_struct *t = current; 3086 struct task_struct *t = current;
@@ -3030,7 +3126,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
3030 return 0; 3126 return 0;
3031} 3127}
3032 3128
3033int 3129static int
3034do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp) 3130do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp)
3035{ 3131{
3036 stack_t oss; 3132 stack_t oss;
@@ -3095,12 +3191,10 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
3095out: 3191out:
3096 return error; 3192 return error;
3097} 3193}
3098#ifdef CONFIG_GENERIC_SIGALTSTACK
3099SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss) 3194SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
3100{ 3195{
3101 return do_sigaltstack(uss, uoss, current_user_stack_pointer()); 3196 return do_sigaltstack(uss, uoss, current_user_stack_pointer());
3102} 3197}
3103#endif
3104 3198
3105int restore_altstack(const stack_t __user *uss) 3199int restore_altstack(const stack_t __user *uss)
3106{ 3200{
@@ -3118,7 +3212,6 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
3118} 3212}
3119 3213
3120#ifdef CONFIG_COMPAT 3214#ifdef CONFIG_COMPAT
3121#ifdef CONFIG_GENERIC_SIGALTSTACK
3122COMPAT_SYSCALL_DEFINE2(sigaltstack, 3215COMPAT_SYSCALL_DEFINE2(sigaltstack,
3123 const compat_stack_t __user *, uss_ptr, 3216 const compat_stack_t __user *, uss_ptr,
3124 compat_stack_t __user *, uoss_ptr) 3217 compat_stack_t __user *, uoss_ptr)
@@ -3168,7 +3261,6 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3168 __put_user(t->sas_ss_size, &uss->ss_size); 3261 __put_user(t->sas_ss_size, &uss->ss_size);
3169} 3262}
3170#endif 3263#endif
3171#endif
3172 3264
3173#ifdef __ARCH_WANT_SYS_SIGPENDING 3265#ifdef __ARCH_WANT_SYS_SIGPENDING
3174 3266
@@ -3178,7 +3270,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3178 */ 3270 */
3179SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) 3271SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
3180{ 3272{
3181 return do_sigpending(set, sizeof(*set)); 3273 return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t));
3182} 3274}
3183 3275
3184#endif 3276#endif
@@ -3234,7 +3326,7 @@ SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, nset,
3234} 3326}
3235#endif /* __ARCH_WANT_SYS_SIGPROCMASK */ 3327#endif /* __ARCH_WANT_SYS_SIGPROCMASK */
3236 3328
3237#ifdef __ARCH_WANT_SYS_RT_SIGACTION 3329#ifndef CONFIG_ODD_RT_SIGACTION
3238/** 3330/**
3239 * sys_rt_sigaction - alter an action taken by a process 3331 * sys_rt_sigaction - alter an action taken by a process
3240 * @sig: signal to be sent 3332 * @sig: signal to be sent
@@ -3268,7 +3360,132 @@ SYSCALL_DEFINE4(rt_sigaction, int, sig,
3268out: 3360out:
3269 return ret; 3361 return ret;
3270} 3362}
3271#endif /* __ARCH_WANT_SYS_RT_SIGACTION */ 3363#ifdef CONFIG_COMPAT
3364COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
3365 const struct compat_sigaction __user *, act,
3366 struct compat_sigaction __user *, oact,
3367 compat_size_t, sigsetsize)
3368{
3369 struct k_sigaction new_ka, old_ka;
3370 compat_sigset_t mask;
3371#ifdef __ARCH_HAS_SA_RESTORER
3372 compat_uptr_t restorer;
3373#endif
3374 int ret;
3375
3376 /* XXX: Don't preclude handling different sized sigset_t's. */
3377 if (sigsetsize != sizeof(compat_sigset_t))
3378 return -EINVAL;
3379
3380 if (act) {
3381 compat_uptr_t handler;
3382 ret = get_user(handler, &act->sa_handler);
3383 new_ka.sa.sa_handler = compat_ptr(handler);
3384#ifdef __ARCH_HAS_SA_RESTORER
3385 ret |= get_user(restorer, &act->sa_restorer);
3386 new_ka.sa.sa_restorer = compat_ptr(restorer);
3387#endif
3388 ret |= copy_from_user(&mask, &act->sa_mask, sizeof(mask));
3389 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
3390 if (ret)
3391 return -EFAULT;
3392 sigset_from_compat(&new_ka.sa.sa_mask, &mask);
3393 }
3394
3395 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3396 if (!ret && oact) {
3397 sigset_to_compat(&mask, &old_ka.sa.sa_mask);
3398 ret = put_user(ptr_to_compat(old_ka.sa.sa_handler),
3399 &oact->sa_handler);
3400 ret |= copy_to_user(&oact->sa_mask, &mask, sizeof(mask));
3401 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3402#ifdef __ARCH_HAS_SA_RESTORER
3403 ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer),
3404 &oact->sa_restorer);
3405#endif
3406 }
3407 return ret;
3408}
3409#endif
3410#endif /* !CONFIG_ODD_RT_SIGACTION */
3411
3412#ifdef CONFIG_OLD_SIGACTION
3413SYSCALL_DEFINE3(sigaction, int, sig,
3414 const struct old_sigaction __user *, act,
3415 struct old_sigaction __user *, oact)
3416{
3417 struct k_sigaction new_ka, old_ka;
3418 int ret;
3419
3420 if (act) {
3421 old_sigset_t mask;
3422 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
3423 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
3424 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
3425 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
3426 __get_user(mask, &act->sa_mask))
3427 return -EFAULT;
3428#ifdef __ARCH_HAS_KA_RESTORER
3429 new_ka.ka_restorer = NULL;
3430#endif
3431 siginitset(&new_ka.sa.sa_mask, mask);
3432 }
3433
3434 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3435
3436 if (!ret && oact) {
3437 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
3438 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
3439 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
3440 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
3441 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
3442 return -EFAULT;
3443 }
3444
3445 return ret;
3446}
3447#endif
3448#ifdef CONFIG_COMPAT_OLD_SIGACTION
3449COMPAT_SYSCALL_DEFINE3(sigaction, int, sig,
3450 const struct compat_old_sigaction __user *, act,
3451 struct compat_old_sigaction __user *, oact)
3452{
3453 struct k_sigaction new_ka, old_ka;
3454 int ret;
3455 compat_old_sigset_t mask;
3456 compat_uptr_t handler, restorer;
3457
3458 if (act) {
3459 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
3460 __get_user(handler, &act->sa_handler) ||
3461 __get_user(restorer, &act->sa_restorer) ||
3462 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
3463 __get_user(mask, &act->sa_mask))
3464 return -EFAULT;
3465
3466#ifdef __ARCH_HAS_KA_RESTORER
3467 new_ka.ka_restorer = NULL;
3468#endif
3469 new_ka.sa.sa_handler = compat_ptr(handler);
3470 new_ka.sa.sa_restorer = compat_ptr(restorer);
3471 siginitset(&new_ka.sa.sa_mask, mask);
3472 }
3473
3474 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3475
3476 if (!ret && oact) {
3477 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
3478 __put_user(ptr_to_compat(old_ka.sa.sa_handler),
3479 &oact->sa_handler) ||
3480 __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
3481 &oact->sa_restorer) ||
3482 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
3483 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
3484 return -EFAULT;
3485 }
3486 return ret;
3487}
3488#endif
3272 3489
3273#ifdef __ARCH_WANT_SYS_SGETMASK 3490#ifdef __ARCH_WANT_SYS_SGETMASK
3274 3491
@@ -3336,7 +3553,6 @@ int sigsuspend(sigset_t *set)
3336 return -ERESTARTNOHAND; 3553 return -ERESTARTNOHAND;
3337} 3554}
3338 3555
3339#ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND
3340/** 3556/**
3341 * sys_rt_sigsuspend - replace the signal mask for a value with the 3557 * sys_rt_sigsuspend - replace the signal mask for a value with the
3342 * @unewset value until a signal is received 3558 * @unewset value until a signal is received
@@ -3355,7 +3571,45 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
3355 return -EFAULT; 3571 return -EFAULT;
3356 return sigsuspend(&newset); 3572 return sigsuspend(&newset);
3357} 3573}
3358#endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ 3574
3575#ifdef CONFIG_COMPAT
3576COMPAT_SYSCALL_DEFINE2(rt_sigsuspend, compat_sigset_t __user *, unewset, compat_size_t, sigsetsize)
3577{
3578#ifdef __BIG_ENDIAN
3579 sigset_t newset;
3580 compat_sigset_t newset32;
3581
3582 /* XXX: Don't preclude handling different sized sigset_t's. */
3583 if (sigsetsize != sizeof(sigset_t))
3584 return -EINVAL;
3585
3586 if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
3587 return -EFAULT;
3588 sigset_from_compat(&newset, &newset32);
3589 return sigsuspend(&newset);
3590#else
3591 /* on little-endian bitmaps don't care about granularity */
3592 return sys_rt_sigsuspend((sigset_t __user *)unewset, sigsetsize);
3593#endif
3594}
3595#endif
3596
3597#ifdef CONFIG_OLD_SIGSUSPEND
3598SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
3599{
3600 sigset_t blocked;
3601 siginitset(&blocked, mask);
3602 return sigsuspend(&blocked);
3603}
3604#endif
3605#ifdef CONFIG_OLD_SIGSUSPEND3
3606SYSCALL_DEFINE3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask)
3607{
3608 sigset_t blocked;
3609 siginitset(&blocked, mask);
3610 return sigsuspend(&blocked);
3611}
3612#endif
3359 3613
3360__attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma) 3614__attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma)
3361{ 3615{