From e54a5dfb960053437f464a7ce372a8acc293fdcb Mon Sep 17 00:00:00 2001
From: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Date: Sat, 3 Sep 2005 15:57:27 -0700
Subject: [PATCH] uml: fix signal frame copy_user

The copy_user stuff in the signal frame code was broke.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 arch/um/sys-i386/signal.c   |  2 +-
 arch/um/sys-x86_64/signal.c | 41 ++++++++++++++++++++++++-----------------
 2 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 4efc69a039d..16bc19928b3 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -122,9 +122,9 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
 	int err;
 
 	to_fp = to->fpstate;
-	from_fp = from->fpstate;
 	sigs = to->oldmask;
 	err = copy_from_user(to, from, sizeof(*to));
+	from_fp = to->fpstate;
 	to->oldmask = sigs;
 	to->fpstate = to_fp;
 	if(to_fp != NULL)
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 8fdaed06c10..fe1d065332b 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -104,28 +104,35 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
 int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
                         int fpsize)
 {
-       struct _fpstate *to_fp, *from_fp;
-       unsigned long sigs;
-       int err;
-
-       to_fp = to->fpstate;
-       from_fp = from->fpstate;
-       sigs = to->oldmask;
-       err = copy_from_user(to, from, sizeof(*to));
-       to->oldmask = sigs;
-       return(err);
+	struct _fpstate *to_fp, *from_fp;
+	unsigned long sigs;
+	int err;
+
+	to_fp = to->fpstate;
+	sigs = to->oldmask;
+	err = copy_from_user(to, from, sizeof(*to));
+	from_fp = to->fpstate;
+	to->fpstate = to_fp;
+	to->oldmask = sigs;
+	if(to_fp != NULL)
+		err |= copy_from_user(to_fp, from_fp, fpsize);
+	return(err);
 }
 
 int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
                       struct sigcontext *from, int fpsize)
 {
-       struct _fpstate *to_fp, *from_fp;
-       int err;
-
-       to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
-       from_fp = from->fpstate;
-       err = copy_to_user(to, from, sizeof(*to));
-       return(err);
+	struct _fpstate *to_fp, *from_fp;
+	int err;
+
+	to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
+	from_fp = from->fpstate;
+	err = copy_to_user(to, from, sizeof(*to));
+	if(from_fp != NULL){
+		err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
+		err |= copy_to_user(to_fp, from_fp, fpsize);
+	}
+	return(err);
 }
 
 #endif
-- 
cgit v1.2.3-18-g5258