s4-librpc: Fix double free.
authorAndreas Schneider <asn@samba.org>
Wed, 3 Aug 2011 21:44:45 +0000 (23:44 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 4 Aug 2011 10:31:18 +0000 (12:31 +0200)
Autobuild-User: Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date: Thu Aug  4 12:31:18 CEST 2011 on sn-devel-104

source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_smb2.c

index 395e0672558a57f3e3ad3b9504b8a590deb5ba2a..c2312953f849a864c8958f8ca49dd32d144f2a48 100644 (file)
@@ -79,6 +79,7 @@ struct smb_read_state {
 */
 static void smb_read_callback(struct smbcli_request *req)
 {
+       struct dcecli_connection *c;
        struct smb_private *smb;
        struct smb_read_state *state;
        union smb_read *io;
@@ -88,11 +89,12 @@ static void smb_read_callback(struct smbcli_request *req)
        state = talloc_get_type(req->async.private_data, struct smb_read_state);
        smb = talloc_get_type(state->c->transport.private_data, struct smb_private);
        io = state->io;
+       c = state->c;
 
        status = smb_raw_read_recv(state->req, io);
        if (NT_STATUS_IS_ERR(status)) {
-               pipe_dead(state->c, status);
                talloc_free(state);
+               pipe_dead(c, status);
                return;
        }
 
@@ -101,8 +103,8 @@ static void smb_read_callback(struct smbcli_request *req)
        if (state->received < 16) {
                DEBUG(0,("dcerpc_smb: short packet (length %d) in read callback!\n",
                         (int)state->received));
-               pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_INFO_LENGTH_MISMATCH);
                return;
        }
 
@@ -110,7 +112,6 @@ static void smb_read_callback(struct smbcli_request *req)
 
        if (frag_length <= state->received) {
                DATA_BLOB data = state->data;
-               struct dcecli_connection *c = state->c;
                data.length = state->received;
                talloc_steal(state->c, data.data);
                talloc_free(state);
@@ -128,8 +129,8 @@ static void smb_read_callback(struct smbcli_request *req)
 
        state->req = smb_raw_read_send(smb->tree, io);
        if (state->req == NULL) {
-               pipe_dead(state->c, NT_STATUS_NO_MEMORY);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_NO_MEMORY);
                return;
        }
 
@@ -257,7 +258,7 @@ static NTSTATUS smb_send_trans_request(struct dcecli_connection *c, DATA_BLOB *b
        struct smb_trans_state *state;
        uint16_t max_data;
 
-       state = talloc(smb, struct smb_trans_state);
+       state = talloc(c, struct smb_trans_state);
        if (state == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
index 50aed8cfd871ceb7f05a318ad091702f604f7cbc..59ee7a8fd8b7fbd7cd658af46ad2ce90e3541c53 100644 (file)
@@ -78,6 +78,7 @@ struct smb2_read_state {
 */
 static void smb2_read_callback(struct smb2_request *req)
 {
+       struct dcecli_connection *c;
        struct smb2_private *smb;
        struct smb2_read_state *state;
        struct smb2_read io;
@@ -86,26 +87,27 @@ static void smb2_read_callback(struct smb2_request *req)
 
        state = talloc_get_type(req->async.private_data, struct smb2_read_state);
        smb = talloc_get_type(state->c->transport.private_data, struct smb2_private);
+       c = state->c;
 
        status = smb2_read_recv(req, state, &io);
        if (NT_STATUS_IS_ERR(status)) {
-               pipe_dead(state->c, status);
                talloc_free(state);
+               pipe_dead(c, status);
                return;
        }
 
        if (!data_blob_append(state, &state->data, 
                                  io.out.data.data, io.out.data.length)) {
-               pipe_dead(state->c, NT_STATUS_NO_MEMORY);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_NO_MEMORY);
                return;
        }
 
        if (state->data.length < 16) {
                DEBUG(0,("dcerpc_smb2: short packet (length %d) in read callback!\n",
                         (int)state->data.length));
-               pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_INFO_LENGTH_MISMATCH);
                return;
        }
 
@@ -113,7 +115,6 @@ static void smb2_read_callback(struct smb2_request *req)
 
        if (frag_length <= state->data.length) {
                DATA_BLOB data = state->data;
-               struct dcecli_connection *c = state->c;
                talloc_steal(c, data.data);
                talloc_free(state);
                c->transport.recv_data(c, &data, NT_STATUS_OK);
@@ -131,8 +132,8 @@ static void smb2_read_callback(struct smb2_request *req)
        
        req = smb2_read_send(smb->tree, &io);
        if (req == NULL) {
-               pipe_dead(state->c, NT_STATUS_NO_MEMORY);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_NO_MEMORY);
                return;
        }
 
@@ -152,7 +153,7 @@ static NTSTATUS send_read_request_continue(struct dcecli_connection *c, DATA_BLO
        struct smb2_read_state *state;
        struct smb2_request *req;
 
-       state = talloc(smb, struct smb2_read_state);
+       state = talloc(c, struct smb2_read_state);
        if (state == NULL) {
                return NT_STATUS_NO_MEMORY;
        }