From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Wed, 15 May 2002 20:33:09 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Wed, 15 May 2002 20:33:08 -0400 Received: from supreme.pcug.org.au ([203.10.76.34]:46844 "EHLO pcug.org.au") by vger.kernel.org with ESMTP id ; Wed, 15 May 2002 20:33:03 -0400 Date: Thu, 16 May 2002 10:32:14 +1000 From: Stephen Rothwell To: Linus Cc: linux-kernel@vger.kernel.org Subject: [PATCH] signal cleanup continued: rationalise copy_siginfo_to_user Message-Id: <20020516103214.46df7d15.sfr@canb.auug.org.au> X-Mailer: Sylpheed version 0.7.6 (GTK+ 1.2.10; i386-debian-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Hi Linus, Most of the copy_siginfo_to_user routines that were defined per architecture are identical. This patch starts the migration to using a generic version of this routine where possible. This patch just changes the architectures that are (essentially) the same code. The other architectures will follow if possible (some have may not be). Please apply. If nothing else, it reduces dramatically the places we need to fix bugs in this code. More similar changes to follow. -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.5.15/arch/arm/kernel/signal.c 2.5.15-si.4/arch/arm/kernel/signal.c --- 2.5.15/arch/arm/kernel/signal.c Tue Apr 23 10:42:06 2002 +++ 2.5.15-si.4/arch/arm/kernel/signal.c Wed May 15 17:46:52 2002 @@ -51,42 +51,6 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - int err = -EFAULT;; - - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - goto out; - - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } -out: - return err; -} - /* * atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/i386/kernel/signal.c 2.5.15-si.4/arch/i386/kernel/signal.c --- 2.5.15/arch/i386/kernel/signal.c Fri May 10 09:35:06 2002 +++ 2.5.15-si.4/arch/i386/kernel/signal.c Wed May 15 17:56:01 2002 @@ -29,41 +29,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/m68k/kernel/signal.c 2.5.15-si.4/arch/m68k/kernel/signal.c --- 2.5.15/arch/m68k/kernel/signal.c Fri May 10 09:35:06 2002 +++ 2.5.15-si.4/arch/m68k/kernel/signal.c Wed May 15 17:47:36 2002 @@ -190,41 +190,6 @@ }; -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */ static inline int restore_fpu_state(struct sigcontext *sc) diff -ruN 2.5.15/arch/mips/kernel/signal.c 2.5.15-si.4/arch/mips/kernel/signal.c --- 2.5.15/arch/mips/kernel/signal.c Mon Apr 15 10:44:54 2002 +++ 2.5.15-si.4/arch/mips/kernel/signal.c Wed May 15 17:47:47 2002 @@ -37,41 +37,6 @@ extern asmlinkage void syscall_trace(void); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/ppc/kernel/signal.c 2.5.15-si.4/arch/ppc/kernel/signal.c --- 2.5.15/arch/ppc/kernel/signal.c Fri May 10 09:35:08 2002 +++ 2.5.15-si.4/arch/ppc/kernel/signal.c Wed May 15 17:47:53 2002 @@ -62,41 +62,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/ppc64/kernel/signal.c 2.5.15-si.4/arch/ppc64/kernel/signal.c --- 2.5.15/arch/ppc64/kernel/signal.c Fri May 3 12:08:04 2002 +++ 2.5.15-si.4/arch/ppc64/kernel/signal.c Wed May 15 17:47:59 2002 @@ -65,41 +65,6 @@ extern long sys_wait4(pid_t pid, unsigned int *stat_addr, int options, /*unsigned long*/ struct rusage *ru); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/s390/kernel/signal.c 2.5.15-si.4/arch/s390/kernel/signal.c --- 2.5.15/arch/s390/kernel/signal.c Wed Feb 20 16:36:40 2002 +++ 2.5.15-si.4/arch/s390/kernel/signal.c Wed May 15 17:48:08 2002 @@ -49,41 +49,6 @@ asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/s390x/kernel/signal.c 2.5.15-si.4/arch/s390x/kernel/signal.c --- 2.5.15/arch/s390x/kernel/signal.c Wed Feb 20 16:36:40 2002 +++ 2.5.15-si.4/arch/s390x/kernel/signal.c Wed May 15 17:48:14 2002 @@ -49,41 +49,6 @@ asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/sh/kernel/signal.c 2.5.15-si.4/arch/sh/kernel/signal.c --- 2.5.15/arch/sh/kernel/signal.c Wed Feb 20 16:36:40 2002 +++ 2.5.15-si.4/arch/sh/kernel/signal.c Wed May 15 17:48:19 2002 @@ -34,41 +34,6 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ diff -ruN 2.5.15/arch/x86_64/kernel/signal.c 2.5.15-si.4/arch/x86_64/kernel/signal.c --- 2.5.15/arch/x86_64/kernel/signal.c Tue Apr 23 10:42:14 2002 +++ 2.5.15-si.4/arch/x86_64/kernel/signal.c Wed May 15 17:48:25 2002 @@ -39,41 +39,6 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - asmlinkage long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs) { diff -ruN 2.5.15/include/asm-alpha/siginfo.h 2.5.15-si.4/include/asm-alpha/siginfo.h --- 2.5.15/include/asm-alpha/siginfo.h Tue Apr 23 10:42:28 2002 +++ 2.5.15-si.4/include/asm-alpha/siginfo.h Wed May 15 17:50:44 2002 @@ -227,6 +227,7 @@ memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); #endif /* __KERNEL__ */ diff -ruN 2.5.15/include/asm-cris/siginfo.h 2.5.15-si.4/include/asm-cris/siginfo.h --- 2.5.15/include/asm-cris/siginfo.h Mon Feb 11 17:37:27 2002 +++ 2.5.15-si.4/include/asm-cris/siginfo.h Wed May 15 17:51:21 2002 @@ -226,6 +226,7 @@ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); #endif /* __KERNEL__ */ diff -ruN 2.5.15/include/asm-ia64/siginfo.h 2.5.15-si.4/include/asm-ia64/siginfo.h --- 2.5.15/include/asm-ia64/siginfo.h Mon Apr 29 14:57:13 2002 +++ 2.5.15-si.4/include/asm-ia64/siginfo.h Wed May 15 17:52:18 2002 @@ -271,6 +271,7 @@ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from); diff -ruN 2.5.15/include/asm-mips64/siginfo.h 2.5.15-si.4/include/asm-mips64/siginfo.h --- 2.5.15/include/asm-mips64/siginfo.h Mon Feb 11 17:37:27 2002 +++ 2.5.15-si.4/include/asm-mips64/siginfo.h Wed May 15 17:53:04 2002 @@ -248,6 +248,7 @@ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); #endif /* __KERNEL__ */ diff -ruN 2.5.15/include/asm-parisc/siginfo.h 2.5.15-si.4/include/asm-parisc/siginfo.h --- 2.5.15/include/asm-parisc/siginfo.h Mon Feb 11 17:37:27 2002 +++ 2.5.15-si.4/include/asm-parisc/siginfo.h Wed May 15 17:53:21 2002 @@ -228,6 +228,7 @@ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); #endif /* __KERNEL__ */ diff -ruN 2.5.15/include/asm-sparc/siginfo.h 2.5.15-si.4/include/asm-sparc/siginfo.h --- 2.5.15/include/asm-sparc/siginfo.h Tue Mar 19 15:12:09 2002 +++ 2.5.15-si.4/include/asm-sparc/siginfo.h Wed May 15 17:54:17 2002 @@ -236,6 +236,7 @@ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); #endif /* __KERNEL__ */ diff -ruN 2.5.15/include/asm-sparc64/siginfo.h 2.5.15-si.4/include/asm-sparc64/siginfo.h --- 2.5.15/include/asm-sparc64/siginfo.h Tue Mar 19 15:12:09 2002 +++ 2.5.15-si.4/include/asm-sparc64/siginfo.h Wed May 15 17:54:36 2002 @@ -311,6 +311,7 @@ memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld)); } +#define HAVE_ARCH_COPY_SIGINFO_TO_USER extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); extern int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from); diff -ruN 2.5.15/kernel/signal.c 2.5.15-si.4/kernel/signal.c --- 2.5.15/kernel/signal.c Fri May 10 09:35:17 2002 +++ 2.5.15-si.4/kernel/signal.c Wed May 15 17:46:13 2002 @@ -16,6 +16,7 @@ #include #include +#include /* * SLAB caches for signal bits. @@ -931,6 +932,45 @@ { return do_sigpending(set, sigsetsize); } + +#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER + +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) +{ + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) + return -EFAULT; + if (from->si_code < 0) + return __copy_to_user(to, from, sizeof(siginfo_t)); + else { + int err; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + /* First 32bits of unions are always present. */ + err |= __put_user(from->si_pid, &to->si_pid); + switch (from->si_code >> 16) { + case __SI_FAULT >> 16: + break; + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_uid, &to->si_uid); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + return err; + } +} + +#endif asmlinkage long sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,