[PATCH] lib/tevent: fix race with signals and tevent_common_add_signal

Rusty Russell rusty at rustcorp.com.au
Thu Aug 27 20:34:22 MDT 2009


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 <rusty at rustcorp.com.au>
---
 lib/tevent/tevent_signal.c |   40 ++++++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index f64f317..172d4fa 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -215,6 +215,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;
@@ -251,26 +271,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;
 }
 
-- 
1.6.0.4




More information about the samba-technical mailing list