Back-port of Volkers fix.
authorJeremy Allison <jra@samba.org>
Fri, 25 Jul 2008 18:46:34 +0000 (11:46 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 25 Jul 2008 18:46:34 +0000 (11:46 -0700)
    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.

source/nsswitch/winbindd_dual.c

index 40ebf54cb95a479bb50600ce90297b511f302d63..396eca7beb389c181f06b01166b4ed3599f082f4 100644 (file)
@@ -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;
        }