Reset SIGCHLD and SIGTERM handlers to SIG_DFL in child processes because it is not their business to handle these signals. Block SIGCHLD and SIGTERM for the short time of fork, changing signal handlers and changing "children" hash table to avoid race conditions with nasty consequences. Fix SIGTERM handler to always unlink pidfile.
Signed-off-by: Dmitry V. Levin <[email protected]> --- nbd-server.c | 23 ++++++++++++++--------- 1 files changed, 14 insertions(+), 9 deletions(-) diff --git a/nbd-server.c b/nbd-server.c index 80681c7..fc5ae2d 100644 --- a/nbd-server.c +++ b/nbd-server.c @@ -1087,10 +1087,8 @@ void sigchld_handler(int s) { **/ void killchild(gpointer key, gpointer value, gpointer user_data) { pid_t *pid=value; - int *parent=user_data; kill(*pid, SIGTERM); - *parent=1; } /** @@ -1099,13 +1097,8 @@ void killchild(gpointer key, gpointer value, gpointer user_data) { * is severely wrong). **/ void sigterm_handler(int s) { - int parent=0; - - g_hash_table_foreach(children, killchild, &parent); - - if(parent) { - unlink(pidfname); - } + g_hash_table_foreach(children, killchild, NULL); + unlink(pidfname); exit(EXIT_SUCCESS); } @@ -2198,9 +2191,16 @@ handle_connection(GArray *servers, int net, SERVER *serve, CLIENT *client) if (!dontfork) { pid_t pid; int i; + sigset_t newset; + sigset_t oldset; + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + sigaddset(&newset, SIGTERM); + sigprocmask(SIG_BLOCK, &newset, &oldset); if ((pid = fork()) < 0) { msg3(LOG_INFO,"Could not fork (%s)",strerror(errno)) ; + sigprocmask(SIG_SETMASK, &oldset, NULL); goto handle_connection_out; } if (pid > 0) { /* parent */ @@ -2209,9 +2209,14 @@ handle_connection(GArray *servers, int net, SERVER *serve, CLIENT *client) pidp = g_malloc(sizeof(pid_t)); *pidp = pid; g_hash_table_insert(children, pidp, pidp); + sigprocmask(SIG_SETMASK, &oldset, NULL); goto handle_connection_out; } /* child */ + signal(SIGCHLD, SIG_DFL); + signal(SIGTERM, SIG_DFL); + sigprocmask(SIG_SETMASK, &oldset, NULL); + g_hash_table_destroy(children); children = NULL; for(i=0;i<servers->len;i++) { -- ldv ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Nbd-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nbd-general
