Subject: copy_from_user() bugfix

From: Ralf Baechle <[email-masked]>
Date: Fri, 18 Feb 2000 13:59:07 +0100

Appended are two patches, one for Linux 2.2 and one for 2.3, which fix
a bug copy_from_user / __copy_from_user.  When used in a module these
two functions may return a wrong result in the error case.

  Ralf
Index: include/asm-mips/uaccess.h
===================================================================
RCS file: /usr/src/cvs/linux/include/asm-mips/uaccess.h,v
retrieving revision 1.16.2.1
diff -u -r1.16.2.1 uaccess.h
--- uaccess.h	1999/10/21 21:26:27	1.16.2.1
+++ uaccess.h	2000/02/18 12:43:41
@@ -322,10 +322,12 @@
 		"move\t$4, %1\n\t" \
 		"move\t$5, %2\n\t" \
 		"move\t$6, %3\n\t" \
+		".set\tnoreorder\n\t" \
 		".set\tnoat\n\t" \
+		__MODULE_JAL(__copy_user) \
 		"addu\t$1, %2, %3\n\t" \
 		".set\tat\n\t" \
-		__MODULE_JAL(__copy_user) \
+		".set\treorder\n\t" \
 		"move\t%0, $6" \
 		: "=r" (__cu_len) \
 		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
@@ -369,10 +371,12 @@
 			"move\t$4, %1\n\t" \
 			"move\t$5, %2\n\t" \
 			"move\t$6, %3\n\t" \
+			".set\tnoreorder\n\t" \
 			".set\tnoat\n\t" \
+			__MODULE_JAL(__copy_user) \
 			"addu\t$1, %2, %3\n\t" \
 			".set\tat\n\t" \
-			__MODULE_JAL(__copy_user) \
+			".set\treorder\n\t" \
 			"move\t%0, $6" \
 			: "=r" (__cu_len) \
 			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
Index: include/asm-mips/uaccess.h
===================================================================
RCS file: /usr/src/cvs/linux/include/asm-mips/uaccess.h,v
retrieving revision 1.18
diff -u -r1.18 uaccess.h
--- uaccess.h	1999/11/19 20:35:48	1.18
+++ uaccess.h	2000/02/18 12:44:43
@@ -323,10 +323,12 @@
 		"move\t$4, %1\n\t" \
 		"move\t$5, %2\n\t" \
 		"move\t$6, %3\n\t" \
+		".set\tnoreorder\n\t" \
 		".set\tnoat\n\t" \
+		__MODULE_JAL(__copy_user) \
 		"addu\t$1, %2, %3\n\t" \
 		".set\tat\n\t" \
-		__MODULE_JAL(__copy_user) \
+		".set\treorder\n\t" \
 		"move\t%0, $6" \
 		: "=r" (__cu_len) \
 		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
@@ -370,10 +372,12 @@
 			"move\t$4, %1\n\t" \
 			"move\t$5, %2\n\t" \
 			"move\t$6, %3\n\t" \
+			".set\tnoreorder\n\t" \
 			".set\tnoat\n\t" \
+			__MODULE_JAL(__copy_user) \
 			"addu\t$1, %2, %3\n\t" \
 			".set\tat\n\t" \
-			__MODULE_JAL(__copy_user) \
+			".set\treorder\n\t" \
 			"move\t%0, $6" \
 			: "=r" (__cu_len) \
 			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
Index: include/asm-mips64/uaccess.h
===================================================================
RCS file: /usr/src/cvs/linux/include/asm-mips64/uaccess.h,v
retrieving revision 1.4
diff -u -r1.4 uaccess.h
--- uaccess.h	1999/11/19 20:35:49	1.4
+++ uaccess.h	2000/02/18 12:48:43
@@ -261,10 +261,12 @@
 		"move\t$4, %1\n\t" \
 		"move\t$5, %2\n\t" \
 		"move\t$6, %3\n\t" \
+		".set\tnoreorder\n\t" \
 		".set\tnoat\n\t" \
-		"addu\t$1, %2, %3\n\t" \
-		".set\tat\n\t" \
 		__MODULE_JAL(__copy_user) \
+		"daddu\t$1, %2, %3\n\t" \
+		".set\tat\n\t" \
+		".set\treorder\n\t" \
 		"move\t%0, $6" \
 		: "=r" (__cu_len) \
 		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
@@ -308,10 +310,12 @@
 			"move\t$4, %1\n\t" \
 			"move\t$5, %2\n\t" \
 			"move\t$6, %3\n\t" \
+			".set\tnoreorder\n\t" \
 			".set\tnoat\n\t" \
-			"addu\t$1, %2, %3\n\t" \
-			".set\tat\n\t" \
 			__MODULE_JAL(__copy_user) \
+			"daddu\t$1, %2, %3\n\t" \
+			".set\tat\n\t" \
+			".set\treorder\n\t" \
 			"move\t%0, $6" \
 			: "=r" (__cu_len) \
 			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \