First part of fix for bug #7159 - client rpc_transport doesn't cope with bad server...
authorStefan Metzmacher <metze@samba.org>
Tue, 6 Apr 2010 10:20:02 +0000 (12:20 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 7 Apr 2010 09:04:15 +0000 (11:04 +0200)
Ensure that subreq is *always* talloc_free'd in the _done
function, as it has an event timeout attached. If the
read requests look longer than the cli->timeout, then
the timeout fn is called with already freed data.

Jeremy.
(cherry picked from commit ad77ae1d5870e06f8587ecf634e0b6bdcbb950d7)
(similar to commit 6e5b6b5acb30869eb63b25ed1406014101a5e89d)

Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/rpc_client/rpc_transport_np.c
source3/rpc_client/rpc_transport_sock.c

index 80ff3840462d938b8ed5ff262f5fbacf0816752c..fdfbab4ceac0f2cb01ca7dd5c9065b887994fd56 100644 (file)
@@ -159,6 +159,9 @@ static void rpc_np_read_done(struct async_req *subreq)
        NTSTATUS status;
        uint8_t *rcvbuf;
 
+       /* We must free subreq in this function as there is
+          a timer event attached to it. */
+
        status = cli_read_andx_recv(subreq, &state->received, &rcvbuf);
        /*
         * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
@@ -180,6 +183,7 @@ static void rpc_np_read_done(struct async_req *subreq)
        }
 
        memcpy(state->data, rcvbuf, state->received);
+       TALLOC_FREE(subreq);
        async_req_done(req);
 }
 
index b1d9d8fbe133aa7ffbdccb6b2afaebff4b1432cf..7115dc4c928461034f4ce8a0e6cf5b4f1a0e6e0a 100644 (file)
@@ -76,11 +76,17 @@ static void rpc_sock_read_done(struct tevent_req *subreq)
                req->private_data, struct rpc_sock_read_state);
        int err;
 
+       /* We must free subreq in this function as there is
+         a timer event attached to it. */
+
        state->received = async_recv_recv(subreq, &err);
+
        if (state->received == -1) {
+               TALLOC_FREE(subreq);
                async_req_nterror(req, map_nt_error_from_unix(err));
                return;
        }
+       TALLOC_FREE(subreq);
        async_req_done(req);
 }
 
@@ -137,11 +143,17 @@ static void rpc_sock_write_done(struct tevent_req *subreq)
                req->private_data, struct rpc_sock_write_state);
        int err;
 
+       /* We must free subreq in this function as there is
+         a timer event attached to it. */
+
        state->sent = async_send_recv(subreq, &err);
+
        if (state->sent == -1) {
+               TALLOC_FREE(subreq);
                async_req_nterror(req, map_nt_error_from_unix(err));
                return;
        }
+       TALLOC_FREE(subreq);
        async_req_done(req);
 }