# DIY Linux Patch
Date: 2005-07-05
Author: Refer Description
Origin: Debian diff sysklogd_1.4.1-17.diff.gz
Maker: Greg Schafer <gschafer@zip.com.au>
Upstream Status: Refer Description
Description: Fix compilation against 2.6 headers, fix security issues, fix NPTL
  related hang. The upstream maintainer is a senior Debian developer and also
  the Debian packager thus making this a defacto upstream release.

diff -Naur sysklogd-1.4.1.orig/CHANGES sysklogd-1.4.1/CHANGES
--- sysklogd-1.4.1.orig/CHANGES	2001-03-11 19:35:51.000000000 +0000
+++ sysklogd-1.4.1/CHANGES	2005-07-05 01:28:15.000000000 +0000
@@ -30,3 +30,4 @@
  . Olaf Kirch <okir@caldera.de>
    - Remove Unix Domain Sockets and switch to Datagram Unix Sockets
  . Several bugfixes and improvements, please refer to the .c files
+
diff -Naur sysklogd-1.4.1.orig/README.linux sysklogd-1.4.1/README.linux
--- sysklogd-1.4.1.orig/README.linux	1999-01-19 00:09:12.000000000 +0000
+++ sysklogd-1.4.1/README.linux	2005-07-05 01:28:15.000000000 +0000
@@ -44,8 +44,8 @@
 mail to Majordomo@Infodrom.North.DE with a line "subscribe sysklogd"
 in the message body.
 
-New versions of this package will be available at Joey's ftp server.
-ftp://ftp.infodrom.north.de/pub/people/joey/sysklogd/
+New versions of this package will be available at Joey's server.
+  http://www.infodrom.org/projects/sysklogd/
 
 Best regards,
 
@@ -67,6 +67,6 @@
 
 Martin Schulze
 Infodrom Oldenburg
-joey@linux.de
+joey@infodrom.org
 
 And a host of bug reporters whose contributions cannot be underestimated.
diff -Naur sysklogd-1.4.1.orig/klogd.8 sysklogd-1.4.1/klogd.8
--- sysklogd-1.4.1.orig/klogd.8	2001-03-11 19:35:51.000000000 +0000
+++ sysklogd-1.4.1/klogd.8	2005-07-05 01:28:15.000000000 +0000
@@ -321,7 +321,7 @@
 .B klogd
 to reload the module symbol information whenever a protection fault
 is detected.  Caution should be used before invoking the program in
-\'paranoid\' mode.  The stability of the kernel and the operating
+\&'paranoid\&' mode.  The stability of the kernel and the operating
 environment is always under question when a protection fault occurs.
 Since the klogd daemon must execute system calls in order to read the
 module symbol information there is the possibility that the system may
diff -Naur sysklogd-1.4.1.orig/ksym_mod.c sysklogd-1.4.1/ksym_mod.c
--- sysklogd-1.4.1.orig/ksym_mod.c	2000-09-12 21:15:28.000000000 +0000
+++ sysklogd-1.4.1/ksym_mod.c	2005-07-05 01:28:15.000000000 +0000
@@ -78,6 +78,11 @@
  *
  * Tue Sep 12 23:11:13 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
  *	Changed llseek() to lseek64() in order to skip a libc warning.
+ *
+ * Wed Mar 31 17:35:01 CEST 2004: Martin Schulze <joey@infodrom.org>
+ *	Removed references to <linux/module.h> since it doesn't work
+ *	anymore with its recent content from Linux 2.4/2.6, created
+ *	module.h locally instead.
  */
 
 
@@ -89,11 +94,12 @@
 #include <errno.h>
 #include <sys/fcntl.h>
 #include <sys/stat.h>
+#include "module.h"
 #if !defined(__GLIBC__)
 #include <linux/time.h>
-#include <linux/module.h>
+#include <linux/linkage.h>
 #else /* __GLIBC__ */
-#include <linux/module.h>
+#include <linux/linkage.h>
 extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
 extern int get_kernel_syms __P ((struct kernel_sym *__table));
 #endif /* __GLIBC__ */
