Messages in this thread Patches in this message | | | From | Topi Miettinen <> | Subject | /proc/kmsg bug (patches for 2.1.10[78], 2.0.35) | Date | Thu, 16 Jul 1998 22:30:05 +0300 |
| |
After some weeks of success in a couple of machines running 2.1.107, I'd like to submit these patches for inclusion in the kernel. As you might remember (yeah, sure), /proc/kmsg doesn't behave like normal file with regard to open() and unprivileged read(). The patch moves log reading to a function of its own, really trivial. 2.0.35 doesn't have [un]lock_kernel() so those calls are dropped, but otherwise the patch is almost identical.
My goal is getting /sbin/klogd to setuid(kloguser) after opening /proc/kmsg. If anyone wants to test that, please look at http://www.debian.org/Bugs/db/24/24326.html for a patch to Debian sysklogd package.
-Topi
diff -ru linux-2.1.107/fs/proc/kmsg.c.orig linux-2.1.107/fs/proc/kmsg.c --- linux-2.1.107/fs/proc/kmsg.c.orig Fri Feb 27 05:54:49 1998 +++ linux-2.1.107/fs/proc/kmsg.c Sun Jun 28 14:43:51 1998 @@ -10,6 +10,7 @@ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/poll.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -18,6 +19,7 @@ extern struct wait_queue * log_wait; asmlinkage int sys_syslog(int type, char * bug, int count); +asmlinkage int read_log(char * buf, int count); static int kmsg_open(struct inode * inode, struct file * file) { @@ -33,7 +35,12 @@ static ssize_t kmsg_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - return sys_syslog(2,buf,count); + int error; + + lock_kernel(); + error = read_log(buf,count); + unlock_kernel(); + return error; } static unsigned int kmsg_poll(struct file *file, poll_table * wait) diff -ru linux-2.1.107/kernel/printk.c.orig linux-2.1.107/kernel/printk.c --- linux-2.1.107/kernel/printk.c.orig Wed May 6 20:56:06 1998 +++ linux-2.1.107/kernel/printk.c Sun Jun 28 14:46:53 1998 @@ -108,6 +108,46 @@ c->index = idx; } +asmlinkage int read_log(char * buf, int len) +{ + unsigned long i; + char c; + int error = -EINVAL; + + if (!buf || len < 0) + goto out; + error = 0; + if (!len) + goto out; + error = verify_area(VERIFY_WRITE,buf,len); + if (error) + goto out; + cli(); + error = -ERESTARTSYS; + while (!log_size) { + if (signal_pending(current)) { + sti(); + goto out; + } + interruptible_sleep_on(&log_wait); + } + i = 0; + while (log_size && i < len) { + c = *((char *) log_buf+log_start); + log_start++; + log_size--; + log_start &= LOG_BUF_LEN-1; + sti(); + __put_user(c,buf); + buf++; + i++; + cli(); + } + sti(); + error = i; +out: + return error; +} /* * Commands to sys_syslog: @@ -139,38 +179,7 @@ case 1: /* Open log */ break; case 2: /* Read from log */ - error = -EINVAL; - if (!buf || len < 0) - goto out; - error = 0; - if (!len) - goto out; - error = verify_area(VERIFY_WRITE,buf,len); - if (error) - goto out; - cli(); - error = -ERESTARTSYS; - while (!log_size) { - if (signal_pending(current)) { - sti(); - goto out; - } - interruptible_sleep_on(&log_wait); - } - i = 0; - while (log_size && i < len) { - c = *((char *) log_buf+log_start); - log_start++; - log_size--; - log_start &= LOG_BUF_LEN-1; - sti(); - __put_user(c,buf); - buf++; - i++; - cli(); - } - sti(); - error = i; + error = read_log(buf, len); break; case 4: /* Read/clear last kernel messages */ do_clear = 1;
--- linux-2.0.35/fs/proc/kmsg.c.orig Fri Dec 22 13:00:19 1995 +++ linux-2.0.35/fs/proc/kmsg.c Thu Jul 16 21:53:25 1998 @@ -17,6 +17,7 @@ extern struct wait_queue * log_wait; asmlinkage int sys_syslog(int type, char * bug, int count); +asmlinkage int read_log(char * buf, int count); static int kmsg_open(struct inode * inode, struct file * file) { @@ -30,7 +31,7 @@ static int kmsg_read(struct inode * inode, struct file * file,char * buf, int count) { - return sys_syslog(2,buf,count); + return read_log(buf,count); } static int kmsg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) diff -ru linux-2.0.35/kernel/printk.c.orig linux-2.0.35/kernel/printk.c --- linux-2.0.35/kernel/printk.c.orig Fri Jun 7 11:54:06 1996 +++ linux-2.0.35/kernel/printk.c Thu Jul 16 21:50:44 1998 @@ -45,6 +45,47 @@ static unsigned long log_start = 0; static unsigned long logged_chars = 0; +asmlinkage int read_log(char * buf, int len) +{ + unsigned long i; + char c; + int error = -EINVAL; + + if (!buf || len < 0) + goto out; + error = 0; + if (!len) + goto out; + error = verify_area(VERIFY_WRITE,buf,len); + if (error) + goto out; + cli(); + error = -ERESTARTSYS; + while (!log_size) { + if (signal_pending(current)) { + sti(); + goto out; + } + interruptible_sleep_on(&log_wait); + } + i = 0; + while (log_size && i < len) { + c = *((char *) log_buf+log_start); + log_start++; + log_size--; + log_start &= LOG_BUF_LEN-1; + sti(); + __put_user(c,buf); + buf++; + i++; + cli(); + } + sti(); + error = i; +out: + return error; +} + /* * Commands to sys_syslog: * @@ -73,35 +114,7 @@ case 1: /* Open log */ return 0; case 2: /* Read from log */ - if (!buf || len < 0) - return -EINVAL; - if (!len) - return 0; - error = verify_area(VERIFY_WRITE,buf,len); - if (error) - return error; - cli(); - while (!log_size) { - if (current->signal & ~current->blocked) { - sti(); - return -ERESTARTSYS; - } - interruptible_sleep_on(&log_wait); - } - i = 0; - while (log_size && i < len) { - c = *((char *) log_buf+log_start); - log_start++; - log_size--; - log_start &= LOG_BUF_LEN-1; - sti(); - put_user(c,buf); - buf++; - i++; - cli(); - } - sti(); - return i; + return read_log(buf, len); case 4: /* Read/clear last kernel messages */ do_clear = 1; /* FALL THRU */
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html
| |