summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-07-07 12:56:26 +0200
committerStefan Metzmacher <metze@samba.org>2008-07-07 13:43:12 +0200
commit88a26f6e7fb8737f33e100a5e83138b0fb63efd4 (patch)
tree7fd55108d2173cdfdc1cae6afba0b8bf846b5196
parentb6327116dd7f0e634e24e5a86e325b93567ecbde (diff)
downloadsamba-88a26f6e7fb8737f33e100a5e83138b0fb63efd4.tar.gz
samba-88a26f6e7fb8737f33e100a5e83138b0fb63efd4.tar.bz2
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)
-rw-r--r--source4/smb_server/smb/trans2.c33
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);
}