diff -Naur sysklogd-1.4.1.orig/module.h sysklogd-1.4.1/module.h
--- sysklogd-1.4.1.orig/module.h	1970-01-01 00:00:00.000000000 +0000
+++ sysklogd-1.4.1/module.h	2005-07-05 01:28:15.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+    module.h - Miscellaneous module definitions
+    Copyright (c) 1996 Richard Henderson <rth@tamu.edu>
+    Copyright (c) 2004 Martin Schulze <joey@infodrom.org>
+
+    This file is part of the sysklogd package.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* ChangeLog:
+ *
+ * Wed Mar 31 17:35:01 CEST 2004: Martin Schulze <joey@infodrom.org>
+ *	Created local copy of module.h based on the content of Linux
+ *	2.2 since <linux/module.h> doesn't work anymore with its
+ *	recent content from Linux 2.4/2.6.
+ */
+
+#include <asm/atomic.h>
+
+#define MODULE_NAME_LEN 60
+
+struct kernel_sym
+{
+	unsigned long value;
+	char name[MODULE_NAME_LEN];
+};
+
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+
+struct module_info
+{
+	unsigned long addr;
+	unsigned long size;
+	unsigned long flags;
+	long usecount;
+};
+
+
+struct module
+{
+	unsigned long size_of_struct;	/* == sizeof(module) */
+	struct module *next;
+	const char *name;
+	unsigned long size;
+
+	union
+	{
+		int usecount;
+		long pad;
+	} uc;				/* Needs to keep its size - so says rth */
+
+	unsigned long flags;		/* AUTOCLEAN et al */
+
+	unsigned nsyms;
+	unsigned ndeps;
+
+	struct module_symbol *syms;
+	struct module_ref *deps;
+	struct module_ref *refs;
+	int (*init)(void);
+	void (*cleanup)(void);
+	const struct exception_table_entry *ex_table_start;
+	const struct exception_table_entry *ex_table_end;
+#ifdef __alpha__
+	unsigned long gp;
+#endif
+	/* Members past this point are extensions to the basic
+	   module support and are optional.  Use mod_opt_member()
+	   to examine them.  */
+	const struct module_persist *persist_start;
+	const struct module_persist *persist_end;
+	int (*can_unload)(void);
+};
diff -Naur sysklogd-1.4.1.orig/pidfile.c sysklogd-1.4.1/pidfile.c
--- sysklogd-1.4.1.orig/pidfile.c	1998-02-10 22:37:12.000000000 +0000
+++ sysklogd-1.4.1/pidfile.c	2005-07-05 01:28:15.000000000 +0000
@@ -87,7 +87,7 @@
   int fd;
   int pid;
 
