[asterisk-commits] tilghman: branch 1.4 r48375 - in /branches/1.4: ./ apps/ res/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Dec 10 17:47:21 MST 2006


Author: tilghman
Date: Sun Dec 10 18:47:21 2006
New Revision: 48375

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48375
Log:
Merged revisions 48374 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r48374 | tilghman | 2006-12-10 18:33:59 -0600 (Sun, 10 Dec 2006) | 5 lines

When doing a fork() and exec(), two problems existed (Issue 8086):
1) Ignored signals stayed ignored after the exec().
2) Signals could possibly fire between the fork() and exec(), causing Asterisk
signal handlers within the child to execute, which caused nasty race conditions.

........

Modified:
    branches/1.4/   (props changed)
    branches/1.4/apps/app_externalivr.c
    branches/1.4/apps/app_festival.c
    branches/1.4/apps/app_ices.c
    branches/1.4/apps/app_mp3.c
    branches/1.4/apps/app_nbscat.c
    branches/1.4/apps/app_zapras.c
    branches/1.4/res/res_agi.c
    branches/1.4/res/res_musiconhold.c

Propchange: branches/1.4/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.

Modified: branches/1.4/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_externalivr.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_externalivr.c (original)
+++ branches/1.4/apps/app_externalivr.c Sun Dec 10 18:47:21 2006
@@ -40,6 +40,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+#include <signal.h>
 
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
@@ -261,9 +262,13 @@
 		.finishlist = AST_LIST_HEAD_INIT_VALUE,
 	};
 	struct ivr_localuser *u = &foo;
+	sigset_t fullset, oldset;
 
 	lu = ast_module_user_add(chan);
-	
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	u->abort_current_sound = 0;
 	u->chan = chan;
 	
@@ -311,6 +316,9 @@
 	if (!pid) {
 		/* child process */
 		int i;
+
+		signal(SIGPIPE, SIG_DFL);
+		pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 
 		if (ast_opt_high_priority)
 			ast_set_priority(0);
@@ -334,6 +342,8 @@
 		int ready_fd;
 		int waitfds[2] = { child_errors_fd, child_commands_fd };
 		struct ast_channel *rchan;
+
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 
 		close(child_stdin[0]);
 		child_stdin[0] = 0;

Modified: branches/1.4/apps/app_festival.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_festival.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_festival.c (original)
+++ branches/1.4/apps/app_festival.c Sun Dec 10 18:47:21 2006
@@ -130,19 +130,26 @@
 #ifdef __PPC__ 
 	char c;
 #endif
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
 
         res = fork();
         if (res < 0)
                 ast_log(LOG_WARNING, "Fork failed\n");
-        if (res)
+        if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
                 return res;
+	}
         for (x=0;x<256;x++) {
                 if (x != fd)
                         close(x);
         }
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
-
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 /*IAS */
 #ifdef __PPC__  
 	for( x=0; x<length; x+=2)

Modified: branches/1.4/apps/app_ices.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_ices.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_ices.c (original)
+++ branches/1.4/apps/app_ices.c Sun Dec 10 18:47:21 2006
@@ -65,15 +65,27 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
+
+	/* Stop ignoring PIPE */
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
 	dup2(fd, STDIN_FILENO);
