Author: robert
Date: 2008-01-18 14:13:49 -0700 (Fri, 18 Jan 2008)
New Revision: 1896

Added:
   trunk/sysklogd/sysklogd-1.5-priv_sep-1.patch
Log:
Added sysklogd-1.5-priv_sep-1.patch

Added: trunk/sysklogd/sysklogd-1.5-priv_sep-1.patch
===================================================================
--- trunk/sysklogd/sysklogd-1.5-priv_sep-1.patch                                
(rev 0)
+++ trunk/sysklogd/sysklogd-1.5-priv_sep-1.patch        2008-01-18 21:13:49 UTC 
(rev 1896)
@@ -0,0 +1,445 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
+Date: 2008-01-18
+Initial Package Version: 1.5
+Upstream Status: Submitted - Partially.. the Owl patches were submitted
+                 http://www.infodrom.org/projects/sysklogd/download/patches/
+Origin:        http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/sysklogd/
+       sysklogd-1.4.2-caen-owl-klogd-drop-root.diff    v1.2
+       sysklogd-1.4.2-caen-owl-syslogd-drop-root.diff  v1.1
+       sysklogd-1.4.2-alt-syslogd-chroot.diff          v1.2
+       and the '-P' option from sysklogd_1.4.1-16ubuntu6.diff
+Description: This patch adds the '-j' option to syslogd and klogd, so they
+can chroot into a jail. This patch also adds the '-u' option to syslogd and
+klogd, so they can change to the specified username before entering the jail.
+This patch also adds '-P' to klogd so it can use an alternative /proc/kmsg
+file, which is nescessary with Linux-2.6 and also works with Linux-2.4.
+
+To get klogd to drop privileges and work with Linux-2.6, root must make a
+second copy of /proc/kmsg because the kernel checks for the CAP_SYS_ADMIN
+capability before every read to /proc/kmsg. In Linux-2.4 the capability is
+only checked when /proc/kmsg is first opened.
+
+Set up syslogd and klogd as regular users in a chroot jail like this:
+
+groupadd syslogd
+groupadd klogd
+useradd -d /var/lib/syslogd -s /bin/false -g syslogd syslogd
+useradd -d /var/lib/klogd -s /bin/false -g klogd klogd
+
+install -d -m0000 /var/lib/syslogd
+install -d -m0000 /var/lib/klogd
+
+This is a snippet of my /etc/rc.d/init.d/sysklogd file:
+
+       start)
+               boot_mesg "Starting system log daemon..."
+               loadproc /usr/sbin/syslogd -m 0 -u syslogd -j /var/lib/syslogd
+
+               boot_mesg "Starting kernel log daemon..."
+               /usr/bin/install -d -m0700 -o root -g root /var/run/klogd
+               /usr/bin/mkfifo -m 700 /var/run/klogd/kmsg
+               /bin/chown klogd:klogd /var/run/klogd/kmsg
+               /bin/sh -c -- '/bin/dd bs=1 if=/proc/kmsg 
of=/var/run/klogd/kmsg &'
+               loadproc /usr/sbin/klogd -x -u klogd -j /var/lib/klogd \
+                       -P /var/run/klogd/kmsg
+       ;;
+
+       stop)
+               boot_mesg "Stopping kernel log daemon..."
+               killproc /usr/sbin/klogd
+               /bin/fuser -s -k /var/run/klogd/kmsg
+               /bin/rm -f /var/run/klogd/kmsg
+
+               boot_mesg "Stopping system log daemon..."
+               killproc /usr/sbin/syslogd
+       ;;
+
+Remove the 'reload)' function, it will not work correctly after the daemons
+have dropped to regular users. For the same reason, do not use 'kill -HUP'
+with syslogd or klogd.
+
+The klogd daemon does not need to ever be root, but root privileges are
+needed to chroot the klogd daemon. If you prefer klogd can be started with
+'/bin/su', or the 'runas' program:
+http://www.ibiblio.org/pub/Linux/system/security/runas-1.01.tar.gz
+Also make sure the klogd user is able to read and execute /usr/sbin/klogd.
+
+diff -Naur sysklogd-1.5.orig/klogd.8 sysklogd-1.5.priv_sep/klogd.8
+--- sysklogd-1.5.orig/klogd.8  2007-05-28 17:25:43.000000000 +0000
++++ sysklogd-1.5.priv_sep/klogd.8      2008-01-18 02:46:52.000000000 +0000
+@@ -14,10 +14,19 @@
+ .RB [ " \-f "
+ .I fname
+ ]
++.RB [ " \-u "
++.I username
++]
++.RB [ " \-j "
++.I chroot_dir
++]
+ .RB [ " \-iI " ]
+ .RB [ " \-n " ]
+ .RB [ " \-o " ]
+ .RB [ " \-p " ]
++.RB [ " \-P "
++.I named_pipe
++]
+ .RB [ " \-s " ]
+ .RB [ " \-k "
+ .I fname
+@@ -41,6 +50,20 @@
+ .BI "\-f " file
+ Log messages to the specified filename rather than to the syslog facility.
+ .TP
++.BI "\-u " username
++Tells klogd to become the specified user and drop root privileges before
++starting logging.
++.TP
++.BI "\-j " chroot_dir
++Tells klogd to
++.BR chroot (2)
++into this directory after initializing.
++This option is only valid if the \-u option is also used to run klogd
++without root privileges.
++Note that the use of this option will prevent \-i and \-I from working
++unless you set up the chroot directory in such a way that klogd can still
++read the kernel module symbols.
++.TP
+ .BI "\-i \-I"
+ Signal the currently executing klogd daemon.  Both of these switches control
+ the loading/reloading of symbol information.  The \-i switch signals the
+@@ -64,6 +87,13 @@
+ symbol information whenever an Oops string is detected in the kernel message
+ stream.
+ .TP
++.B "-P"
++Read kernel messages from an alternative location, instead of from
++.IR /proc/kmsg .
++If \- is the argument then messages will be read from \fBstdin\fP, otherwise
++the argument must be the path of a FIFO named pipe created with
++.BR mkfifo (1) .
++.TP
+ .B "\-s"
+ Force \fBklogd\fP to use the system call interface to the kernel message
+ buffers.
+diff -Naur sysklogd-1.5.orig/klogd.c sysklogd-1.5.priv_sep/klogd.c
+--- sysklogd-1.5.orig/klogd.c  2007-06-17 19:21:55.000000000 +0000
++++ sysklogd-1.5.priv_sep/klogd.c      2008-01-18 02:42:43.000000000 +0000
+@@ -268,6 +268,8 @@
+ #include <stdarg.h>
+ #include <paths.h>
+ #include <stdlib.h>
++#include <pwd.h>
++#include <grp.h>
+ #include "klogd.h"
+ #include "ksyms.h"
+ #ifndef TESTING
+@@ -313,11 +315,16 @@
+ 
+ static FILE *output_file = (FILE *) 0;
+ 
++static char *kmsg_file = NULL;        /* NULL means default /proc/kmsg */
++
+ static enum LOGSRC {none, proc, kernel} logsrc;
+ 
+ int debugging = 0;
+ int symbols_twice = 0;
+ 
++char *server_user = NULL;
++char *chroot_dir = NULL;
++int log_flags = 0;
+ 
+ /* Function prototypes. */
+ extern int ksyslog(int type, char *buf, int len);
+@@ -543,12 +550,29 @@
+                      "console output.");
+       }
+ 
++      /* Do we read kernel messages from a pipe? */
++      if ( kmsg_file ) {
++              if ( !strcmp(kmsg_file, "-") )
++                      kmsg = fileno(stdin);
++              else {
++                      if ( (kmsg = open(kmsg_file, O_RDONLY)) < 0 )
++                      {
++                              fprintf(stderr, "klogd: Cannot open kmsg file, 
" \
++                                      "%d - %s.\n", errno, strerror(errno));
++                              ksyslog(7, NULL, 0);
++                              exit(1);
++                      }
++              }
++              return proc;
++      }
++
+       /*
+        * First do a stat to determine whether or not the proc based
+        * file system is available to get kernel messages from.
+        */
+-      if ( use_syscall ||
+-          ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) )
++      if (!server_user &&
++          (use_syscall ||
++          ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT))))
+       {
+               /* Initialize kernel logging. */
+               ksyslog(1, NULL, 0);
+@@ -972,6 +996,27 @@
+ }
+ 
+ 
++static int drop_root(void)
++{
++      struct passwd *pw;
++
++      if (!(pw = getpwnam(server_user))) return -1;
++
++      if (!pw->pw_uid) return -1;
++
++      if (chroot_dir) {
++              if (chdir(chroot_dir)) return -1;
++              if (chroot(".")) return -1;
++      }
++
++      if (setgroups(0, NULL)) return -1;
++      if (setgid(pw->pw_gid)) return -1;
++      if (setuid(pw->pw_uid)) return -1;
++
++      return 0;
++}
++
++
+ int main(argc, argv)
+ 
+       int argc;
+@@ -990,7 +1035,7 @@
+       chdir ("/");
+ #endif
+       /* Parse the command-line. */
+-      while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2")) != EOF)
++      while ((ch = getopt(argc, argv, "c:df:u:j:iIk:nopP:svx2")) != EOF)
+               switch((char)ch)
+               {
+                   case '2':           /* Print lines with symbols twice. */
+@@ -1012,6 +1057,10 @@
+                   case 'I':
+                       SignalDaemon(SIGUSR2);
+                       return(0);
++                  case 'j':           /* chroot 'j'ail */
++                      chroot_dir = optarg;
++                      log_flags |= LOG_NDELAY;
++                      break;
+                   case 'k':           /* Kernel symbol file. */
+                       symfile = optarg;
+                       break;
+@@ -1024,9 +1073,15 @@
+                   case 'p':
+                       SetParanoiaLevel(1);    /* Load symbols on oops. */
+                       break;  
++                  case 'P':           /* Alternative kmsg file path */
++                       kmsg_file = strdup(optarg);
++                       break;
+                   case 's':           /* Use syscall interface. */
+                       use_syscall = 1;
+                       break;
++                  case 'u':           /* Run as this user */
++                      server_user = optarg;
++                      break;
+                   case 'v':
+                       printf("klogd %s.%s\n", VERSION, PATCHLEVEL);
+                       exit (1);
+@@ -1035,6 +1090,10 @@
+                       break;
+               }
+ 
++      if (chroot_dir && !server_user) {
++              fputs("'-j' is only valid with '-u'\n", stderr);
++              exit(1);
++      }
+ 
+       /* Set console logging level. */
+       if ( log_level != (char *) 0 )
+@@ -1144,7 +1203,7 @@
+               }
+       }
+       else
+-              openlog("kernel", 0, LOG_KERN);
++              openlog("kernel", log_flags, LOG_KERN);
+ 
+ 
+       /* Handle one-shot logging. */
+@@ -1176,6 +1235,11 @@
+               kill (ppid, SIGTERM);
+ #endif
+ 
++      if (server_user && drop_root()) {
++              syslog(LOG_ALERT, "klogd: failed to drop root");
++              Terminate();
++      }
++
+         /* The main loop. */
+       while (1)
+       {
+diff -Naur sysklogd-1.5.orig/sysklogd.8 sysklogd-1.5.priv_sep/sysklogd.8
+--- sysklogd-1.5.orig/sysklogd.8       2007-05-27 12:16:17.000000000 +0000
++++ sysklogd-1.5.priv_sep/sysklogd.8   2008-01-18 02:42:43.000000000 +0000
+@@ -29,6 +29,12 @@
+ .RB [ " \-s "
+ .I domainlist
+ ]
++.RB [ " \-u"
++.IB username
++]
++.RB [ " \-j "
++.I chroot_dir
++]
+ .RB [ " \-v " ]
+ .SH DESCRIPTION
+ .B Sysklogd
+@@ -150,6 +156,32 @@
+ no domain would be cut, you will have to specify two domains like:
+ .BR "\-s north.de:infodrom.north.de" .
+ .TP
++.BI "\-u " "username"
++This causes the
++.B syslogd
++daemon to become the named user before starting up logging.
++
++Note that when this option is in use,
++.B syslogd
++will open all log files as root when the daemon is first started;
++however, after a
++.B SIGHUP
++the files will be reopened as the non-privileged user.  You should
++take this into account when deciding the ownership of the log files.
++.TP
++.BI "\-j " chroot_dir
++Tells
++.B syslogd
++daemon to
++.BR chroot (2)
++into this directory after initializing.
++This option is only valid if the \-u option is also used to run
++.B syslogd
++without root privileges.
++Note that the use of this option will prevent
++.B SIGHUP
++from working which makes daemon reload practically impossible.
++.TP
+ .B "\-v"
+ Print version and exit.
+ .SH SIGNALS
+diff -Naur sysklogd-1.5.orig/syslogd.c sysklogd-1.5.priv_sep/syslogd.c
+--- sysklogd-1.5.orig/syslogd.c        2007-07-04 19:04:01.000000000 +0000
++++ sysklogd-1.5.priv_sep/syslogd.c    2008-01-18 02:51:30.000000000 +0000
+@@ -538,6 +538,9 @@
+ #include <sys/resource.h>
+ #include <signal.h>
+ 
++#include <pwd.h>
++#include <grp.h>
++
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <syscall.h>
+@@ -790,6 +793,9 @@
+ int   NoHops = 1;             /* Can we bounce syslog messages through an
+                                  intermediate host. */
+ 
++char  *server_user = NULL;    /* user name to run server as */
++char  *chroot_dir = NULL;     /* user name to run server as */
++
+ extern        int errno;
+ 
+ /* Function prototypes. */
+@@ -830,6 +836,26 @@
+ static int create_inet_socket();
+ #endif
+ 
++static int drop_root(void)
++{
++      struct passwd *pw;
++
++      if (!(pw = getpwnam(server_user))) return -1;
++
++      if (!pw->pw_uid) return -1;
++
++      if (chroot_dir) {
++              if (chdir(chroot_dir)) return -1;
++              if (chroot(".")) return -1;
++      }
++
++      if (initgroups(server_user, pw->pw_gid)) return -1;
++      if (setgid(pw->pw_gid)) return -1;
++      if (setuid(pw->pw_uid)) return -1;
++
++      return 0;
++}
++
+ int main(argc, argv)
+       int argc;
+       char **argv;
+@@ -886,7 +912,7 @@
+               funix[i]  = -1;
+       }
+ 
+-      while ((ch = getopt(argc, argv, "a:dhf:l:m:np:rs:v")) != EOF)
++      while ((ch = getopt(argc, argv, "a:dhf:j:l:m:np:rs:u:v")) != EOF)
+               switch((char)ch) {
+               case 'a':
+                       if (nfunix < MAXFUNIX)
+@@ -903,9 +929,12 @@
+               case 'h':
+                       NoHops = 0;
+                       break;
++              case 'j':
++                      chroot_dir = optarg;
++                      break;
+               case 'l':
+                       if (LocalHosts) {
+-                              fprintf (stderr, "Only one -l argument 
allowed," \
++                              fprintf(stderr, "Only one -l argument allowed, "
+                                       "the first one is taken.\n");
+                               break;
+                       }
+@@ -931,6 +960,9 @@
+                       }
+                       StripDomains = crunch_list(optarg);
+                       break;
++              case 'u':
++                      server_user = optarg;
++                      break;
+               case 'v':
+                       printf("syslogd %s.%s\n", VERSION, PATCHLEVEL);
+                       exit (0);
+@@ -941,6 +973,10 @@
+       if ((argc -= optind))
+               usage();
+ 
++      if (chroot_dir && !server_user) {
++              fputs("'-j' is only valid with '-u'\n", stderr);
++              exit(1);
++      }
+ #ifndef TESTING
+       if ( !(Debug || NoFork) )
+       {
+@@ -1087,6 +1123,11 @@
+               kill (ppid, SIGTERM);
+ #endif
+ 
++      if (server_user && drop_root()) {
++              dprintf("syslogd: failed to drop root\n");
++              exit(1);
++      }
++
+       /* Main loop begins here. */
+       for (;;) {
+               int nfds;
+@@ -1239,7 +1280,7 @@
+ int usage()
+ {
+       fprintf(stderr, "usage: syslogd [-drvh] [-l hostlist] [-m markinterval] 
[-n] [-p path]\n" \
+-              " [-s domainlist] [-f conffile]\n");
++              " [-s domainlist] [-f conffile] [-j chrootjail] [-u 
username]\n");
+       exit(1);
+ }
+ 

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to