summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-06-02 16:43:31 -0700
committerJeremy Allison <jra@samba.org>2010-06-02 16:43:31 -0700
commit53e465062249bc91e53eb8d5fa54034933a650af (patch)
treee7c38eb3727ece4560d2f637e5cd2ced697b1d69
parentbcd4077be64e49b11a819cdcf27939a0fcc0d9bd (diff)
downloadsamba-53e465062249bc91e53eb8d5fa54034933a650af.tar.gz
samba-53e465062249bc91e53eb8d5fa54034933a650af.tar.xz
samba-53e465062249bc91e53eb8d5fa54034933a650af.zip
Fix a crash bug found by Ira Cooper <samba@ira.wakeful.net>.
A create call comes in, goes async (on the oplock request). At a later time (just before a cancel request is received) it completes, and goes through smbd_smb2_request_reply() to send the reply to the create call. However, the output socket queue is full, so when tstream_writev_queue_send() is called from smbd_smb2_request_reply(), the smb2req stays on the "being processed" queue on sconn->smb2.requests, as only when tstream_writev_queue_send() completes is smbd_smb2_request_writev_done() get called, which will TALLOC_FREE the smb2req (and thus take if off the queue). The cancel comes in, gets processed and looks through the requests on the queue, and BANG - hits the smb2req that has already been processed and is outgoing.... Remove the request from the queue once tstream_writev_queue_send() is called and not in the talloc destructor function. Jeremy.
-rw-r--r--source3/smbd/smb2_server.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index b081b6a2576..7a2a32a9dce 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -156,10 +156,6 @@ static int smbd_smb2_request_parent_destructor(struct smbd_smb2_request **req)
static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
{
- if (req->out.vector) {
- DLIST_REMOVE(req->sconn->smb2.requests, req);
- }
-
if (req->parent) {
*req->parent = NULL;
talloc_free(req->mem_pool);
@@ -1245,6 +1241,11 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
return NT_STATUS_NO_MEMORY;
}
tevent_req_set_callback(subreq, smbd_smb2_request_writev_done, req);
+ /*
+ * We're done with this request -
+ * move it off the "being processed" queue.
+ */
+ DLIST_REMOVE(req->sconn->smb2.requests, req);
return NT_STATUS_OK;
}