-	for (x=STDERR_FILENO + 1;x<256;x++) {
+	for (x=STDERR_FILENO + 1;x<1024;x++) {
 		if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
 			close(x);
 	}
@@ -84,7 +96,7 @@
 	/* As a last-ditch effort, try to use PATH */
 	execlp("ices", "ices", filename, (char *)NULL);
 	ast_log(LOG_WARNING, "Execute of ices failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int ices_exec(struct ast_channel *chan, void *data)

Modified: branches/1.4/apps/app_mp3.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_mp3.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_mp3.c (original)
+++ branches/1.4/apps/app_mp3.c Sun Dec 10 18:47:21 2006
@@ -64,15 +64,25 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	dup2(fd, STDOUT_FILENO);
-	for (x=0;x<256;x++) {
+	for (x=STDERR_FILENO + 1;x<256;x++) {
 		if (x != STDOUT_FILENO)
 			close(x);
 	}
@@ -94,7 +104,7 @@
 	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
 	}
 	ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int timed_read(int fd, void *data, int datalen, int timeout)

Modified: branches/1.4/apps/app_nbscat.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_nbscat.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_nbscat.c (original)
+++ branches/1.4/apps/app_nbscat.c Sun Dec 10 18:47:21 2006
@@ -68,16 +68,26 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
 
 	dup2(fd, STDOUT_FILENO);
-	for (x=0;x<256;x++) {
+	for (x = STDERR_FILENO + 1; x < 1024; x++) {
 		if (x != STDOUT_FILENO)
 			close(x);
 	}
@@ -85,7 +95,7 @@
 	execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
 	execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
 	ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int timed_read(int fd, void *data, int datalen)

Modified: branches/1.4/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_zapras.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_zapras.c (original)
+++ branches/1.4/apps/app_zapras.c Sun Dec 10 18:47:21 2006
@@ -82,11 +82,23 @@
 	char *argv[PPP_MAX_ARGS];
 	int argc = 0;
 	char *stringp=NULL;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
 
 	/* Start by forking */
 	pid = fork();
-	if (pid)
+	if (pid) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return pid;
+	}
+
+	/* Restore original signal handlers */
+	for (x=0;x<NSIG;x++)
+		signal(x, SIG_DFL);
+
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 
 	/* Execute RAS on File handles */
 	dup2(chan->fds[0], STDIN_FILENO);
@@ -98,10 +110,6 @@
 	/* Close other file descriptors */
 	for (x=STDERR_FILENO + 1;x<1024;x++) 
 		close(x);
-
-	/* Restore original signal handlers */
-	for (x=0;x<NSIG;x++)
-		signal(x, SIG_DFL);
 
 	/* Reset all arguments */
 	memset(argv, 0, sizeof(argv));

Modified: branches/1.4/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_agi.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/res/res_agi.c (original)
+++ branches/1.4/res/res_agi.c Sun Dec 10 18:47:21 2006
@@ -240,7 +240,7 @@
 	int audio[2];
 	int x;
 	int res;
-	sigset_t signal_set;
+	sigset_t signal_set, old_set;
 	
 	if (!strncasecmp(script, "agi://", 6))
 		return launch_netscript(script, argv, fds, efd, opid);
@@ -282,11 +282,14 @@
 			return AGI_RESULT_FAILURE;
 		}
 	}
-	ast_replace_sigchld();
+
+	/* Block SIGHUP during the fork - prevents a race */
+	sigfillset(&signal_set);
+	pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
 	pid = fork();
 	if (pid < 0) {
 		ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
-		ast_unreplace_sigchld();
+		pthread_sigmask(SIG_SETMASK, &old_set, NULL);
 		return AGI_RESULT_FAILURE;
 	}
 	if (!pid) {
@@ -314,9 +317,18 @@
 		} else {
 			close(STDERR_FILENO + 1);
 		}
-		
+
+		/* Before we unblock our signals, return our trapped signals back to the defaults */
+		signal(SIGHUP, SIG_DFL);
+		signal(SIGCHLD, SIG_DFL);
+		signal(SIGINT, SIG_DFL);
+		signal(SIGURG, SIG_DFL);
+		signal(SIGTERM, SIG_DFL);
+		signal(SIGPIPE, SIG_DFL);
+		signal(SIGXFSZ, SIG_DFL);
+
 		/* unblock important signal handlers */
-		if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
+		if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
 			ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
 			_exit(1);
 		}
@@ -332,6 +344,7 @@
 		fflush(stdout);
 		_exit(1);
 	}
+	pthread_sigmask(SIG_SETMASK, &old_set, NULL);
 	if (option_verbose > 2) 
 		ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
 	fds[0] = toast[0];
@@ -348,7 +361,6 @@
 
 	*opid = pid;
 	return AGI_RESULT_SUCCESS;
-		
 }
 
 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced)

Modified: branches/1.4/res/res_musiconhold.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_musiconhold.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/res/res_musiconhold.c (original)
+++ branches/1.4/res/res_musiconhold.c Sun Dec 10 18:47:21 2006
@@ -340,6 +340,7 @@
 	int argc = 0;
 	DIR *dir = NULL;
 	struct dirent *de;
+	sigset_t signal_set, old_set;
 
 	
 	if (!strcasecmp(class->dir, "nodir")) {
@@ -424,6 +425,11 @@
 	if (time(NULL) - class->start < respawn_time) {
 		sleep(respawn_time - (time(NULL) - class->start));
 	}
+
+	/* Block signals during the fork() */
+	sigfillset(&signal_set);
+	pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
+
 	time(&class->start);
 	class->pid = fork();
 	if (class->pid < 0) {
@@ -437,6 +443,10 @@
 
 		if (ast_opt_high_priority)
 			ast_set_priority(0);
+
+		/* Reset ignored signals back to default */
+		signal(SIGPIPE, SIG_DFL);
+		pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);
 
 		close(fds[0]);
 		/* Stdout goes to pipe */
@@ -464,6 +474,7 @@
 		_exit(1);
 	} else {
 		/* Parent */
+		pthread_sigmask(SIG_SETMASK, &old_set, NULL);
 		close(fds[1]);
 	}
 	return fds[0];



More information about the asterisk-commits mailing list