Subject: bin/18652: inetd(8) signal handlers are not async-signal-safe
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ryany@pobox.com>
List: netbsd-bugs
Date: 10/13/2002 23:59:23
>Number:         18652
>Category:       bin
>Synopsis:       inetd(8) signal handlers are not async-signal-safe
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Oct 13 21:00:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Ryan Younce
>Release:        NetBSD 1.6I
>Organization:
>Environment:
System: NetBSD rdu57-072-122.nc.rr.com 1.6I NetBSD 1.6I (DORMOUSE) #0: Sun Oct 13 06:38:37 EDT 2002 root@rdu57-072-122.nc.rr.com:/usr/src/sys/arch/i386/compile/DORMOUSE i386
Architecture: i386
Machine: i386
$NetBSD: inetd.c,v 1.84 2002/09/19 21:59:03 mycroft Exp $
>Description:
	The current implementation of inetd uses signal handlers which
	call functions that are not defined to be asynchronous signal safe.
>How-To-Repeat:
	Unknown or difficult.
>Fix:
	This solution implements volatile signal flags which are set in the
	signal handler, which then returns.  Since a signal will interrupt
	an select(2) call (and main() will continue the loop in the event that
	select(2) prematurely exited due to a signal), the respective support
	function is called at the beginning of the loop's next iteration.

	It is difficult to exploit the erroneous behavior or test the
	patched version, but the following should theoretically make inetd 
	immune to any asynchronous side effects due to signal handling.

Index: inetd.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/inetd/inetd.c,v
retrieving revision 1.84
diff -u -r1.84 inetd.c
--- inetd.c	2002/09/19 21:59:03	1.84
+++ inetd.c	2002/10/14 03:31:14
@@ -282,6 +282,12 @@
 char	*curdom;
 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
 
+/* Signal flags */
+volatile sig_atomic_t	do_retry;
+volatile sig_atomic_t	do_config;
+volatile sig_atomic_t	do_reapchild;
+volatile sig_atomic_t	do_goaway;
+
 #ifndef OPEN_MAX
 #define OPEN_MAX	64
 #endif
@@ -373,6 +379,10 @@
 void		run_service __P((int, struct servtab *));
 int		setconfig __P((void));
 void		setup __P((struct servtab *));
+void		signal_config __P((int));
+void		signal_goaway __P((int));
+void		signal_reapchild __P((int));
+void		signal_retry __P((int));
 char	       *sskip __P((char **));
 char	       *skip __P((char **));
 void		tcpmux __P((int, struct servtab *));
@@ -489,18 +499,23 @@
 	}
 #endif
 
+	do_retry = 0;
+	do_config = 0;
+	do_reapchild = 0;
+	do_goaway = 0;
+
 	memset(&sv, 0, sizeof(sv));
 	sv.sv_mask = SIGBLOCK;
-	sv.sv_handler = retry;
+	sv.sv_handler = signal_retry;
 	sigvec(SIGALRM, &sv, (struct sigvec *)0);
 	config(SIGHUP);
-	sv.sv_handler = config;
+	sv.sv_handler = signal_config;
 	sigvec(SIGHUP, &sv, (struct sigvec *)0);
-	sv.sv_handler = reapchild;
+	sv.sv_handler = signal_reapchild;
 	sigvec(SIGCHLD, &sv, (struct sigvec *)0);
-	sv.sv_handler = goaway;
+	sv.sv_handler = signal_goaway;
 	sigvec(SIGTERM, &sv, (struct sigvec *)0);
-	sv.sv_handler = goaway;
+	sv.sv_handler = signal_goaway;
 	sigvec(SIGINT, &sv, (struct sigvec *)0);
 	sv.sv_mask = 0L;
 	sv.sv_handler = SIG_IGN;
@@ -510,6 +525,23 @@
 		int n, ctrl;
 		fd_set readable;
 
+		if (do_retry) {
+			retry(do_retry);
+			do_retry = 0;
+		}
+		if (do_config) {
+			config(do_config);
+			do_config = 0;
+		}
+		if (do_reapchild) {
+			reapchild(do_reapchild);
+			do_reapchild = 0;
+		}
+		if (do_goaway) {
+			goaway(do_goaway);
+			do_goaway = 0;
+		}
+
 		if (nsock == 0) {
 			(void) sigblock(SIGBLOCK);
 			while (nsock == 0)
@@ -741,6 +773,33 @@
 			recv(ctrl, buf, sizeof (buf), 0);
 		_exit(1);
 	}
+}
+
+void
+signal_retry(signo)
+	int signo;
+{
+	do_retry = signo;
+}
+
+void
+signal_config(signo)
+	int signo;
+{
+	do_config = signo;
+}
+
+void
+signal_reapchild(signo)
+	int signo;
+{
+	do_reapchild = signo;
+}
+
+void
+signal_goaway(signo)
+{
+	do_goaway = signo;
 }
 
 void
>Release-Note:
>Audit-Trail:
>Unformatted:
 	As of NetBSD-current 10/13/2002