
From: Andi Kleen <ak@suse.de>

Add proper EFAULT reporting to sys_syslog.

This fixes some silly LTP test in the 32bit emulation of an AMD64 kernel.



 kernel/printk.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff -puN kernel/printk.c~syslog-efault-reporting kernel/printk.c
--- 25/kernel/printk.c~syslog-efault-reporting	2003-06-26 18:42:15.000000000 -0700
+++ 25-akpm/kernel/printk.c	2003-06-26 18:42:15.000000000 -0700
@@ -186,17 +186,18 @@ int do_syslog(int type, char __user * bu
 			goto out;
 		i = 0;
 		spin_lock_irq(&logbuf_lock);
-		while ((log_start != log_end) && i < len) {
+		while (!error && (log_start != log_end) && i < len) {
 			c = LOG_BUF(log_start);
 			log_start++;
 			spin_unlock_irq(&logbuf_lock);
-			__put_user(c,buf);
+			error = __put_user(c,buf);
 			buf++;
 			i++;
 			spin_lock_irq(&logbuf_lock);
 		}
 		spin_unlock_irq(&logbuf_lock);
-		error = i;
+		if (!error)
+			error = i;
 		break;
 	case 4:		/* Read/clear last kernel messages */
 		do_clear = 1; 
@@ -226,26 +227,30 @@ int do_syslog(int type, char __user * bu
 		 * we try to copy to user space. Therefore
 		 * the messages are copied in reverse. <manfreds>
 		 */
-		for(i=0;i < count;i++) {
+		for(i = 0; i < count && !error; i++) {
 			j = limit-1-i;
 			if (j+LOG_BUF_LEN < log_end)
 				break;
 			c = LOG_BUF(j);
 			spin_unlock_irq(&logbuf_lock);
-			__put_user(c,&buf[count-1-i]);
+			error = __put_user(c,&buf[count-1-i]);
 			spin_lock_irq(&logbuf_lock);
 		}
 		spin_unlock_irq(&logbuf_lock);
+		if (error)
+			break;
 		error = i;
 		if(i != count) {
 			int offset = count-error;
 			/* buffer overflow during copy, correct user buffer. */
 			for(i=0;i<error;i++) {
-				__get_user(c,&buf[i+offset]);
-				__put_user(c,&buf[i]);
+				if (__get_user(c,&buf[i+offset]) ||
+				    __put_user(c,&buf[i])) {
+					error = -EFAULT;
+					break;
+				}
 			}
 		}
-
 		break;
 	case 5:		/* Clear ring buffer */
 		logged_chars = 0;

_
