aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c361
1 files changed, 312 insertions, 49 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 3d09cf6cde75..dd72567767d9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -485,6 +485,9 @@ flush_signal_handlers(struct task_struct *t, int force_default)
485 if (force_default || ka->sa.sa_handler != SIG_IGN) 485 if (force_default || ka->sa.sa_handler != SIG_IGN)
486 ka->sa.sa_handler = SIG_DFL; 486 ka->sa.sa_handler = SIG_DFL;
487 ka->sa.sa_flags = 0; 487 ka->sa.sa_flags = 0;
488#ifdef __ARCH_HAS_SA_RESTORER
489 ka->sa.sa_restorer = NULL;
490#endif
488 sigemptyset(&ka->sa.sa_mask); 491 sigemptyset(&ka->sa.sa_mask);
489 ka++; 492 ka++;
490 } 493 }
@@ -1157,11 +1160,11 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
1157static void print_fatal_signal(int signr) 1160static void print_fatal_signal(int signr)
1158{ 1161{
1159 struct pt_regs *regs = signal_pt_regs(); 1162 struct pt_regs *regs = signal_pt_regs();
1160 printk("%s/%d: potentially unexpected fatal signal %d.\n", 1163 printk(KERN_INFO "%s/%d: potentially unexpected fatal signal %d.\n",
1161 current->comm, task_pid_nr(current), signr); 1164 current->comm, task_pid_nr(current), signr);
1162 1165
1163#if defined(__i386__) && !defined(__arch_um__) 1166#if defined(__i386__) && !defined(__arch_um__)
1164 printk("code at %08lx: ", regs->ip); 1167 printk(KERN_INFO "code at %08lx: ", regs->ip);
1165 { 1168 {
1166 int i; 1169 int i;
1167 for (i = 0; i < 16; i++) { 1170 for (i = 0; i < 16; i++) {
@@ -1169,11 +1172,11 @@ static void print_fatal_signal(int signr)
1169 1172
1170 if (get_user(insn, (unsigned char *)(regs->ip + i))) 1173 if (get_user(insn, (unsigned char *)(regs->ip + i)))
1171 break; 1174 break;
1172 printk("%02x ", insn); 1175 printk(KERN_CONT "%02x ", insn);
1173 } 1176 }
1174 } 1177 }
1178 printk(KERN_CONT "\n");
1175#endif 1179#endif
1176 printk("\n");
1177 preempt_disable(); 1180 preempt_disable();
1178 show_regs(regs); 1181 show_regs(regs);
1179 preempt_enable(); 1182 preempt_enable();
@@ -1632,6 +1635,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
1632 unsigned long flags; 1635 unsigned long flags;
1633 struct sighand_struct *psig; 1636 struct sighand_struct *psig;
1634 bool autoreap = false; 1637 bool autoreap = false;
1638 cputime_t utime, stime;
1635 1639
1636 BUG_ON(sig == -1); 1640 BUG_ON(sig == -1);
1637 1641
@@ -1669,8 +1673,9 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
1669 task_uid(tsk)); 1673 task_uid(tsk));
1670 rcu_read_unlock(); 1674 rcu_read_unlock();
1671 1675
1672 info.si_utime = cputime_to_clock_t(tsk->utime + tsk->signal->utime); 1676 task_cputime(tsk, &utime, &stime);
1673 info.si_stime = cputime_to_clock_t(tsk->stime + tsk->signal->stime); 1677 info.si_utime = cputime_to_clock_t(utime + tsk->signal->utime);
1678 info.si_stime = cputime_to_clock_t(stime + tsk->signal->stime);
1674 1679
1675 info.si_status = tsk->exit_code & 0x7f; 1680 info.si_status = tsk->exit_code & 0x7f;
1676 if (tsk->exit_code & 0x80) 1681 if (tsk->exit_code & 0x80)
@@ -1734,6 +1739,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
1734 unsigned long flags; 1739 unsigned long flags;
1735 struct task_struct *parent; 1740 struct task_struct *parent;
1736 struct sighand_struct *sighand; 1741 struct sighand_struct *sighand;
1742 cputime_t utime, stime;
1737 1743
1738 if (for_ptracer) { 1744 if (for_ptracer) {
1739 parent = tsk->parent; 1745 parent = tsk->parent;
@@ -1752,8 +1758,9 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
1752 info.si_uid = from_kuid_munged(task_cred_xxx(parent, user_ns), task_uid(tsk)); 1758 info.si_uid = from_kuid_munged(task_cred_xxx(parent, user_ns), task_uid(tsk));
1753 rcu_read_unlock(); 1759 rcu_read_unlock();
1754 1760
1755 info.si_utime = cputime_to_clock_t(tsk->utime); 1761 task_cputime(tsk, &utime, &stime);
1756 info.si_stime = cputime_to_clock_t(tsk->stime); 1762 info.si_utime = cputime_to_clock_t(utime);
1763 info.si_stime = cputime_to_clock_t(stime);
1757 1764
1758 info.si_code = why; 1765 info.si_code = why;
1759 switch (why) { 1766 switch (why) {
@@ -2395,6 +2402,15 @@ void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
2395 tracehook_signal_handler(sig, info, ka, regs, stepping); 2402 tracehook_signal_handler(sig, info, ka, regs, stepping);
2396} 2403}
2397 2404
2405void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
2406{
2407 if (failed)
2408 force_sigsegv(ksig->sig, current);
2409 else
2410 signal_delivered(ksig->sig, &ksig->info, &ksig->ka,
2411 signal_pt_regs(), stepping);
2412}
2413
2398/* 2414/*
2399 * It could be that complete_signal() picked us to notify about the 2415 * It could be that complete_signal() picked us to notify about the
2400 * group-wide signal. Other threads should be notified now to take 2416 * group-wide signal. Other threads should be notified now to take
@@ -2612,40 +2628,95 @@ SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset,
2612 return 0; 2628 return 0;
2613} 2629}
2614 2630
2615long do_sigpending(void __user *set, unsigned long sigsetsize) 2631#ifdef CONFIG_COMPAT
2632COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
2633 compat_sigset_t __user *, oset, compat_size_t, sigsetsize)
2616{ 2634{
2617 long error = -EINVAL; 2635#ifdef __BIG_ENDIAN
2618 sigset_t pending; 2636 sigset_t old_set = current->blocked;
2637
2638 /* XXX: Don't preclude handling different sized sigset_t's. */
2639 if (sigsetsize != sizeof(sigset_t))
2640 return -EINVAL;
2641
2642 if (nset) {
2643 compat_sigset_t new32;
2644 sigset_t new_set;
2645 int error;
2646 if (copy_from_user(&new32, nset, sizeof(compat_sigset_t)))
2647 return -EFAULT;
2648
2649 sigset_from_compat(&new_set, &new32);
2650 sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
2651
2652 error = sigprocmask(how, &new_set, NULL);
2653 if (error)
2654 return error;
2655 }
2656 if (oset) {
2657 compat_sigset_t old32;
2658 sigset_to_compat(&old32, &old_set);
2659 if (copy_to_user(oset, &old32, sizeof(compat_sigset_t)))
2660 return -EFAULT;
2661 }
2662 return 0;
2663#else
2664 return sys_rt_sigprocmask(how, (sigset_t __user *)nset,
2665 (sigset_t __user *)oset, sigsetsize);
2666#endif
2667}
2668#endif
2619 2669
2670static int do_sigpending(void *set, unsigned long sigsetsize)
2671{
2620 if (sigsetsize > sizeof(sigset_t)) 2672 if (sigsetsize > sizeof(sigset_t))
2621 goto out; 2673 return -EINVAL;
2622 2674
2623 spin_lock_irq(&current->sighand->siglock); 2675 spin_lock_irq(&current->sighand->siglock);
2624 sigorsets(&pending, &current->pending.signal, 2676 sigorsets(set, &current->pending.signal,
2625 &current->signal->shared_pending.signal); 2677 &current->signal->shared_pending.signal);
2626 spin_unlock_irq(&current->sighand->siglock); 2678 spin_unlock_irq(&current->sighand->siglock);
2627 2679
2628 /* Outside the lock because only this thread touches it. */ 2680 /* Outside the lock because only this thread touches it. */
2629 sigandsets(&pending, &current->blocked, &pending); 2681 sigandsets(set, &current->blocked, set);
2630 2682 return 0;
2631 error = -EFAULT;
2632 if (!copy_to_user(set, &pending, sigsetsize))
2633 error = 0;
2634
2635out:
2636 return error;
2637} 2683}
2638 2684
2639/** 2685/**
2640 * sys_rt_sigpending - examine a pending signal that has been raised 2686 * sys_rt_sigpending - examine a pending signal that has been raised
2641 * while blocked 2687 * while blocked
2642 * @set: stores pending signals 2688 * @uset: stores pending signals
2643 * @sigsetsize: size of sigset_t type or larger 2689 * @sigsetsize: size of sigset_t type or larger
2644 */ 2690 */
2645SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) 2691SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
2646{ 2692{
2647 return do_sigpending(set, sigsetsize); 2693 sigset_t set;
2694 int err = do_sigpending(&set, sigsetsize);
2695 if (!err && copy_to_user(uset, &set, sigsetsize))
2696 err = -EFAULT;
2697 return err;
2698}
2699
2700#ifdef CONFIG_COMPAT
2701COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
2702 compat_size_t, sigsetsize)
2703{
2704#ifdef __BIG_ENDIAN
2705 sigset_t set;
2706 int err = do_sigpending(&set, sigsetsize);
2707 if (!err) {
2708 compat_sigset_t set32;
2709 sigset_to_compat(&set32, &set);
2710 /* we can get here only if sigsetsize <= sizeof(set) */
2711 if (copy_to_user(uset, &set32, sigsetsize))
2712 err = -EFAULT;
2713 }
2714 return err;
2715#else
2716 return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
2717#endif
2648} 2718}
2719#endif
2649 2720
2650#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER 2721#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
2651 2722
@@ -2923,6 +2994,23 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig)
2923 return do_tkill(0, pid, sig); 2994 return do_tkill(0, pid, sig);
2924} 2995}
2925 2996
2997static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
2998{
2999 /* Not even root can pretend to send signals from the kernel.
3000 * Nor can they impersonate a kill()/tgkill(), which adds source info.
3001 */
3002 if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
3003 (task_pid_vnr(current) != pid)) {
3004 /* We used to allow any < 0 si_code */
3005 WARN_ON_ONCE(info->si_code < 0);
3006 return -EPERM;
3007 }
3008 info->si_signo = sig;
3009
3010 /* POSIX.1b doesn't mention process groups. */
3011 return kill_proc_info(sig, info, pid);
3012}
3013
2926/** 3014/**
2927 * sys_rt_sigqueueinfo - send signal information to a signal 3015 * sys_rt_sigqueueinfo - send signal information to a signal
2928 * @pid: the PID of the thread 3016 * @pid: the PID of the thread
@@ -2933,25 +3021,26 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
2933 siginfo_t __user *, uinfo) 3021 siginfo_t __user *, uinfo)
2934{ 3022{
2935 siginfo_t info; 3023 siginfo_t info;
2936
2937 if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) 3024 if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
2938 return -EFAULT; 3025 return -EFAULT;
3026 return do_rt_sigqueueinfo(pid, sig, &info);
3027}
2939 3028
2940 /* Not even root can pretend to send signals from the kernel. 3029#ifdef CONFIG_COMPAT
2941 * Nor can they impersonate a kill()/tgkill(), which adds source info. 3030COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo,
2942 */ 3031 compat_pid_t, pid,
2943 if (info.si_code >= 0 || info.si_code == SI_TKILL) { 3032 int, sig,
2944 /* We used to allow any < 0 si_code */ 3033 struct compat_siginfo __user *, uinfo)
2945 WARN_ON_ONCE(info.si_code < 0); 3034{
2946 return -EPERM; 3035 siginfo_t info;
2947 } 3036 int ret = copy_siginfo_from_user32(&info, uinfo);
2948 info.si_signo = sig; 3037 if (unlikely(ret))
2949 3038 return ret;
2950 /* POSIX.1b doesn't mention process groups. */ 3039 return do_rt_sigqueueinfo(pid, sig, &info);
2951 return kill_proc_info(sig, &info, pid);
2952} 3040}
3041#endif
2953 3042
2954long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) 3043static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
2955{ 3044{
2956 /* This is only valid for single tasks */ 3045 /* This is only valid for single tasks */
2957 if (pid <= 0 || tgid <= 0) 3046 if (pid <= 0 || tgid <= 0)
@@ -2960,7 +3049,8 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
2960 /* Not even root can pretend to send signals from the kernel. 3049 /* Not even root can pretend to send signals from the kernel.
2961 * Nor can they impersonate a kill()/tgkill(), which adds source info. 3050 * Nor can they impersonate a kill()/tgkill(), which adds source info.
2962 */ 3051 */
2963 if (info->si_code >= 0 || info->si_code == SI_TKILL) { 3052 if (((info->si_code >= 0 || info->si_code == SI_TKILL)) &&
3053 (task_pid_vnr(current) != pid)) {
2964 /* We used to allow any < 0 si_code */ 3054 /* We used to allow any < 0 si_code */
2965 WARN_ON_ONCE(info->si_code < 0); 3055 WARN_ON_ONCE(info->si_code < 0);
2966 return -EPERM; 3056 return -EPERM;
@@ -2981,6 +3071,21 @@ SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig,
2981 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); 3071 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
2982} 3072}
2983 3073
3074#ifdef CONFIG_COMPAT
3075COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo,
3076 compat_pid_t, tgid,
3077 compat_pid_t, pid,
3078 int, sig,
3079 struct compat_siginfo __user *, uinfo)
3080{
3081 siginfo_t info;
3082
3083 if (copy_siginfo_from_user32(&info, uinfo))
3084 return -EFAULT;
3085 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
3086}
3087#endif
3088
2984int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) 3089int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
2985{ 3090{
2986 struct task_struct *t = current; 3091 struct task_struct *t = current;
@@ -3026,7 +3131,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
3026 return 0; 3131 return 0;
3027} 3132}
3028 3133
3029int 3134static int
3030do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp) 3135do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp)
3031{ 3136{
3032 stack_t oss; 3137 stack_t oss;
@@ -3091,12 +3196,10 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
3091out: 3196out:
3092 return error; 3197 return error;
3093} 3198}
3094#ifdef CONFIG_GENERIC_SIGALTSTACK
3095SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss) 3199SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
3096{ 3200{
3097 return do_sigaltstack(uss, uoss, current_user_stack_pointer()); 3201 return do_sigaltstack(uss, uoss, current_user_stack_pointer());
3098} 3202}
3099#endif
3100 3203
3101int restore_altstack(const stack_t __user *uss) 3204int restore_altstack(const stack_t __user *uss)
3102{ 3205{
@@ -3114,7 +3217,6 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
3114} 3217}
3115 3218
3116#ifdef CONFIG_COMPAT 3219#ifdef CONFIG_COMPAT
3117#ifdef CONFIG_GENERIC_SIGALTSTACK
3118COMPAT_SYSCALL_DEFINE2(sigaltstack, 3220COMPAT_SYSCALL_DEFINE2(sigaltstack,
3119 const compat_stack_t __user *, uss_ptr, 3221 const compat_stack_t __user *, uss_ptr,
3120 compat_stack_t __user *, uoss_ptr) 3222 compat_stack_t __user *, uoss_ptr)
@@ -3164,7 +3266,6 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3164 __put_user(t->sas_ss_size, &uss->ss_size); 3266 __put_user(t->sas_ss_size, &uss->ss_size);
3165} 3267}
3166#endif 3268#endif
3167#endif
3168 3269
3169#ifdef __ARCH_WANT_SYS_SIGPENDING 3270#ifdef __ARCH_WANT_SYS_SIGPENDING
3170 3271
@@ -3174,7 +3275,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3174 */ 3275 */
3175SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) 3276SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
3176{ 3277{
3177 return do_sigpending(set, sizeof(*set)); 3278 return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t));
3178} 3279}
3179 3280
3180#endif 3281#endif
@@ -3230,7 +3331,7 @@ SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, nset,
3230} 3331}
3231#endif /* __ARCH_WANT_SYS_SIGPROCMASK */ 3332#endif /* __ARCH_WANT_SYS_SIGPROCMASK */
3232 3333
3233#ifdef __ARCH_WANT_SYS_RT_SIGACTION 3334#ifndef CONFIG_ODD_RT_SIGACTION
3234/** 3335/**
3235 * sys_rt_sigaction - alter an action taken by a process 3336 * sys_rt_sigaction - alter an action taken by a process
3236 * @sig: signal to be sent 3337 * @sig: signal to be sent
@@ -3264,7 +3365,132 @@ SYSCALL_DEFINE4(rt_sigaction, int, sig,
3264out: 3365out:
3265 return ret; 3366 return ret;
3266} 3367}
3267#endif /* __ARCH_WANT_SYS_RT_SIGACTION */ 3368#ifdef CONFIG_COMPAT
3369COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
3370 const struct compat_sigaction __user *, act,
3371 struct compat_sigaction __user *, oact,
3372 compat_size_t, sigsetsize)
3373{
3374 struct k_sigaction new_ka, old_ka;
3375 compat_sigset_t mask;
3376#ifdef __ARCH_HAS_SA_RESTORER
3377 compat_uptr_t restorer;
3378#endif
3379 int ret;
3380
3381 /* XXX: Don't preclude handling different sized sigset_t's. */
3382 if (sigsetsize != sizeof(compat_sigset_t))
3383 return -EINVAL;
3384
3385 if (act) {
3386 compat_uptr_t handler;
3387 ret = get_user(handler, &act->sa_handler);
3388 new_ka.sa.sa_handler = compat_ptr(handler);
3389#ifdef __ARCH_HAS_SA_RESTORER
3390 ret |= get_user(restorer, &act->sa_restorer);
3391 new_ka.sa.sa_restorer = compat_ptr(restorer);
3392#endif
3393 ret |= copy_from_user(&mask, &act->sa_mask, sizeof(mask));
3394 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
3395 if (ret)
3396 return -EFAULT;
3397 sigset_from_compat(&new_ka.sa.sa_mask, &mask);
3398 }
3399
3400 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3401 if (!ret && oact) {
3402 sigset_to_compat(&mask, &old_ka.sa.sa_mask);
3403 ret = put_user(ptr_to_compat(old_ka.sa.sa_handler),
3404 &oact->sa_handler);
3405 ret |= copy_to_user(&oact->sa_mask, &mask, sizeof(mask));
3406 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3407#ifdef __ARCH_HAS_SA_RESTORER
3408 ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer),
3409 &oact->sa_restorer);
3410#endif
3411 }
3412 return ret;
3413}
3414#endif
3415#endif /* !CONFIG_ODD_RT_SIGACTION */
3416
3417#ifdef CONFIG_OLD_SIGACTION
3418SYSCALL_DEFINE3(sigaction, int, sig,
3419 const struct old_sigaction __user *, act,
3420 struct old_sigaction __user *, oact)
3421{
3422 struct k_sigaction new_ka, old_ka;
3423 int ret;
3424
3425 if (act) {
3426 old_sigset_t mask;
3427 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
3428 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
3429 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
3430 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
3431 __get_user(mask, &act->sa_mask))
3432 return -EFAULT;
3433#ifdef __ARCH_HAS_KA_RESTORER
3434 new_ka.ka_restorer = NULL;
3435#endif
3436 siginitset(&new_ka.sa.sa_mask, mask);
3437 }
3438
3439 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3440
3441 if (!ret && oact) {
3442 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
3443 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
3444 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
3445 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
3446 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
3447 return -EFAULT;
3448 }
3449
3450 return ret;
3451}
3452#endif
3453#ifdef CONFIG_COMPAT_OLD_SIGACTION
3454COMPAT_SYSCALL_DEFINE3(sigaction, int, sig,
3455 const struct compat_old_sigaction __user *, act,
3456 struct compat_old_sigaction __user *, oact)
3457{
3458 struct k_sigaction new_ka, old_ka;
3459 int ret;
3460 compat_old_sigset_t mask;
3461 compat_uptr_t handler, restorer;
3462
3463 if (act) {
3464 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
3465 __get_user(handler, &act->sa_handler) ||
3466 __get_user(restorer, &act->sa_restorer) ||
3467 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
3468 __get_user(mask, &act->sa_mask))
3469 return -EFAULT;
3470
3471#ifdef __ARCH_HAS_KA_RESTORER
3472 new_ka.ka_restorer = NULL;
3473#endif
3474 new_ka.sa.sa_handler = compat_ptr(handler);
3475 new_ka.sa.sa_restorer = compat_ptr(restorer);
3476 siginitset(&new_ka.sa.sa_mask, mask);
3477 }
3478
3479 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3480
3481 if (!ret && oact) {
3482 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
3483 __put_user(ptr_to_compat(old_ka.sa.sa_handler),
3484 &oact->sa_handler) ||
3485 __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
3486 &oact->sa_restorer) ||
3487 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
3488 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
3489 return -EFAULT;
3490 }
3491 return ret;
3492}
3493#endif
3268 3494
3269#ifdef __ARCH_WANT_SYS_SGETMASK 3495#ifdef __ARCH_WANT_SYS_SGETMASK
3270 3496
@@ -3332,7 +3558,6 @@ int sigsuspend(sigset_t *set)
3332 return -ERESTARTNOHAND; 3558 return -ERESTARTNOHAND;
3333} 3559}
3334 3560
3335#ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND
3336/** 3561/**
3337 * sys_rt_sigsuspend - replace the signal mask for a value with the 3562 * sys_rt_sigsuspend - replace the signal mask for a value with the
3338 * @unewset value until a signal is received 3563 * @unewset value until a signal is received
@@ -3351,7 +3576,45 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
3351 return -EFAULT; 3576 return -EFAULT;
3352 return sigsuspend(&newset); 3577 return sigsuspend(&newset);
3353} 3578}
3354#endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ 3579
3580#ifdef CONFIG_COMPAT
3581COMPAT_SYSCALL_DEFINE2(rt_sigsuspend, compat_sigset_t __user *, unewset, compat_size_t, sigsetsize)
3582{
3583#ifdef __BIG_ENDIAN
3584 sigset_t newset;
3585 compat_sigset_t newset32;
3586
3587 /* XXX: Don't preclude handling different sized sigset_t's. */
3588 if (sigsetsize != sizeof(sigset_t))
3589 return -EINVAL;
3590
3591 if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
3592 return -EFAULT;
3593 sigset_from_compat(&newset, &newset32);
3594 return sigsuspend(&newset);
3595#else
3596 /* on little-endian bitmaps don't care about granularity */
3597 return sys_rt_sigsuspend((sigset_t __user *)unewset, sigsetsize);
3598#endif
3599}
3600#endif
3601
3602#ifdef CONFIG_OLD_SIGSUSPEND
3603SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
3604{
3605 sigset_t blocked;
3606 siginitset(&blocked, mask);
3607 return sigsuspend(&blocked);
3608}
3609#endif
3610#ifdef CONFIG_OLD_SIGSUSPEND3
3611SYSCALL_DEFINE3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask)
3612{
3613 sigset_t blocked;
3614 siginitset(&blocked, mask);
3615 return sigsuspend(&blocked);
3616}
3617#endif
3355 3618
3356__attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma) 3619__attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma)
3357{ 3620{