From f75182841d4a7d63bd070022270926e324631fa9 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 26 Mar 2015 10:48:31 +0100 Subject: [PATCH] s4-process_model: Do not close random fds while forking. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11180 The issue has been found with nss_wrapper debug output running: samba4.ntvfs.cifs.krb5.base.lock In the case here, we fork a child and close the fd without resetting the pipe fd variable. Then the fd was used to open the nss_wrapper hosts file which got the same fd. We forked again in the process model called close() on the re-used fd (of the pipe variable) again without nss_wrapper noticing. Now Samba opened the secrets tdb and got the same fd as nss_wrapper was using for the hosts file and next nss_wrapper tried to parse a TDB ... Pair-Programmed-With: Michael Adam Signed-off-by: Andreas Schneider Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher --- source4/smbd/process_standard.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index d3622f9f916..e68dbb12ce0 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -42,7 +42,7 @@ NTSTATUS process_model_standard_init(void); /* we hold a pipe open in the parent, and the any child processes wait for EOF on that pipe. This ensures that children die when the parent dies */ -static int child_pipe[2]; +static int child_pipe[2] = { -1, -1 }; /* called when the process model is selected @@ -266,7 +266,10 @@ static void standard_accept_connection(struct tevent_context *ev, tevent_add_fd(ev, ev, child_pipe[0], TEVENT_FD_READ, standard_pipe_handler, NULL); - close(child_pipe[1]); + if (child_pipe[1] != -1) { + close(child_pipe[1]); + child_pipe[1] = -1; + } /* Ensure that the forked children do not expose identical random streams */ set_need_random_reseed(); @@ -342,7 +345,10 @@ static void standard_new_task(struct tevent_context *ev, tevent_add_fd(ev, ev, child_pipe[0], TEVENT_FD_READ, standard_pipe_handler, NULL); - close(child_pipe[1]); + if (child_pipe[1] != -1) { + close(child_pipe[1]); + child_pipe[1] = -1; + } /* Ensure that the forked children do not expose identical random streams */ set_need_random_reseed(); -- 2.11.4.GIT