From 6abb637e3e0d23635fdbbb91c163731b325d696d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 28 Aug 2009 12:04:22 +0930 Subject: lib/tevent: fix race with signals and tevent_common_add_signal We carefully preserve the old signal handler, but we replace it before we've set up everything; in particular, if we fail setting up the pipe_hack we could write a NUL char to stdout (fd 0), instead of calling the old signal handler. Replace the signal handler as the very last thing we do. Signed-off-by: Rusty Russell --- lib/tevent/tevent_signal.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c index 429995318b..5e4e81b73c 100644 --- a/lib/tevent/tevent_signal.c +++ b/lib/tevent/tevent_signal.c @@ -219,6 +219,26 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, return NULL; } + /* we need to setup the pipe hack handler if not already + setup */ + if (ev->pipe_fde == NULL) { + if (sig_state->pipe_hack[0] == 0 && + sig_state->pipe_hack[1] == 0) { + if (pipe(sig_state->pipe_hack) == -1) { + talloc_free(se); + return NULL; + } + ev_set_blocking(sig_state->pipe_hack[0], false); + ev_set_blocking(sig_state->pipe_hack[1], false); + } + ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0], + TEVENT_FD_READ, signal_pipe_handler, NULL); + if (!ev->pipe_fde) { + talloc_free(se); + return NULL; + } + } + /* only install a signal handler if not already installed */ if (sig_state->sig_handlers[signum] == NULL) { struct sigaction act; @@ -255,26 +275,6 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, talloc_set_destructor(se, tevent_signal_destructor); talloc_set_destructor(sl, tevent_common_signal_list_destructor); - /* we need to setup the pipe hack handler if not already - setup */ - if (ev->pipe_fde == NULL) { - if (sig_state->pipe_hack[0] == 0 && - sig_state->pipe_hack[1] == 0) { - if (pipe(sig_state->pipe_hack) == -1) { - talloc_free(se); - return NULL; - } - ev_set_blocking(sig_state->pipe_hack[0], false); - ev_set_blocking(sig_state->pipe_hack[1], false); - } - ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0], - TEVENT_FD_READ, signal_pipe_handler, NULL); - if (!ev->pipe_fde) { - talloc_free(se); - return NULL; - } - } - return se; } -- cgit