summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-06-28 00:10:03 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-06-28 00:10:03 -0700
commit6bdc026425097fd4fb921ea14bac9a10d64fb6bd (patch)
tree25ff94610bcde36d35a45f0d2d28842ae835913e /kernel
parentfbe51b1e992ba5f92bdeff56ab6cc68748810e97 (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.c21
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;