Subject: bin/24682: syslogd may die if HUP arrives in a certain phase of DNS lookup
To: None <gnats-bugs@gnats.netbsd.org>
From: None <he@netbsd.org>
List: netbsd-bugs
Date: 03/05/2004 17:36:38
>Number:         24682
>Category:       bin
>Synopsis:       syslogd may die if HUP arrives in a certain phase of DNS lookup
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 05 16:37:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Havard Eidnes
>Release:        NetBSD 1.6_STABLE 11 Dec 2002
>Organization:
	
>Environment:
System: NetBSD nnn.nnn.nnn 1.6_STABLE NetBSD 1.6_STABLE (NNN) #2: Thu Dec 12 11:23:32 CET 2002     he@nnn.nnn.nnn:/usr/src/sys/arch/i386/compile/NNN i386
Architecture: i386
Machine: i386
>Description:
	Syslogd may die if HUP signal to reinitialize arrives while
	doing a DNS lookup, because a malloc() may be attempted while
	the DNS lookup code is doing a free():

(gdb) target core /syslogd.core
Core was generated by `syslogd'.
Program terminated with signal 11, Segmentation fault.
#0  0x804a5eb in cfline (
    line=0xbfbfbe98 "*.err;kern.*;auth.notice;authpriv.none;mail.crit;local7,local6,local5.none\t/dev/console", f=0x0)
    at /usr/src/usr.sbin/syslogd/syslogd.c:1320
1320            memset(f, 0, sizeof(*f));
(gdb) p f
$1 = (struct filed *) 0x0
(gdb) where
#0  0x804a5eb in cfline (
    line=0xbfbfbe98 "*.err;kern.*;auth.notice;authpriv.none;mail.crit;local7,local6,local5.none\t/dev/console", f=0x0)
    at /usr/src/usr.sbin/syslogd/syslogd.c:1320
#1  0x804a368 in init (signo=1) at /usr/src/usr.sbin/syslogd/syslogd.c:1246
#2  0xbfbfdfdc in ?? ()
#3  0x807e6f5 in free ()
#4  0x8052e8f in _dns_gethtbyaddr ()
#5  0x806cb75 in nsdispatch ()
#6  0x80524ad in gethostbyaddr ()
#7  0x805147e in getnameinfo ()
#8  0x80511fa in getnameinfo ()
#9  0x8049e4d in cvthname (f=0xbfbfd4ac)
    at /usr/src/usr.sbin/syslogd/syslogd.c:1066
#10 0x80490bf in main (argc=1, argv=0xbfbfd674)
    at /usr/src/usr.sbin/syslogd/syslogd.c:540
#11 0x804825c in ___start ()
(gdb) 
(gdb) 
Suspended
nnn# ls -l /syslogd.core
-rw-------  1 root  wheel  290816 Mar  5 03:00 /syslogd.core
nnn# 
nnn# crontab -l
...
# rotate log files every hour, if necessary
0       *       *       *       *       /usr/bin/newsyslog
...

	
>How-To-Repeat:
	Run a moderately busy syslog server; watch it occasionally
	drop core when it's being reinitialized.


>Fix:
	This is an untested patch, but I think the cvthname() function
	also needs to be protected from the HUP and ALRM signals, and
	the easiest way seems to be to do as shown here.

	The same patch seems to be applicable to -current.

--- syslogd.c.orig	Wed Dec 11 17:43:15 2002
+++ syslogd.c	Fri Mar  5 17:25:04 2004
@@ -234,6 +234,7 @@
 	char *argv[];
 {
 	int ch, *funix, i, j, fklog, len, linesize;
+	int omask;
 	int *nfinetix, nfklogix, nfunixbaseix, nfds;
 	int funixsize = 0, funixmaxsize = 0;
 	struct sockaddr_un sunx, fromunix;
@@ -536,9 +537,14 @@
 					}
 
 					line[i] = '\0';
-					if (!reject)
+					if (!reject) {
+						omask = sigblock(
+							sigmask(SIGHUP)|
+							sigmask(SIGALRM));
 						printline(cvthname(&frominet),
 						    line);
+						(void)sigsetmask(omask);
+					}
 				}
 			}
 		}
@@ -714,14 +720,12 @@
 	int flags;
 {
 	struct filed *f;
-	int fac, msglen, omask, prilev;
+	int fac, msglen, prilev;
 	char *timestamp;
 
 	dprintf("logmsg: pri 0%o, flags 0x%x, from %s, msg %s\n",
 	    pri, flags, from, msg);
 
-	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
-
 	/*
 	 * Check to see if msg looks non-standard.
 	 */
@@ -755,7 +759,6 @@
 			fprintlog(f, flags, msg);
 			(void)close(f->f_file);
 		}
-		(void)sigsetmask(omask);
 		return;
 	}
 	for (f = Files; f; f = f->f_next) {
@@ -812,7 +815,6 @@
 			}
 		}
 	}
-	(void)sigsetmask(omask);
 }
 
 void
>Release-Note:
>Audit-Trail:
>Unformatted: