Commit 6bdc0264 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix syslog(2) EFAULT reporting

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.
parent fbe51b1e
...@@ -186,17 +186,18 @@ int do_syslog(int type, char __user * buf, int len) ...@@ -186,17 +186,18 @@ int do_syslog(int type, char __user * buf, int len)
goto out; goto out;
i = 0; i = 0;
spin_lock_irq(&logbuf_lock); 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); c = LOG_BUF(log_start);
log_start++; log_start++;
spin_unlock_irq(&logbuf_lock); spin_unlock_irq(&logbuf_lock);
__put_user(c,buf); error = __put_user(c,buf);
buf++; buf++;
i++; i++;
spin_lock_irq(&logbuf_lock); spin_lock_irq(&logbuf_lock);
} }
spin_unlock_irq(&logbuf_lock); spin_unlock_irq(&logbuf_lock);
error = i; if (!error)
error = i;
break; break;
case 4: /* Read/clear last kernel messages */ case 4: /* Read/clear last kernel messages */
do_clear = 1; do_clear = 1;
...@@ -226,26 +227,30 @@ int do_syslog(int type, char __user * buf, int len) ...@@ -226,26 +227,30 @@ int do_syslog(int type, char __user * buf, int len)
* we try to copy to user space. Therefore * we try to copy to user space. Therefore
* the messages are copied in reverse. <manfreds> * the messages are copied in reverse. <manfreds>
*/ */
for(i=0;i < count;i++) { for(i = 0; i < count && !error; i++) {
j = limit-1-i; j = limit-1-i;
if (j+LOG_BUF_LEN < log_end) if (j+LOG_BUF_LEN < log_end)
break; break;
c = LOG_BUF(j); c = LOG_BUF(j);
spin_unlock_irq(&logbuf_lock); 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_lock_irq(&logbuf_lock);
} }
spin_unlock_irq(&logbuf_lock); spin_unlock_irq(&logbuf_lock);
if (error)
break;
error = i; error = i;
if(i != count) { if(i != count) {
int offset = count-error; int offset = count-error;
/* buffer overflow during copy, correct user buffer. */ /* buffer overflow during copy, correct user buffer. */
for(i=0;i<error;i++) { for(i=0;i<error;i++) {
__get_user(c,&buf[i+offset]); if (__get_user(c,&buf[i+offset]) ||
__put_user(c,&buf[i]); __put_user(c,&buf[i])) {
error = -EFAULT;
break;
}
} }
} }
break; break;
case 5: /* Clear ring buffer */ case 5: /* Clear ring buffer */
logged_chars = 0; logged_chars = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment