Index: CHANGES =================================================================== RCS file: /var/cvs/infodrom/sysklogd/CHANGES,v retrieving revision 1.9 retrieving revision 1.15 diff -u -p -a -r1.9 -r1.15 --- CHANGES 11 Mar 2001 19:35:51 -0000 1.9 +++ CHANGES 15 Jan 2005 19:14:21 -0000 1.15 @@ -1,3 +1,42 @@ +Version 1.4.2 + + . Dmitry V. Levin + - Close file descriptor in FindSymbolFile() in ksym.c in order not to + leak file descriptors. + . Solar Designer + - improve crunch_list() + - Prevent potential buffer overflow in reading messages from the + kernel log ringbuffer. + - Ensure that "len" is not placed in a register, and that the + endtty() signal handler is not installed too early which could + cause a segmentation fault or worse. + . Steve Grubb + - fix memory calculation in crunch_list() + . Martin Schulze + - klogd will reconnect to the logger (mostly syslogd) after it went + away + - On heavily loaded system syslog will not spit out error messages + anymore when recvfrom() results in EAGAIN + - Makefile improvements + - Local copy of module.h + - Improved sysklogd.8 + - Always log with syslogd's timezone and locale + - Remove trailing newline when forwarding messages + . Jon Burgess + - Moved the installation of the signal handler up a little bit so it + guaranteed to be available when the child is forked, hence, fixing a + race condition. This used to create problems with UML and fast + machines. + . Greg Trounson + - Improved README.linux + . Ulf Härnhammar + - Bondary check for fscanf() in InitKsyms() and CheckMapVersion() + . Colin Phipps + - Don't block on the network socket in case of package los + . Dirk Mueller + - Don't crash when filesize limit is reached (e.g. without LFS) + + Version 1.4.1 . klogd will set the console log level only if `-c' is given on the @@ -30,3 +69,9 @@ Version 1.4 . Olaf Kirch - Remove Unix Domain Sockets and switch to Datagram Unix Sockets . Several bugfixes and improvements, please refer to the .c files + + +Local variables: +mode: indented-text +fill-column: 72 +End: Index: Makefile =================================================================== RCS file: /var/cvs/infodrom/sysklogd/Makefile,v retrieving revision 1.7 retrieving revision 1.10 diff -u -p -a -r1.7 -r1.10 --- Makefile 12 Oct 1998 20:25:15 -0000 1.7 +++ Makefile 25 May 2006 07:12:44 -0000 1.10 @@ -4,12 +4,17 @@ CC= gcc #CFLAGS= -g -DSYSV -Wall #LDFLAGS= -g CFLAGS= $(RPM_OPT_FLAGS) -O3 -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce +# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE +# $(shell getconf LFS_CFLAGS) LDFLAGS= -s # Look where your install program is. INSTALL = /usr/bin/install -BINDIR = /usr/sbin -MANDIR = /usr/man + +# Destination paths, set prefix=/opt if required +BINDIR = $(prefix)/usr/sbin +MANDIR = $(prefix)/usr/share/man # There is one report that under an all ELF system there may be a need to # explicilty link with libresolv.a. If linking syslogd fails you may wish @@ -34,8 +39,9 @@ FSSTND = -DFSSTND # The following define establishes ownership for the man pages. # Avery tells me that there is a difference between Debian and # Slackware. Rather than choose sides I am leaving it up to the user. -MAN_OWNER = root -# MAN_OWNER = man +MAN_USER = root +MAN_GROUP = root +MAN_PERMS = 644 # The following define establishes the name of the pid file for the # syslogd daemon. The library include file (paths.h) defines the @@ -116,7 +122,7 @@ install_exec: syslogd klogd ${INSTALL} -m 500 -s klogd ${BINDIR}/klogd install_man: - ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 sysklogd.8 ${MANDIR}/man8/sysklogd.8 - ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslogd.8 ${MANDIR}/man8/syslogd.8 - ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslog.conf.5 ${MANDIR}/man5/syslog.conf.5 - ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 klogd.8 ${MANDIR}/man8/klogd.8 + ${INSTALL} -o ${MAN_USER} -g ${MAN_GROUP} -m ${MAN_PERMS} sysklogd.8 ${MANDIR}/man8/sysklogd.8 + ${INSTALL} -o ${MAN_USER} -g ${MAN_GROUP} -m ${MAN_PERMS} syslogd.8 ${MANDIR}/man8/syslogd.8 + ${INSTALL} -o ${MAN_USER} -g ${MAN_GROUP} -m ${MAN_PERMS} syslog.conf.5 ${MANDIR}/man5/syslog.conf.5 + ${INSTALL} -o ${MAN_USER} -g ${MAN_GROUP} -m ${MAN_PERMS} klogd.8 ${MANDIR}/man8/klogd.8 Index: README.1st =================================================================== RCS file: /var/cvs/infodrom/sysklogd/README.1st,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -p -a -r1.1.1.1 -r1.3 --- README.1st 2 Jun 1997 17:21:39 -0000 1.1.1.1 +++ README.1st 25 May 2006 08:11:49 -0000 1.3 @@ -1,5 +1,5 @@ -Very important information before using version 1.3 ---------------------------------------------------- +Important information +--------------------- The included version of syslogd behaves in a slightly different manner to the one in former releases. Please review the following important @@ -63,3 +63,33 @@ differences: these scripts should remove all old .pid files found in /var/run. This will insure that klogd and syslogd start properly even if prior executions have been terminated harshly. + +* Large file support, i.e. support to write to log files that are + larger than 2 GB is not part of syslogd, but a matter of the glibc + emitting different system calls to the kernel interface. To support + large files you'll have to compile syslogd with the compiler defines + commented out in the main Makefile so that glibc adjusts the system + calls. + +Modifying the kernel console log level +-------------------------------------- + + There are two ways to alter the kernel console log level. This + setting controls whether log messages from the kernel should appear + on the system console or not. + + In the past, klogd had to do this with the -c parameter. Using '-c + 4' will set the log level of console messages to 4 and only display + warnings and errors but not regular debug or information messages. + + This behaviour is deprecated and hencely not enforced anymore via + the RC script of klogd. Instead sysctl(8) should be used as + interface to various kernel variables. These can be stored + non-volatile in /etc/sysctl.conf. + + The prevent the kernel to flood the system console and to achieve + the same behaviour of '-c 4' simply add the following to the + configuration file and let sysctl set this kernel parameter upon + system boot. + + kernel/printk = 4 4 1 7 Index: README.linux =================================================================== RCS file: /var/cvs/infodrom/sysklogd/README.linux,v retrieving revision 1.5 retrieving revision 1.7 diff -u -p -a -r1.5 -r1.7 --- README.linux 19 Jan 1999 00:09:12 -0000 1.5 +++ README.linux 9 Jul 2004 17:22:29 -0000 1.7 @@ -40,12 +40,17 @@ sources. Hopefully the Linux community a useful addition to the software gene pool. There is a mailing list covering this package and syslog in general. -The lists address is sysklogd@Infodrom.North.DE . To subscribe send a -mail to Majordomo@Infodrom.North.DE with a line "subscribe sysklogd" +The lists address is infodrom-sysklogd@lists.infodrom.org . To subscribe send a +mail to majordomo@lists.infodrom.org with a line "subscribe infodrom-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/ +A second mailing list exists as infodrom-sysklogd-cvs@lists.infodrom.org. Only +CVS messages and diffs are distributed there. Whenever new code is added to +sysklogd, CVS generates a mail from these changes which will be sent to +this list. Discussions will take place on the first list. + +The latest version of this software can be found at: +http://www.infodrom.org/projects/sysklogd/download.php3 Best regards, @@ -67,6 +72,6 @@ shane@ion.apana.org.au Martin Schulze Infodrom Oldenburg -joey@linux.de +joey@infodrom.org -And a host of bug reporters whose contributions cannot be underestimated. +And a number of bug reporters whose contributions cannot be underestimated. Index: klogd.8 =================================================================== RCS file: /var/cvs/infodrom/sysklogd/klogd.8,v retrieving revision 1.8 retrieving revision 1.11 diff -u -p -a -r1.8 -r1.11 --- klogd.8 11 Mar 2001 19:35:51 -0000 1.8 +++ klogd.8 11 Mar 2005 16:12:09 -0000 1.11 @@ -3,8 +3,9 @@ .\" Sun Jul 30 01:35:55 MET: Martin Schulze: Updates .\" Sun Nov 19 23:22:21 MET: Martin Schulze: Updates .\" Mon Aug 19 09:42:08 CDT 1996: Dr. G.W. Wettstein: Updates +.\" Fri Mar 11 17:11:46 CET 2005: Martin Schulze: sysctl updates .\" -.TH KLOGD 8 "21 August, 1999" "Version 1.4" "Linux System Administration" +.TH KLOGD 8 "11 March 2005" "Version 1.4" "Linux System Administration" .SH NAME klogd \- Kernel Log Daemon .LP @@ -38,6 +39,12 @@ messages. .TP .BI "\-c " n Sets the default log level of console messages to \fIn\fR. +This should nowardays be configured with the +.BR sysctl (8) +program, e.g. via +.BI "sysctl kernel.printk=" n +or via +.IR /etc/sysctl.conf . .TP .B "\-d" Enable debugging mode. This will generate \fBLOTS\fR of output to @@ -321,7 +328,7 @@ to date. This switch instructs .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 Index: klogd.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/klogd.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -p -a -r1.21 -r1.22 --- klogd.c 11 Mar 2001 19:40:10 -0000 1.21 +++ klogd.c 29 Apr 2004 13:29:03 -0000 1.22 @@ -243,6 +243,9 @@ * people have submitted patches: Troels Walsted Hansen * , Wolfgang Oertl * and Thomas Roessler. + * Thu Apr 29 15:24:07 2004: Solar Designer + * Prevent potential buffer overflow in reading messages from the + * kernel log rinbuffer. */ @@ -938,7 +941,7 @@ static void LogKernelLine(void) * messages into this fresh buffer. */ memset(log_buffer, '\0', sizeof(log_buffer)); - if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer))) < 0 ) + if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer)-1)) < 0 ) { if ( errno == EINTR ) return; Index: ksym.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/ksym.c,v retrieving revision 1.12 retrieving revision 1.14 diff -u -p -a -r1.12 -r1.14 --- ksym.c 12 Sep 2000 21:53:31 -0000 1.12 +++ ksym.c 16 Jul 2004 06:48:27 -0000 1.14 @@ -105,6 +105,15 @@ * * Tue Sep 12 23:48:12 CEST 2000: Martin Schulze * Close symbol file in InitKsyms() when an error occurred. + * + * Thu Apr 29 18:07:16 CEST 2004: Dmitry Levin + * Close file descriptor in FindSymbolFile() in order not to leak + * file descriptors. + * + * Fri Jul 16 08:32:49 CEST 2004: Ulf Härnhammar + * Added boundary check for fscanf() in InitKsyms() and + * CheckMapVersion() to prevent an unintended crash when reading + * an incorrect System.map. */ @@ -236,7 +245,7 @@ extern int InitKsyms(mapfile) */ while ( !feof(sym_file) ) { - if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym) + if ( fscanf(sym_file, "%lx %c %511s\n", &address, &type, sym) != 3 ) { Syslog(LOG_ERR, "Error in symbol table input (#1)."); @@ -344,6 +353,7 @@ static char * FindSymbolFile() if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) { if (CheckMapVersion(symfile) == 1) file = symfile; + fclose (sym_file); } if (sym_file == (FILE *) 0 || file == (char *) 0) { sprintf (symfile, "%s", *mf); @@ -352,6 +362,7 @@ static char * FindSymbolFile() if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) { if (CheckMapVersion(symfile) == 1) file = symfile; + fclose (sym_file); } } @@ -533,7 +544,7 @@ static int CheckMapVersion(fname) version = 0; while ( !feof(sym_file) && (version == 0) ) { - if ( fscanf(sym_file, "%lx %c %s\n", &address, \ + if ( fscanf(sym_file, "%lx %c %511s\n", &address, \ &type, sym) != 3 ) { Syslog(LOG_ERR, "Error in symbol table input (#2)."); @@ -899,3 +910,11 @@ extern void Syslog(int priority, char *f return; } #endif + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ Index: ksym_mod.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/ksym_mod.c,v retrieving revision 1.10 retrieving revision 1.12 diff -u -p -a -r1.10 -r1.12 --- ksym_mod.c 12 Sep 2000 21:15:28 -0000 1.10 +++ ksym_mod.c 31 Mar 2004 15:47:08 -0000 1.12 @@ -78,6 +78,11 @@ * * Tue Sep 12 23:11:13 CEST 2000: Martin Schulze * Changed llseek() to lseek64() in order to skip a libc warning. + * + * Wed Mar 31 17:35:01 CEST 2004: Martin Schulze + * Removed references to 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 #include #include +#include "module.h" #if !defined(__GLIBC__) #include -#include +#include #else /* __GLIBC__ */ -#include +#include extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); extern int get_kernel_syms __P ((struct kernel_sym *__table)); #endif /* __GLIBC__ */ @@ -107,7 +113,7 @@ extern int get_kernel_syms __P ((struct #if !defined(__GLIBC__) /* - * The following bit uses some kernel/library magic to product what + * The following bit uses some kernel/library magic to produce what * looks like a function call to user level code. This function is * actually a system call in disguise. The purpose of the getsyms * call is to return a current copy of the in-kernel symbol table. Index: module.h =================================================================== RCS file: module.h diff -N module.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ module.h 25 May 2006 07:15:57 -0000 1.4 @@ -0,0 +1,90 @@ +/* + module.h - Miscellaneous module definitions + Copyright (c) 1996 Richard Henderson + Copyright (c) 2004 Martin Schulze + + 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 + * Created local copy of module.h based on the content of Linux + * 2.2 since doesn't work anymore with its + * recent content from Linux 2.4/2.6. + * Thu May 25 09:14:33 CEST 2006: Martin Schulze + * Removed asm/atomic.h since it is not needed anymore. + */ + +#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); +}; Index: pidfile.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/pidfile.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -a -r1.2 -r1.3 --- pidfile.c 10 Feb 1998 22:37:12 -0000 1.2 +++ pidfile.c 28 Sep 2003 02:38:18 -0000 1.3 @@ -87,7 +87,7 @@ int write_pid (char *pidfile) 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; Index: sysklogd.8 =================================================================== RCS file: /var/cvs/infodrom/sysklogd/sysklogd.8,v retrieving revision 1.10 retrieving revision 1.13 diff -u -p -a -r1.10 -r1.13 --- sysklogd.8 11 Mar 2001 19:35:51 -0000 1.10 +++ sysklogd.8 9 Jul 2004 17:33:32 -0000 1.13 @@ -84,7 +84,7 @@ the symbol .B MAXFUNIX within the syslogd.c source file. An example for a chroot() daemon is described by the people from OpenBSD at -http://www.psionic.com/papers/dns.html. +. .TP .B "\-d" Turns on debug mode. Using this the daemon will not proceed a @@ -117,7 +117,8 @@ logs a mark timestamp regularly. The de between two \fI-- MARK --\fR lines is 20 minutes. This can be changed with this option. Setting the .I interval -to zero turns it off entirely. +to zero turns it off entirely. Depending on other log messages +generated these lines may not be written consecutively. .TP .B "\-n" Avoid auto-backgrounding. This is needed especially if the @@ -364,8 +365,10 @@ with the same single message. :-( To avoid this in further times no messages that were received from a remote host are sent out to another (or the same) remote host -anymore. If there are scenarios where this doesn't make sense, please -drop me (Joey) a line. +anymore. If you experience are setup in which this doesn't make +sense, please use the +.B \-h +commandline switch. If the remote host is located in the same domain as the host, .B syslogd Index: syslog.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/syslog.c,v retrieving revision 1.4 retrieving revision 1.6 diff -u -p -a -r1.4 -r1.6 --- syslog.c 11 Mar 2001 19:35:51 -0000 1.4 +++ syslog.c 27 Aug 2003 15:56:01 -0000 1.6 @@ -47,6 +47,9 @@ static char sccsid[] = "@(#)syslog.c 5.2 * Sun Mar 11 20:23:44 CET 2001: Martin Schulze * Use SOCK_DGRAM for loggin, renables it to work. * + * Wed Aug 27 17:48:16 CEST 2003: Martin Schulze + * Improved patch by Michael Pomraning to + * reconnect klogd to the logger after it went away. */ #include @@ -98,6 +101,7 @@ vsyslog(pri, fmt, ap) register char *p; time_t now; int fd, saved_errno; + int result; char tbuf[2048], fmt_cpy[1024], *stdp = (char *) 0; saved_errno = errno; @@ -167,7 +171,16 @@ vsyslog(pri, fmt, ap) } /* output the message to the local logger */ - if (write(LogFile, tbuf, cnt + 1) >= 0 || !(LogStat&LOG_CONS)) + result = write(LogFile, tbuf, cnt + 1); + + if (result == -1 + && (errno == ECONNRESET || errno == ENOTCONN || errno == ECONNREFUSED)) { + closelog(); + openlog(LogTag, LogStat | LOG_NDELAY, LogFacility); + result = write(LogFile, tbuf, cnt + 1); + } + + if (result >= 0 || !(LogStat&LOG_CONS)) return; /* Index: syslog.conf.5 =================================================================== RCS file: /var/cvs/infodrom/sysklogd/syslog.conf.5,v retrieving revision 1.7 retrieving revision 1.11 diff -u -p -a -r1.7 -r1.11 --- syslog.conf.5 21 Aug 1999 10:49:14 -0000 1.7 +++ syslog.conf.5 28 Sep 2006 18:43:36 -0000 1.11 @@ -64,7 +64,7 @@ in 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 @@ -121,12 +121,21 @@ behavior you can exclude some priorities This .BR syslogd (8) -has a syntax extension to the original BSD source, that makes its use -more intuitively. You may precede every priority with an equation sign -(``='') to specify only this single priority and not any of the -above. You may also (both is valid, too) precede the priority with an -exclamation mark (``!'') to ignore all that priorities, either exact -this one or this and any higher priority. If you use both extensions +has a syntax extension to the original BSD source, which makes its use +more intuitive. You may precede every priority with an equation sign +(``='') to specify that +.B syslogd +should only refer to this single priority and not this priority and +all higher priorities. + +You may also precide the priority with an exclamation mark (``!'') if +you want +.B syslogd +to ignore this priority and all higher priorities. +You may even use both, the exclamation mark and the equation sign if +you want +.B syslogd +to ignore only this single priority. If you use both extensions than the exclamation mark must occur before the equation sign, just use it intuitively. @@ -300,7 +309,7 @@ This lets the .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 Index: syslog_tst.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/syslog_tst.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -p -a -r1.1.1.1 -r1.2 --- syslog_tst.c 2 Jun 1997 17:21:41 -0000 1.1.1.1 +++ syslog_tst.c 18 Sep 2006 09:56:13 -0000 1.2 @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) if ( (nl = strrchr(bufr, '\n')) != \ (char *) 0) *nl = '\0'; - syslog(LOG_INFO, bufr); + syslog(LOG_INFO, "%s", bufr); logged += strlen(bufr); if ( logged > 1024 ) { @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) } else while (argc-- > 1) - syslog(LOG_INFO, argv++[1]); + syslog(LOG_INFO, "%s", argv++[1]); } else { Index: syslogd.c =================================================================== RCS file: /var/cvs/infodrom/sysklogd/syslogd.c,v retrieving revision 1.34 retrieving revision 1.48 diff -u -p -a -r1.34 -r1.48 --- syslogd.c 11 Mar 2001 19:40:10 -0000 1.34 +++ syslogd.c 25 May 2006 07:49:54 -0000 1.48 @@ -441,6 +441,45 @@ static char sccsid[] = "@(#)syslogd.c 5. * Don't return a closed fd if `-a' is called with a wrong path. * Thanks to Bill Nottingham for providing * a patch. + * Thu Apr 13 05:08:10 CEST 2001: Jon Burgess + * Moved the installation of the signal handler up a little bit + * so it guaranteed to be available when the child is forked, + * hence, fixing a race condition. This used to create problems + * with UML and fast machines. + * + * Sat Apr 17 18:03:05 CEST 2004: Steve Grubb + * Correct memory allocation for for commandline arguments in + * crunch_list(). + * + * Thu Apr 29 12:38:39 CEST 2004: Solar Designer + * Applied Openwall paranoia patches to improve crunch_list(). + * + * Tue May 4 16:47:30 CEST 2004: Solar Designer + * Ensure that "len" is not placed in a register, and that the + * endtty() signal handler is not installed too early which could + * cause a segmentation fault or worse. + * + * Tue May 4 16:52:01 CEST 2004: Solar Designer + * Adjust the size of a variable to prevent a buffer overflow + * should _PATH_DEV ever contain something different than "/dev/". + * + * Tue Nov 2 20:28:23 CET 2004: Colin Phipps + * Don't block on the network socket, in case a packet gets lost + * between select and recv. + * + * Sun Nov 7 12:28:47 CET 2004: Martin Schulze + * Discard any timestamp information found in received syslog + * messages. This will affect local messages sent from a + * different timezone. + * + * Sun Nov 7 13:47:00 CET 2004: Martin Schulze + * Remove trailing newline when forwarding messages. + * + * Thu May 25 09:47:38 CEST 2006: Martin Schulze + * Reset the 'restart' flag immediately after entering the + * restart code, so that subsequent SIGHUPs are able to set it + * again and cause a new restart. This fixes a race condition + * when somebody sends tons of HUP signals. */ @@ -890,11 +929,11 @@ int main(argc, argv) 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 @@ -992,6 +1031,7 @@ int main(argc, argv) (void) signal(SIGCHLD, reapchild); (void) signal(SIGALRM, domark); (void) signal(SIGUSR1, Debug ? debug_switch : SIG_IGN); + (void) signal(SIGXFSZ, SIG_IGN); (void) alarm(TIMERINTVL); /* Create a partial message table for all file descriptors. */ @@ -1074,9 +1114,9 @@ int main(argc, argv) (fd_set *) NULL, (struct timeval *) NULL); if ( restart ) { + restart = 0; dprintf("\nReceived SIGHUP, reloading syslogd.\n"); init(); - restart = 0; continue; } if (nfds == 0) { @@ -1141,13 +1181,13 @@ int main(argc, argv) */ 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 +1256,7 @@ static int create_inet_socket() { int fd, on = 1; struct sockaddr_in sin; + int sockflags; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { @@ -1241,6 +1282,24 @@ static int create_inet_socket() 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); @@ -1254,30 +1313,26 @@ char ** crunch_list(list) char *list; { - int count, i; + int i, m, n; char *p, *q; char **result = NULL; p = list; /* strip off trailing delimiters */ - while (p[strlen(p)-1] == LIST_DELIMITER) { - count--; + while (*p && p[strlen(p)-1] == LIST_DELIMITER) p[strlen(p)-1] = '\0'; - } /* cut off leading delimiters */ - while (p[0] == LIST_DELIMITER) { - count--; + while (p[0] == LIST_DELIMITER) p++; - } - /* count delimiters to calculate elements */ - for (count=i=0; p[i]; i++) - if (p[i] == LIST_DELIMITER) count++; + /* count delimiters to calculate the number of elements */ + for (n = i = 0; p[i]; i++) + if (p[i] == LIST_DELIMITER) n++; - if ((result = (char **)malloc(sizeof(char *) * count+2)) == NULL) { + if ((result = (char **)malloc(sizeof(char *) * (n + 2))) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); - exit(0); + exit(1); } /* @@ -1285,30 +1340,28 @@ crunch_list(list) * characters are different from any delimiters, * so we don't have to care about this. */ - count = 0; - while ((q=strchr(p, LIST_DELIMITER))) { - result[count] = (char *) malloc((q - p + 1) * sizeof(char)); - if (result[count] == NULL) { + m = 0; + while ((q = strchr(p, LIST_DELIMITER)) && m < n) { + result[m] = (char *) malloc((q - p + 1) * sizeof(char)); + if (result[m] == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); - exit(0); + exit(1); } - strncpy(result[count], p, q - p); - result[count][q - p] = '\0'; + memcpy(result[m], p, q - p); + result[m][q - p] = '\0'; p = q; p++; - count++; + m++; } - if ((result[count] = \ - (char *)malloc(sizeof(char) * strlen(p) + 1)) == NULL) { + if ((result[m] = strdup(p)) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); - exit(0); + exit(1); } - strcpy(result[count],p); - result[++count] = NULL; + result[++m] = NULL; #if 0 - count=0; - while (result[count]) - dprintf ("#%d: %s\n", count, StripDomains[count++]); + m = 0; + while (result[m]) + dprintf ("#%d: %s\n", m, result[m++]); #endif return result; } @@ -1539,30 +1592,48 @@ void logmsg(pri, msg, from, flags) 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. + * + * A message looks like + * Nov 17 11:42:33 CRON[ + * 01234567890123456 + * ^ ^ ^ ^ ^ + * + * Remote messages are not accompanied by a timestamp. + * Local messages are accompanied by a timestamp (program's timezone) */ msglen = strlen(msg); - if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' || - msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') - flags |= ADDDATE; - - (void) time(&now); - if (flags & ADDDATE) - timestamp = ctime(&now) + 4; - else { - timestamp = msg; + if (!(msglen < 16 || msg[3] != ' ' || msg[6] != ' ' || + msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')) { msg += 16; msglen -= 16; } + (void) time(&now); + timestamp = ctime(&now) + 4; + /* extract facility and priority level */ if (flags & MARK) fac = LOG_NFACILITIES; @@ -1581,9 +1652,13 @@ void logmsg(pri, msg, from, flags) (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 +1721,13 @@ void logmsg(pri, msg, from, flags) } } } +#ifdef __gnu_linux__ + sigprocmask(SIG_UNBLOCK, &mask, NULL); +#else #ifndef SYSV (void) sigsetmask(omask); #endif +#endif } #if FALSE } /* balance parentheses for emacs */ @@ -1771,7 +1850,7 @@ void fprintlog(f, from, flags, msg) dprintf("Not sending message to remote.\n"); else { f->f_time = now; - (void) snprintf(line, sizeof(line), "<%d>%s\n", f->f_prevpri, \ + (void) snprintf(line, sizeof(line), "<%d>%s", f->f_prevpri, \ (char *) iov[4].iov_base); l = strlen(line); if (l > MAXLINE) @@ -1815,7 +1894,7 @@ void fprintlog(f, from, flags, msg) v->iov_len = 1; } again: - /* f->f_file == -1 is an indicator that the we couldn't + /* f->f_file == -1 is an indicator that we couldn't open the file at startup. */ if (f->f_file == -1) break; @@ -1852,7 +1931,7 @@ void fprintlog(f, from, flags, msg) errno = e; logerror(f->f_un.f_fname); } - } else if (f->f_flags & SYNC_FILE) + } else if (f->f_type == F_FILE && (f->f_flags & SYNC_FILE)) (void) fsync(f->f_file); break; @@ -1891,7 +1970,7 @@ void wallmsg(f, iov) register struct filed *f; struct iovec *iov; { - char p[6 + UNAMESZ]; + char p[sizeof (_PATH_DEV) + UNAMESZ]; register int i; int ttyf, len; static int reenter = 0; @@ -1899,6 +1978,8 @@ void wallmsg(f, iov) struct utmp *uptr; char greetings[200]; + (void) &len; + if (reenter++) return; @@ -1913,7 +1994,6 @@ void wallmsg(f, iov) if (fork() == 0) { (void) signal(SIGTERM, SIG_DFL); (void) alarm(0); - (void) signal(SIGALRM, endtty); #ifndef SYSV (void) signal(SIGTTOU, SIG_IGN); (void) sigsetmask(0); @@ -1929,7 +2009,7 @@ void wallmsg(f, iov) /* is this slot used? */ if (ut.ut_name[0] == '\0') continue; - if (ut.ut_type == LOGIN_PROCESS) + if (ut.ut_type != USER_PROCESS) continue; if (!(strcmp (ut.ut_name,"LOGIN"))) /* paranoia */ continue; @@ -1959,6 +2039,7 @@ void wallmsg(f, iov) iov[1].iov_len = 0; } if (setjmp(ttybuf) == 0) { + (void) signal(SIGALRM, endtty); (void) alarm(15); /* open the terminal */ ttyf = open(p, O_WRONLY|O_NOCTTY);