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

Next file: linux/arch/i386/kernel/smp.c
Previous file: linux/arch/i386/kernel/setup.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre9/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
@@ -4,6 +4,8 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *  Pentium III support by Ingo Molnar, modifications and OS Exception support
+ *              by Goutham Rao
  */
 
 #include <linux/config.h>
@@ -30,6 +32,41 @@
 			 int options, unsigned long *ru);
 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.
  */
@@ -155,7 +192,7 @@
 {
 	struct task_struct *tsk = current;
 	clear_fpu(tsk);
-	return __copy_from_user(&tsk->thread.i387.hard, buf, sizeof(*buf));
+	return i387_user_to_hard(&tsk->thread.i387.hard, buf);
 }
 
 static inline int restore_i387(struct _fpstate *buf)
@@ -309,7 +346,7 @@
 
 	unlazy_fpu(tsk);
 	tsk->thread.i387.hard.status = tsk->thread.i387.hard.swd;
-	if (__copy_to_user(buf, &tsk->thread.i387.hard, sizeof(*buf)))
+	if (i387_hard_to_user(buf, &tsk->thread.i387.hard))
 		return -1;
 	return 1;
 }
@@ -491,7 +528,7 @@
 			  &frame->sig);
 	err |= __put_user(&frame->info, &frame->pinfo);
 	err |= __put_user(&frame->uc, &frame->puc);
-	err |= __copy_to_user(&frame->info, info, sizeof(*info));
+	err |= copy_siginfo_to_user(&frame->info, info);
 	if (err)
 		goto give_sigsegv;
 

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