mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 03:50:31 +00:00
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. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2@48374 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -234,7 +234,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
|
||||
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);
|
||||
@@ -276,6 +276,10 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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));
|
||||
@@ -293,9 +297,18 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
|
||||
} 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);
|
||||
}
|
||||
@@ -310,6 +323,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op
|
||||
fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno));
|
||||
_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];
|
||||
|
@@ -326,6 +326,7 @@ static int spawn_mp3(struct mohclass *class)
|
||||
int argc = 0;
|
||||
DIR *dir = NULL;
|
||||
struct dirent *de;
|
||||
sigset_t signal_set, old_set;
|
||||
|
||||
|
||||
if (!strcasecmp(class->dir, "nodir")) {
|
||||
@@ -426,6 +427,11 @@ static int spawn_mp3(struct mohclass *class)
|
||||
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) {
|
||||
@@ -440,6 +446,10 @@ static int spawn_mp3(struct mohclass *class)
|
||||
if (option_highpriority)
|
||||
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 */
|
||||
dup2(fds[1], STDOUT_FILENO);
|
||||
@@ -466,6 +476,7 @@ static int spawn_mp3(struct mohclass *class)
|
||||
_exit(1);
|
||||
} else {
|
||||
/* Parent */
|
||||
pthread_sigmask(SIG_SETMASK, &old_set, NULL);
|
||||
close(fds[1]);
|
||||
}
|
||||
return fds[0];
|
||||
|
Reference in New Issue
Block a user