RedHat 5.2
Date: Mon, 9 Nov 1998 14:34:58 +0100
From: Alexander Kjeldaas <[email protected]>
To: Chris Evans <[email protected]>,
Subject: Re: RedHat 5.2
Cc: [email protected], Alan Cox <[email protected]>
On Mon, Nov 02, 1998 at 06:59:42PM +0000, Chris Evans wrote:
>
> > -rwsr-xr-x 1 root root 5508 Oct 3 01:40 /usr/X11R6/bin/XConsole
>
> I shall be checking that this now opens the /proc/kmsg as a first action
> then drops privs.
>
The problem is that the kernel is buggy for /proc/kmesg. It will
check your privileges on each read. I use the following patch to
remedy the situation and make it possible to run a non-root klogd.
The patch is from the Debian sysklogd maintainer.
astor
diff -urN linux-2.1.122/fs/proc/kmsg.c linux-2.1.122-samsix/fs/proc/kmsg.c
--- linux-2.1.122/fs/proc/kmsg.c Wed Sep 23 01:41:40 1998
+++ linux-2.1.122-samsix/fs/proc/kmsg.c Wed Sep 23 01:43:07 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)
--- linux-2.1.122/kernel/printk.c Wed Sep 23 01:41:40 1998
+++ linux-2.1.122-samsix/kernel/printk.c Wed Sep 23 01:43:07 1998
@@ -107,6 +107,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:
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;
astor
--
Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway
http://www.guardian.no/