-  if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
+  if ( ((fd = open(pidfile, O_RDWR|O_CREAT|O_TRUNC, 0644)) == -1)
        || ((f = fdopen(fd, "r+")) == NULL) ) {
       fprintf(stderr, "Can't open or create %s.\n", pidfile);
       return 0;
diff -Naur sysklogd-1.4.1.orig/syslog.conf.5 sysklogd-1.4.1/syslog.conf.5
--- sysklogd-1.4.1.orig/syslog.conf.5	1999-08-21 10:49:14.000000000 +0000
+++ sysklogd-1.4.1/syslog.conf.5	2005-07-05 01:28:15.000000000 +0000
@@ -64,7 +64,7 @@
 The
 .I facility
 is one of the following keywords:
-.BR auth ", " authpriv ", " cron ", " daemon ", " kern ", " lpr ", "
+.BR auth ", " authpriv ", " cron ", " daemon ", " ftp ", " kern ", " lpr ", "
 .BR mail ", " mark ", " news ", " security " (same as " auth "), "
 .BR syslog ", " user ", " uucp " and " local0 " through " local7 .
 The keyword 
@@ -300,7 +300,7 @@
 .B syslogd
 log all messages that come with either the
 .BR info " or the " notice
-facility into the file
+priority into the file
 .IR /var/log/messages ,
 except for all messages that use the
 .B mail
diff -Naur sysklogd-1.4.1.orig/syslogd.c sysklogd-1.4.1/syslogd.c
--- sysklogd-1.4.1.orig/syslogd.c	2001-03-11 19:40:10.000000000 +0000
+++ sysklogd-1.4.1/syslogd.c	2005-07-05 01:28:15.000000000 +0000
@@ -890,11 +890,11 @@
 		dprintf("Checking pidfile.\n");
 		if (!check_pid(PidFile))
 		{
+			signal (SIGTERM, doexit);
 			if (fork()) {
 				/*
 				 * Parent process
 				 */
-				signal (SIGTERM, doexit);
 				sleep(300);
 				/*
 				 * Not reached unless something major went wrong.  5
@@ -1141,13 +1141,13 @@
 				 */
 				printchopped(from, line, \
  					     i + 2,  finet);
-			} else if (i < 0 && errno != EINTR) {
+			} else if (i < 0 && errno != EINTR && errno != EAGAIN) {
 				dprintf("INET socket error: %d = %s.\n", \
 					errno, strerror(errno));
 				logerror("recvfrom inet");
 				/* should be harmless now that we set
 				 * BSDCOMPAT on the socket */
-				sleep(10);
+				sleep(1);
 			}
 		}
 #endif
@@ -1216,6 +1216,7 @@
 {
 	int fd, on = 1;
 	struct sockaddr_in sin;
+	int sockflags;
 
 	fd = socket(AF_INET, SOCK_DGRAM, 0);
 	if (fd < 0) {
@@ -1241,6 +1242,24 @@
 		close(fd);
 		return -1;
 	}
+	/* We must not block on the network socket, in case a packet
+	 * gets lost between select and recv, otherise the process
+	 * will stall until the timeout, and other processes trying to
+	 * log will also stall.
+	 */
+	if ((sockflags = fcntl(fd, F_GETFL)) != -1) {
+		sockflags |= O_NONBLOCK;
+		/*
+		 * SETFL could fail too, so get it caught by the subsequent
+		 * error check.
+		 */
+		sockflags = fcntl(fd, F_SETFL, sockflags);
+	}
+	if (sockflags == -1) {
+		logerror("fcntl(O_NONBLOCK), suspending inet");
+		close(fd);
+		return -1;
+	}
 	if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
 		logerror("bind, suspending inet");
 		close(fd);
@@ -1275,7 +1294,7 @@
 	for (count=i=0; p[i]; i++)
 		if (p[i] == LIST_DELIMITER) count++;
 	
-	if ((result = (char **)malloc(sizeof(char *) * count+2)) == NULL) {
+	if ((result = (char **)malloc(sizeof(char *) * (count+2))) == NULL) {
 		printf ("Sorry, can't get enough memory, exiting.\n");
 		exit(0);
 	}
@@ -1539,20 +1558,37 @@
 	int fac, prilev, lognum;
 	int msglen;
 	char *timestamp;
+#ifdef __gnu_linux__
+	sigset_t mask;
+#else
+#ifndef SYSV
+	sigset_t omask;
+#endif
+#endif
 
 	dprintf("logmsg: %s, flags %x, from %s, msg %s\n", textpri(pri), flags, from, msg);
 
+#ifdef __gnu_linux__
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGHUP);
+	sigaddset(&mask, SIGALRM);
+	sigprocmask(SIG_BLOCK, &mask, NULL);
+#else
 #ifndef SYSV
 	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
 #endif
+#endif
 
 	/*
 	 * Check to see if msg looks non-standard.
 	 */
 	msglen = strlen(msg);
-	if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
-	    msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
-		flags |= ADDDATE;
+	flags |= ADDDATE;
+	if ( !(msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
+	    msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')) {
+		msg += 16;
+		msglen -= 16;
+	}
 
 	(void) time(&now);
 	if (flags & ADDDATE)
@@ -1581,9 +1617,13 @@
 			(void) close(f->f_file);
 			f->f_file = -1;
 		}
+#ifdef __gnu_linux__
+		sigprocmask(SIG_UNBLOCK, &mask, NULL);
+#else
 #ifndef SYSV
 		(void) sigsetmask(omask);
 #endif
+#endif
 		return;
 	}
 #ifdef SYSV
@@ -1646,9 +1686,13 @@
 			}
 		}
 	}
+#ifdef __gnu_linux__
+	sigprocmask(SIG_UNBLOCK, &mask, NULL);
+#else
 #ifndef SYSV
 	(void) sigsetmask(omask);
 #endif
+#endif
 }
 #if FALSE
 } /* balance parentheses for emacs */
@@ -1839,7 +1883,7 @@
 #else
 				&& e == EBADF) {
 #endif
-				f->f_file = open(f->f_un.f_fname, O_WRONLY|O_APPEND|O_NOCTTY);
+				f->f_file = open(f->f_un.f_fname, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
 				if (f->f_file < 0) {
 					f->f_type = F_UNUSED;
 					logerror(f->f_un.f_fname);
@@ -2640,7 +2684,7 @@
 			f->f_file = open(++p, O_RDWR|O_NONBLOCK);
 			f->f_type = F_PIPE;
 	        } else {
-			f->f_file = open(p, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
+			f->f_file = open(p, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_NONBLOCK,
 					 0644);
 			f->f_type = F_FILE;
 		}
