diff options
| author | Andrew Morton <akpm@digeo.com> | 2003-06-28 00:10:03 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-06-28 00:10:03 -0700 |
| commit | 6bdc026425097fd4fb921ea14bac9a10d64fb6bd (patch) | |
| tree | 25ff94610bcde36d35a45f0d2d28842ae835913e /kernel | |
| parent | fbe51b1e992ba5f92bdeff56ab6cc68748810e97 (diff) | |
[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.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/printk.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index a7a9811929b9..830b690f9692 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -186,17 +186,18 @@ int do_syslog(int type, char __user * buf, int len) 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 * buf, int len) * 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; |
