On Wed, Apr 13, 2011 at 11:29:50AM +0200, Stefano Zacchiroli wrote: > On Wed, Apr 13, 2011 at 09:20:40AM +0100, Matt Zimmerman wrote: > > > I agree that preparing a delayed NMU would be appropriate in this case. > > > (Unfortunately I cannot volunteer myself for doing that ATM.) > > > > I cannot do this myself as I do not have upload privileges in Debian, and > > need help from someone who can upload packages on behalf of DEX. > > Just because I'm mean, let me strip you off of this lame excuse :-) > Everybody can *prepare* NMUs, test them, and post nmudiffs for review. > The only action which is limited to who has upload access to the Debian > archive is to actually *upload* them, including uploads to the various > DELAYED/XX queues. Very well. Let me remove all excuses of lack of time then. ;-) debdiff attached. I would appreciate both testing and upload sponsorship for it. -- - mdz
diff -u sysklogd-1.5/syslogd.c sysklogd-1.5/syslogd.c --- sysklogd-1.5/syslogd.c +++ sysklogd-1.5/syslogd.c @@ -46,6 +46,10 @@ * extensive changes by Ralph Campbell * more extensive changes by Eric Allman (again) * + * Wed Nov 24 2004 14:02:48 CET 2004: Martin Pitt + * Added option "-u <user>" to drop privileges to given user after + * initialisation. + * * Steve Lord: Fix UNIX domain socket code, added linux kernel logging * change defines to * SYSLOG_INET - listen on a UDP socket @@ -553,6 +557,9 @@ #include <paths.h> #endif +#include <pwd.h> +#include <grp.h> + #ifndef UTMP_FILE #ifdef UTMP_FILENAME #define UTMP_FILE UTMP_FILENAME @@ -878,6 +885,11 @@ extern char *optarg; int maxfds; + /* user and group id to drop to */ + uid_t uid = 0; + gid_t gid = 0; + const char* username = NULL; + #ifndef TESTING chdir ("/"); #endif @@ -886,7 +898,7 @@ funix[i] = -1; } - while ((ch = getopt(argc, argv, "a:dhf:l:m:np:rs:v")) != EOF) + while ((ch = getopt(argc, argv, "a:dhf:l:m:np:rs:vu:")) != EOF) switch((char)ch) { case 'a': if (nfunix < MAXFUNIX) @@ -934,6 +946,21 @@ case 'v': printf("syslogd %s.%s\n", VERSION, PATCHLEVEL); exit (0); + case 'u': + if (optarg) { + username = strdup (optarg); + struct passwd *pw = getpwnam (username); + if (!pw) { + fprintf (stderr, "User %s does not exist, aborting.\n", username); + exit (1); + } + uid = pw->pw_uid; + gid = pw->pw_gid; + } else { + fputs ("Internal error: -u optarg == NULL!\n", stderr); + exit (1); + } + break; case '?': default: usage(); @@ -1087,6 +1114,19 @@ kill (ppid, SIGTERM); #endif + /* + * Drop privileges if -u was specified + */ + if (username) { + if (initgroups (username, gid) || + setgid (gid) || setuid (uid)) { + perror ("Could not drop to specified user privileges"); + exit (1); + } + free (username); + username = NULL; + } + /* Main loop begins here. */ for (;;) { int nfds; @@ -1239,7 +1279,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] [-u user]\n"); exit(1); } @@ -1603,10 +1643,10 @@ int msglen; char *timestamp; #ifdef __gnu_linux__ - sigset_t mask; + sigset_t mask; #else #ifndef SYSV - sigset_t omask; + sigset_t omask; #endif #endif @@ -1618,9 +1658,9 @@ sigaddset(&mask, SIGALRM); sigprocmask(SIG_BLOCK, &mask, NULL); #else -#ifndef SYSV +# ifndef SYSV omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM)); -#endif +# endif #endif /* @@ -1660,11 +1700,11 @@ f->f_file = -1; } #ifdef __gnu_linux__ - sigprocmask(SIG_UNBLOCK, &mask, NULL); + sigprocmask(SIG_UNBLOCK, &mask, NULL); #else -#ifndef SYSV +# ifndef SYSV (void) sigsetmask(omask); -#endif +# endif #endif return; } @@ -1731,9 +1771,9 @@ #ifdef __gnu_linux__ sigprocmask(SIG_UNBLOCK, &mask, NULL); #else -#ifndef SYSV +# ifndef SYSV (void) sigsetmask(omask); -#endif +# endif #endif } #if FALSE diff -u sysklogd-1.5/debian/rules sysklogd-1.5/debian/rules --- sysklogd-1.5/debian/rules +++ sysklogd-1.5/debian/rules @@ -39,7 +39,7 @@ build: $(MAKE) DEB="-DDEBRELEASE=\\\"$(revision)\\\"" \ SKFLAGS="$(CFLAGS) -DSYSV -fomit-frame-pointer -fno-strength-reduce" \ - LDFLAGS="" + LDFLAGS="" KLOGD_DEFINES='-DPIDFILE_DIR=\"/var/run/klogd/\"' pod2man --section=8 --lax --center="Debian GNU/Linux" \ --release="Debian Project" debian/syslog-facility.pod \ > syslog-facility.8 diff -u sysklogd-1.5/debian/postinst sysklogd-1.5/debian/postinst --- sysklogd-1.5/debian/postinst +++ sysklogd-1.5/debian/postinst @@ -52,6 +52,8 @@ update-rc.d sysklogd defaults 10 90 >/dev/null + adduser --system --group --no-create-home --quiet syslog + # restarting daemon # if [ -f /etc/init.d/sysklogd ] diff -u sysklogd-1.5/debian/control sysklogd-1.5/debian/control --- sysklogd-1.5/debian/control +++ sysklogd-1.5/debian/control @@ -8,7 +8,7 @@ Package: sysklogd Architecture: any Section: admin -Depends: ${shlibs:Depends}, klogd | linux-kernel-log-daemon, lsb-base +Depends: ${shlibs:Depends}, klogd | linux-kernel-log-daemon, adduser, lsb-base Conflicts: syslogd Provides: syslogd, system-log-daemon Replaces: syslogd @@ -21,7 +21,7 @@ Package: klogd Architecture: any Section: admin -Depends: ${shlibs:Depends}, sysklogd | system-log-daemon, lsb-base +Depends: ${shlibs:Depends}, sysklogd | system-log-daemon, adduser, lsb-base Conflicts: sysklogd (<= 1.3-33) Provides: linux-kernel-log-daemon Replaces: sysklogd diff -u sysklogd-1.5/debian/postrm.klogd sysklogd-1.5/debian/postrm.klogd --- sysklogd-1.5/debian/postrm.klogd +++ sysklogd-1.5/debian/postrm.klogd @@ -4,6 +4,7 @@ if [ "$1" = "purge" ] then + deluser --system --quiet klog || true update-rc.d klogd remove >/dev/null test ! -f /lib/init/rw/sendsigs.omit.d/klogd || \ diff -u sysklogd-1.5/debian/cron.daily sysklogd-1.5/debian/cron.daily --- sysklogd-1.5/debian/cron.daily +++ sysklogd-1.5/debian/cron.daily @@ -24,6 +24,9 @@ test -x /sbin/syslogd || exit 0 test -f /usr/share/sysklogd/dummy || exit 0 +USER=$(ps -C syslogd -o user= | head -n 1) +[ -z "${USER}" ] && USER="root" || true + set -e cd /var/log @@ -35,7 +38,7 @@ for LOG in $logs do if [ -s $LOG ]; then - savelog -g adm -m 640 -u root -c 7 $LOG >/dev/null + savelog -g adm -m 640 -u ${USER} -c 7 $LOG >/dev/null fi done diff -u sysklogd-1.5/debian/rc.klogd sysklogd-1.5/debian/rc.klogd --- sysklogd-1.5/debian/rc.klogd +++ sysklogd-1.5/debian/rc.klogd @@ -12,37 +12,55 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin -pidfile=/var/run/klogd.pid +pidfile=/var/run/klogd/klogd.pid +kmsgpipe=/var/run/klogd/kmsg +kmsgpidfile=/var/run/klogd/kmsgpipe.pid binpath=/sbin/klogd test -f $binpath || exit 0 -test ! -r /etc/default/klogd || . /etc/default/klogd - . /lib/lsb/init-functions +# Use KLOGD="-k /boot/System.map-$(uname -r)" to specify System.map +# +KLOGD="-P $kmsgpipe" + +test ! -r /etc/default/klogd || . /etc/default/klogd + case "$1" in start) log_begin_msg "Starting kernel log daemon..." - start-stop-daemon --start --quiet --pidfile $pidfile --name klogd --startas $binpath -- $KLOGD + # create klog-writeable pid and fifo directory + mkdir -p /var/run/klogd + chown klog:klog /var/run/klogd + mkfifo -m 700 $kmsgpipe + chown klog:klog $kmsgpipe + + # shovel /proc/kmsg to pipe readable by klogd user + start-stop-daemon --start --pidfile $kmsgpidfile --exec /bin/dd -b -m -- bs=1 if=/proc/kmsg of=$kmsgpipe + + # start klogd as non-root with reading from kmsgpipe + start-stop-daemon --start --quiet --chuid klog --exec $binpath -- $KLOGD log_end_msg $? - test -d /lib/init/rw/sendsigs.omit.d || mkdir -p /lib/init/rw/sendsigs.omit.d - test ! -f /lib/init/rw/sendsigs.omit.d/klogd || rm -f /lib/init/rw/sendsigs.omit.d/klogd - ln -s $pidfile /lib/init/rw/sendsigs.omit.d/klogd ;; stop) log_begin_msg "Stopping kernel log daemon..." - start-stop-daemon --stop --quiet --retry 3 --exec $binpath --pidfile $pidfile + start-stop-daemon --stop --quiet --retry 3 --oknodo --exec $binpath --pidfile $pidfile + # stop kmsgpipe + start-stop-daemon --stop --quiet --oknodo --pidfile $kmsgpidfile + rm -f $kmsgpidfile $kmsgpipe log_end_msg $? ;; restart|force-reload) - log_begin_msg "Reloading kernel log daemon..." - start-stop-daemon --stop --quiet --retry 3 --exec $binpath --pidfile $pidfile - start-stop-daemon --start --quiet --pidfile $pidfile --name klogd --startas $binpath -- $KLOGD - log_end_msg $? + $0 stop + sleep 1 + $0 start + ;; + status) + status_of_proc -p $pidfile $binpath klogd && exit 0 || exit $? ;; *) - log_success_msg "Usage: /etc/init.d/klogd {start|stop|restart|force-reload}" + log_success_msg "Usage: /etc/init.d/klogd {start|stop|restart|force-reload|status}" exit 1 esac diff -u sysklogd-1.5/debian/postinst.klogd sysklogd-1.5/debian/postinst.klogd --- sysklogd-1.5/debian/postinst.klogd +++ sysklogd-1.5/debian/postinst.klogd @@ -25,6 +25,8 @@ update-rc.d klogd defaults 11 89 >/dev/null + adduser --system --quiet --group --no-create-home klog || true + # restarting daemon # if [ -f /etc/init.d/klogd ] diff -u sysklogd-1.5/debian/changelog sysklogd-1.5/debian/changelog --- sysklogd-1.5/debian/changelog +++ sysklogd-1.5/debian/changelog @@ -1,3 +1,20 @@ +sysklogd (1.5-6.1) unstable; urgency=low + + * Non-maintainer upload. + * Merge Ubuntu patch to enable klogd and syslogd to run as non-root users + (Closes: Bug#35325) + - debian/control: add dependency on adduser + - debian/postrm.klogd, postinst.klogd: handle addition/removal of klogd + user + - debian/rc.klogd, default.klogd: run klogd as user klogd + - klogd.c, debian/rules, Makefile, klogd.8: specify location of klogd pid + file + + - syslogd.c, syslogd.8: add -u <user> option + - debian/cron.daily, cron.weekly, rc: run syslogd as user syslogd + + -- Matt Zimmerman <mdz@debian.org> Thu, 14 Apr 2011 06:52:27 -0400 + sysklogd (1.5-6) unstable; urgency=low * Remove faulty fclose() call. Thanks to Andrea Morandi and Sean Young diff -u sysklogd-1.5/debian/cron.weekly sysklogd-1.5/debian/cron.weekly --- sysklogd-1.5/debian/cron.weekly +++ sysklogd-1.5/debian/cron.weekly @@ -25,6 +25,9 @@ set -e +USER=$(ps -C syslogd -o user= | head -n 1) +[ -z "${USER}" ] && USER="root" || true + cd /var/log logs=$(syslogd-listfiles --weekly) @@ -34,7 +37,7 @@ for LOG in $logs do if [ -s $LOG ]; then - savelog -g adm -m 640 -u root -c 4 $LOG >/dev/null + savelog -g adm -m 640 -u ${USER} -c 4 $LOG >/dev/null fi done diff -u sysklogd-1.5/debian/rc sysklogd-1.5/debian/rc --- sysklogd-1.5/debian/rc +++ sysklogd-1.5/debian/rc @@ -19,8 +19,31 @@ test -x $binpath || exit 0 +# syslogd options should be set in /etc/default/syslogd +SYSLOGD="" + +# user to run syslogd as - this can overriden in /etc/default/syslogd +USER="syslog" + test ! -r /etc/default/syslogd || . /etc/default/syslogd +# Figure out under which user syslogd should be running as +if echo ${SYSLOGD} | grep -q '^.*-u[[:space:]]*\([[:alnum:]]*\)[[:space:]]*.*$' +then + # A specific user has been set on the command line, try to extract it. + USER=$(echo ${SYSLOGD} | sed -e 's/^.*-u[[:space:]]*\([[:alnum:]]*\)[[:space:]]*.*$/\1/') +else + # By default, run syslogd under the syslog user + SYSLOGD="${SYSLOGD} -u ${USER}" +fi + +# Unable to get the user under which syslogd should be running, stop. +if [ -z "${USER}" ] +then + log_failure_msg "Unable to get syslog user" + exit 1 +fi + . /lib/lsb/init-functions create_xconsole() @@ -36,8 +59,18 @@ else chmod 0640 /dev/xconsole fi - chown root:adm /dev/xconsole + + chown ${USER}:adm /dev/xconsole test ! -x /sbin/restorecon || /sbin/restorecon /dev/xconsole + +} + +fix_log_ownership() +{ + for l in `syslogd-listfiles -a` + do + chown ${USER}:adm $l + done } running() @@ -79,6 +112,7 @@ start) log_begin_msg "Starting system log daemon..." create_xconsole + fix_log_ownership start-stop-daemon --start --quiet --pidfile $pidfile --name syslogd --startas $binpath -- $SYSLOGD log_end_msg $? test -d /lib/init/rw/sendsigs.omit.d || mkdir -p /lib/init/rw/sendsigs.omit.d @@ -92,12 +126,14 @@ ;; reload|force-reload) log_begin_msg "Reloading system log daemon..." + fix_log_ownership start-stop-daemon --stop --quiet --signal 1 --pidfile $pidfile --name syslogd log_end_msg $? ;; restart) log_begin_msg "Restarting system log daemon..." start-stop-daemon --stop --retry 5 --quiet --pidfile $pidfile --name syslogd + fix_log_ownership start-stop-daemon --start --quiet --pidfile $pidfile --name syslogd --startas $binpath -- $SYSLOGD log_end_msg $? ;; diff -u sysklogd-1.5/debian/default.klogd sysklogd-1.5/debian/default.klogd --- sysklogd-1.5/debian/default.klogd +++ sysklogd-1.5/debian/default.klogd @@ -15 +15 @@ -KLOGD="-x" +#KLOGD="-P /var/run/klogd/kmsg -x" only in patch2: unchanged: --- sysklogd-1.5.orig/Makefile +++ sysklogd-1.5/Makefile @@ -70,7 +70,7 @@ SYSLOGD_FLAGS= -DSYSLOG_INET -DSYSLOG_UNIXAF -DNO_SCCS ${FSSTND} \ ${SYSLOGD_PIDNAME} SYSLOG_FLAGS= -DALLOW_KERNEL_LOGGING -KLOGD_FLAGS = ${FSSTND} ${KLOGD_START_DELAY} +KLOGD_FLAGS = ${FSSTND} ${KLOGD_START_DELAY} ${KLOGD_DEFINES} DEB = all: syslogd klogd @@ -102,7 +102,7 @@ ${CC} ${SKFLAGS} ${SYSLOG_FLAGS} -c syslog.c klogd.o: klogd.c klogd.h version.h - ${CC} ${SKFLAGS} ${KLOGD_FLAGS} $(DEB) -c klogd.c + ${CC} -U_FORTIFY_SOURCE ${SKFLAGS} ${KLOGD_FLAGS} $(DEB) -c klogd.c ksym.o: ksym.c klogd.h ksyms.h module.h ${CC} ${SKFLAGS} ${KLOGD_FLAGS} -c ksym.c only in patch2: unchanged: --- sysklogd-1.5.orig/klogd.8 +++ sysklogd-1.5/klogd.8 @@ -18,6 +18,9 @@ .RB [ " \-n " ] .RB [ " \-o " ] .RB [ " \-p " ] +.RB [ " \-P " +.I path +] .RB [ " \-s " ] .RB [ " \-k " .I fname @@ -64,6 +67,11 @@ symbol information whenever an Oops string is detected in the kernel message stream. .TP +.B "\-P " path +Use \fIpath\fR instead of /proc/kmsg as the source of the kernel message. +Specify "-" to read from standard input. This allows klogd to run entirely +without root privileges. +.TP .B "\-s" Force \fBklogd\fP to use the system call interface to the kernel message buffers. @@ -94,10 +102,15 @@ .I /proc file system and the syscall (sys_syslog) interface, although ultimately they are one and the same. Klogd is designed to choose -whichever source of information is the most appropriate. It does this -by first checking for the presence of a mounted +whichever source of information is the most appropriate. If the +.B \-P +switch is used, +.B klogd +opens the specified path as the source of kernel log information. Otherwise +.B klogd +checks for the presence of a mounted .I /proc -file system. If this is found the +file system and if this is found the .I /proc/kmsg file is used as the source of kernel log information. If the proc file system is not mounted only in patch2: unchanged: --- sysklogd-1.5.orig/sysklogd.8 +++ sysklogd-1.5/sysklogd.8 @@ -29,6 +29,9 @@ .RB [ " \-s " .I domainlist ] +.RB [ " \-u" +.IB user +] .RB [ " \-v " ] .SH DESCRIPTION .B Sysklogd @@ -150,6 +153,26 @@ no domain would be cut, you will have to specify two domains like: .BR "\-s north.de:infodrom.north.de" . .TP +.BI "\-u" " user" +The +.B syslogd +daemon runs with full root privileges by default. If you specify this +option, the daemon will drop its privileges to the given user (and the +primary group of this user) before starting up logging. This +greatly reduces the potential impact of exploitable security holes in +syslogd. + +.B syslogd +will still open all log files as root at startup. +However, after receiving a +.B SIGHUP +signal (which causes the daemon to restart) the log files will be +reopened as the non-privileged user which fails if the log files are +only writeable by root. If you need to restart the daemon using the +signal, then you have to adapt the permissions of your log files to be +writeable by the specified user (or its primary group). + +.TP .B "\-v" Print version and exit. .SH SIGNALS only in patch2: unchanged: --- sysklogd-1.5.orig/klogd.c +++ sysklogd-1.5/klogd.c @@ -20,6 +20,13 @@ */ /* + * Thu Nov 25 16:48:39 CET 2004: Martin Pitt + * Added option -P to give alternative location of /proc/kmsg ("-" for + * stdin). This allows to run klogd entirely without root privileges. + * + * Added support for macro PIDFILE_DIR which is used as pid file directory + * instead of _PATH_VARRUN. + * * Steve Lord (lord@cray.com) 7th Nov 92 * * Modified to check for kernel info by Dr. G.W. Wettstein 02/17/93. @@ -289,7 +296,9 @@ #define LOG_LINE_LENGTH 1000 #ifndef TESTING -#if defined(FSSTND) +#if defined(PIDFILE_DIR) +static char *PidFile = PIDFILE_DIR "klogd.pid"; +#elif defined(FSSTND) static char *PidFile = _PATH_VARRUN "klogd.pid"; #else static char *PidFile = "/etc/klogd.pid"; @@ -313,6 +322,8 @@ 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; @@ -543,6 +554,22 @@ "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. @@ -990,7 +1017,7 @@ chdir ("/"); #endif /* Parse the command-line. */ - while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2")) != EOF) + while ((ch = getopt(argc, argv, "c:df:iIk:nopP:svx2")) != EOF) switch((char)ch) { case '2': /* Print lines with symbols twice. */ @@ -1024,6 +1051,9 @@ 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; @@ -1035,7 +1065,6 @@ break; } - /* Set console logging level. */ if ( log_level != (char *) 0 ) {
Attachment:
signature.asc
Description: Digital signature