linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] signal cleanup continued: rationalise copy_siginfo_to_user
@ 2002-05-16  0:32 Stephen Rothwell
  0 siblings, 0 replies; only message in thread
From: Stephen Rothwell @ 2002-05-16  0:32 UTC (permalink / raw)
  To: Linus; +Cc: linux-kernel

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 <linux/fs.h>
 
 #include <asm/uaccess.h>
+#include <asm/siginfo.h>
 
 /*
  * 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,

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-05-16  0:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-16  0:32 [PATCH] signal cleanup continued: rationalise copy_siginfo_to_user Stephen Rothwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).