From: Jeremy Allison Date: Fri, 25 Jul 2008 18:46:34 +0000 (-0700) Subject: Back-port of Volkers fix. X-Git-Tag: samba-3.0.32~8 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=c93d42969451949566327e7fdbf29bfcee2c8319 Back-port of Volkers fix. Fix a race condition in winbind leading to a crash When SIGCHLD handling is delayed for some reason, sending a request to a child can fail early because the child has died already. In this case async_main_request_sent() directly called the continuation function without properly removing the malfunctioning child process and the requests in the queue. The next request would then crash in the DLIST_ADD_END() in async_request() because the request pending for the child had been talloc_free()'ed and yet still was referenced in the list. This one is *old*... Volker Jeremy. --- diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index 40ebf54cb95..396eca7beb3 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -102,6 +102,7 @@ struct winbindd_async_request { void *private_data; }; +static void async_request_fail(struct winbindd_async_request *state); static void async_main_request_sent(void *private_data, BOOL success); static void async_request_sent(void *private_data, BOOL success); static void async_reply_recv(void *private_data, BOOL success); @@ -127,6 +128,7 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, state->mem_ctx = mem_ctx; state->child = child; + state->reply_timeout_event = NULL; state->request = request; state->response = response; state->continuation = continuation; @@ -146,10 +148,7 @@ static void async_main_request_sent(void *private_data, BOOL success) if (!success) { DEBUG(5, ("Could not send async request\n")); - - state->response->length = sizeof(struct winbindd_response); - state->response->result = WINBINDD_ERROR; - state->continuation(state->private_data, False); + async_request_fail(state); return; }