patch-2.4.0-test1 linux/arch/sparc64/kernel/signal.c

Next file: linux/arch/sparc64/kernel/signal32.c
Previous file: linux/arch/sparc64/kernel/ioctl32.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre9/linux/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
@@ -42,6 +42,38 @@
 /* #define DEBUG_SIGNALS_TRACE 1 */
 /* #define DEBUG_SIGNALS_MAPS 1 */
 
+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(*(long *)&from->si_signo, (long *)&to->si_signo);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		switch (from->si_code >> 16) {
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+		case __SI_FAULT >> 16:
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_trapno, &to->si_trapno);
+		default:
+			err |= __put_user(from->si_addr, &to->si_addr);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
 /* {set, get}context() needed for 64-bit SparcLinux userland. */
 asmlinkage void sparc64_set_context(struct pt_regs *regs)
 {
@@ -512,7 +544,7 @@
 			    sizeof(struct reg_window));
 
 	if (info)
-		err |= copy_to_user(&sf->info, info, sizeof(siginfo_t));
+		err |= copy_siginfo_to_user(&sf->info, info);
 	else {
 		err |= __put_user(signo, &sf->info.si_signo);
 		err |= __put_user(SI_NOINFO, &sf->info.si_code);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)