[PATCH] signal cleanup continued: rationalise copy_siginfo_to_user

Stephen Rothwell (sfr@canb.auug.org.au)
Thu, 16 May 2002 10:32:14 +1000


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 o