diff options
author | Stefan Metzmacher <metze@samba.org> | 2008-07-07 12:56:26 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2008-07-07 13:43:12 +0200 |
commit | 88a26f6e7fb8737f33e100a5e83138b0fb63efd4 (patch) | |
tree | 7fd55108d2173cdfdc1cae6afba0b8bf846b5196 /source4/smb_server/smb/trans2.c | |
parent | b6327116dd7f0e634e24e5a86e325b93567ecbde (diff) | |
download | samba-88a26f6e7fb8737f33e100a5e83138b0fb63efd4.tar.gz samba-88a26f6e7fb8737f33e100a5e83138b0fb63efd4.tar.xz samba-88a26f6e7fb8737f33e100a5e83138b0fb63efd4.zip |
smb_server/smb: fix crash bug with fragmented trans calls
We need to use smbsrv_setup_secondary_request(req) to send the
trans ack, because smbsrv_send_reply(req) destroys 'req'
and the partial trans list had dead elements in the list.
Also make sure the partial list element is removed by a talloc
destructor.
metze
(This used to be commit 221f4d6e534a40b7def6e51dc6b4f9e8057d18b7)
Diffstat (limited to 'source4/smb_server/smb/trans2.c')
-rw-r--r-- | source4/smb_server/smb/trans2.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c index 711c86bb74..fc17491c42 100644 --- a/source4/smb_server/smb/trans2.c +++ b/source4/smb_server/smb/trans2.c @@ -1036,6 +1036,12 @@ static NTSTATUS trans2_backend(struct smbsrv_request *req, struct trans_op *op) return NT_STATUS_FOOBAR; } +static int smbsrv_trans_partial_destructor(struct smbsrv_trans_partial *tp) +{ + DLIST_REMOVE(tp->req->smb_conn->trans_partial, tp); + return 0; +} + /* send a continue request @@ -1043,6 +1049,7 @@ static NTSTATUS trans2_backend(struct smbsrv_request *req, struct trans_op *op) static void reply_trans_continue(struct smbsrv_request *req, uint8_t command, struct smb_trans2 *trans) { + struct smbsrv_request *req2; struct smbsrv_trans_partial *tp; int count; @@ -1055,15 +1062,18 @@ static void reply_trans_continue(struct smbsrv_request *req, uint8_t command, tp = talloc(req, struct smbsrv_trans_partial); - tp->req = talloc_reference(tp, req); + tp->req = req; tp->trans = trans; tp->command = command; DLIST_ADD(req->smb_conn->trans_partial, tp); + talloc_set_destructor(tp, smbsrv_trans_partial_destructor); + + req2 = smbsrv_setup_secondary_request(req); /* send a 'please continue' reply */ - smbsrv_setup_reply(req, 0, 0); - smbsrv_send_reply(req); + smbsrv_setup_reply(req2, 0, 0); + smbsrv_send_reply(req2); } @@ -1334,7 +1344,8 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command) uint8_t, param_disp + param_count); if (trans->in.params.data == NULL) { - goto failed; + smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY); + return; } trans->in.params.length = param_disp + param_count; } @@ -1345,7 +1356,8 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command) uint8_t, data_disp + data_count); if (trans->in.data.data == NULL) { - goto failed; + smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY); + return; } trans->in.data.length = data_disp + data_count; } @@ -1363,16 +1375,11 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command) if (trans->in.params.length == param_total && trans->in.data.length == data_total) { /* its now complete */ - DLIST_REMOVE(tp->req->smb_conn->trans_partial, tp); - reply_trans_complete(tp->req, command, trans); + req = tp->req; + talloc_free(tp); + reply_trans_complete(req, command, trans); } return; - -failed: - smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY); - DLIST_REMOVE(req->smb_conn->trans_partial, tp); - talloc_free(req); - talloc_free(tp); } |