diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d840bc772fd3..ad6943468ee9 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -621,6 +621,18 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) | |||
621 | 621 | ||
622 | #define copy_siginfo_to_user copy_siginfo_to_user32 | 622 | #define copy_siginfo_to_user copy_siginfo_to_user32 |
623 | 623 | ||
624 | int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from) | ||
625 | { | ||
626 | memset(to, 0, sizeof *to); | ||
627 | |||
628 | if (copy_from_user(to, from, 3*sizeof(int)) || | ||
629 | copy_from_user(to->_sifields._pad, | ||
630 | from->_sifields._pad, SI_PAD_SIZE32)) | ||
631 | return -EFAULT; | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
624 | /* | 636 | /* |
625 | * Note: it is necessary to treat pid and sig as unsigned ints, with the | 637 | * Note: it is necessary to treat pid and sig as unsigned ints, with the |
626 | * corresponding cast to a signed int to insure that the proper conversion | 638 | * corresponding cast to a signed int to insure that the proper conversion |
@@ -634,9 +646,10 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo | |||
634 | int ret; | 646 | int ret; |
635 | mm_segment_t old_fs = get_fs(); | 647 | mm_segment_t old_fs = get_fs(); |
636 | 648 | ||
637 | if (copy_from_user (&info, uinfo, 3*sizeof(int)) || | 649 | ret = copy_siginfo_from_user32(&info, uinfo); |
638 | copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32)) | 650 | if (unlikely(ret)) |
639 | return -EFAULT; | 651 | return ret; |
652 | |||
640 | set_fs (KERNEL_DS); | 653 | set_fs (KERNEL_DS); |
641 | /* The __user pointer cast is valid becasuse of the set_fs() */ | 654 | /* The __user pointer cast is valid becasuse of the set_fs() */ |
642 | ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info); | 655 | ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info); |