sophie: sig_exit() callable by child, causes weird hangs

Chris Stromsoe <[email protected]> Mon, 9 Aug 2004 23:33:44 -0700 (PDT)
Newsgroups gmane.comp.security.virus.vtools
Message-ID <[email protected]>
While trying to figure out why sophie was inexplicably hanging on me 
earlier today, I found a problem.  If a child process segfaults, the 
sig_exit handler gets called and will close and unlink the sophie socket, 
leaving the parent to sit in accept() forever.  I added a test to 
sig_exit() to check for child status.  This may fix some of the other 
random "hang" issues that have come up over the last few months that sound 
sort of similar to what I was seeing earlier.  Patch is attached.


-Chris

_______________________________________________
vtools mailing list
[email protected]
http://www.vanja.com/list/listinfo.cgi/vtools
sophie.c.diff (text/plain, 1.5 KB)
--- sophie.c.orig	Mon Aug  9 23:17:50 2004
+++ sophie.c	Mon Aug  9 22:08:51 2004
@@ -39,6 +39,8 @@
 	NULL
 };
 
+static int child = -1;
+
 /* Configuration file */
 char config_file[MAXPATHLEN];
 
@@ -100,6 +102,12 @@
 /* Cleanup and exit */
 void sig_exit(int sig)
 {
+	if (child == 0) {
+		sophie_print(1, "%s SIGNAL '%d' caught by the child, ignoring",
+			NOTESTR, sig);
+		return;
+	}
+
 	sophie_print(0, "%s SIGNAL '%d' caught - cleaning up and exiting.", NOTESTR, sig);
 
 	sophie_end();
@@ -186,7 +194,7 @@
 	int msgsock = -99;
 	
 	/* Related to other stuff */
-	int c, pid, cpid;
+	int c, pid;
 	
 	/* 'Read' buffer */
 	char buf[MAXPATHLEN];
@@ -616,16 +624,16 @@
 			sigaddset(&bset, SIGCHLD);
 			sigprocmask(SIG_BLOCK, &bset, NULL);
 
-			cpid = fork();
+			child = fork();
 
-			if (cpid == -1)
+			if (child == -1)
 			{
 				sigprocmask(SIG_UNBLOCK, &bset, NULL);
 				sophie_print(0, "%s fork() failed! [%s]", ERRSTR, strerror(errno));
 				close(msgsock);
 				goto LOOP;
 			}
-			else if (cpid > 0)
+			else if (child > 0)
 			{
 				close(msgsock);
 #ifdef SOPHIE_NET
@@ -636,7 +644,7 @@
 				sophie_print(1, "%s fork()ed a child - everything seems ok", NOTESTR);
 				continue;
 			}
-			else if (cpid == 0)
+			else if (child == 0)
 			{
 				struct sophie_notification notification;
 #ifdef USE_FGETS
@@ -644,6 +652,7 @@
 #else
 				int ret;
 #endif
+
 				/* child */
 				sigprocmask(SIG_UNBLOCK, &bset, NULL);