lkml.org 
[lkml]   [1998]   [Jun]   [28]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
FromTopi Miettinen <>
Subject/proc/kmsg oddness, patch
DateSun, 28 Jun 1998 15:05:51 +0300
It would seem like /proc/kmsg would work differently from normal file
regarding open and read.

# ls -l /proc/kmsg /proc/1/environ 
-r--------   1 root     root            0 Jun 28 14:52 /proc/1/environ
-r--------   1 root     root            0 Jun 28 14:52 /proc/kmsg
# su - nobody -c 'cat /proc/1/environ'
cat: /proc/1/environ: Permission denied
# su - nobody -c 'cat /proc/kmsg'
cat: /proc/kmsg: Permission denied
# su - nobody -c 'cat -v' </proc/1/environ 
HOME=[cut]
# su - nobody -c cat </proc/kmsg 
cat: -: Operation not permitted
So, non-root read() from open fd that points to /proc/kmsg fails. This
happens because kmsg_read() calls sys_syslog(2, buf, count), which is
restricted to capable users only.

This untested patch attempts to fix it, but is it the Way?

What I'm really trying to do is getting /sbin/klogd to setuid(kloguser)
after opening /proc/kmsg.

-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; 


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 12:43    [from the cache]
©2003-2008