diff options
author | Volker Lendecke <vl@samba.org> | 2008-07-25 12:08:03 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2008-07-25 12:12:49 +0200 |
commit | 0f9c30c11421d045cace1f2c909fdb583ea830ba (patch) | |
tree | ccb52d64c949fa0e58f6b4a1a03fb164e5e45809 /source3 | |
parent | 933fdd4017fb79539b23222c8f8b538e11133130 (diff) | |
download | samba-0f9c30c11421d045cace1f2c909fdb583ea830ba.tar.gz samba-0f9c30c11421d045cace1f2c909fdb583ea830ba.tar.bz2 samba-0f9c30c11421d045cace1f2c909fdb583ea830ba.zip |
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
(cherry picked from commit 8691709626b0d461de91b8fc9d10c730d1f183dd)
(This used to be commit c70e2b6476d2d99c79624e15a4a3cfcdc850fc7c)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/winbindd/winbindd_dual.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 57ab627a5b..f2be6d692c 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -104,6 +104,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); @@ -129,6 +130,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; @@ -148,10 +150,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; } |