From 1885b6e3a8db06c1c57378d635cf3cf92a1b7297 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Jun 2017 12:30:33 +0200 Subject: [PATCH] s3:smb2_create: avoid reusing the 'tevent_req' within smbd_smb2_create_send() As the caller ("smbd_smb2_request_process_create()") already sets the callback, the first time, it's not safe to reuse the tevent_req structure. The typicall 'tevent_req_nterror(); return tevent_req_post()' will crash as the tevent_req_nterror() already triggered the former callback, which calls smbd_smb2_create_recv(), were tevent_req_received() invalidates the tevent_req structure, so that tevent_req_post() will crash. There's actually no need to (re-)use the old structure at all. All we need in the reentrant code path is the existing smb1req structure, smbd_smb2_fake_smb_request() should handle this transparently for us. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12832 Signed-off-by: Stefan Metzmacher --- source3/smbd/smb2_create.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 81e0818..0a5d0ec 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -483,34 +483,28 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, requested_oplock_level = in_oplock_level; } - - if (smb2req->subreq == NULL) { - /* New create call. */ - req = tevent_req_create(mem_ctx, &state, + req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_create_state); - if (req == NULL) { - return NULL; - } - state->smb2req = smb2req; + if (req == NULL) { + return NULL; + } + state->smb2req = smb2req; - smb1req = smbd_smb2_fake_smb_request(smb2req); - if (tevent_req_nomem(smb1req, req)) { - return tevent_req_post(req, ev); - } - state->smb1req = smb1req; - smb2req->subreq = req; + smb1req = smbd_smb2_fake_smb_request(smb2req); + if (tevent_req_nomem(smb1req, req)) { + return tevent_req_post(req, ev); + } + state->smb1req = smb1req; + + if (smb2req->subreq == NULL) { DEBUG(10,("smbd_smb2_create: name[%s]\n", in_name)); } else { - /* Re-entrant create call. */ - req = smb2req->subreq; - state = tevent_req_data(req, - struct smbd_smb2_create_state); - smb1req = state->smb1req; - TALLOC_FREE(state->out_context_blobs); DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n", in_name )); } + TALLOC_FREE(smb2req->subreq); + smb2req->subreq = req; state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs); if (tevent_req_nomem(state->out_context_blobs, req)) { -- 1.9.1