From 988118c2358204eab5bb5907d0f5390cfece9538 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Aug 2012 16:49:52 -0700 Subject: [PATCH] s3: Fix a crash in reply_lockingX_error A timed brlock with 2 locks comes in and the second one blocks, file is closed. smbd_cancel_pending_lock_requests_by_fid sets blr->fsp to NULL. reply_lockingX_error (called via MSG_SMB_BLOCKING_LOCK_CANCEL) deferences blr->fsp because blr->lock_num==1 (the second one blocked). This patch fixes the bug by only undoing the locks if fsp!=NULL. fsp==NULL is the close case where everything is undone anyway. Thanks to Peter Somogyi, somogyi@hu.ibm.com for this bug report. Fix bug #9084 - Blocking lock followed by close can crash smbd. (cherry picked from commit d80fbbea8ec77c0bda0e3fb9eaed2f170784ea7d) (cherry picked from commit b27caac5e077b49f46edf34045bb4fd8d17b4c77) --- source3/smbd/blocking.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 3f49421f53c..08af28ad0dd 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -299,7 +299,7 @@ static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTAT obtained first. *****************************************************************************/ -static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status) +static void undo_locks_obtained(struct blocking_lock_record *blr) { files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); @@ -343,8 +343,6 @@ static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS stat offset, WINDOWS_LOCK); } - - generic_blocking_lock_error(blr, status); } /**************************************************************************** @@ -357,8 +355,17 @@ static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS switch(blr->req->cmd) { case SMBlockingX: - reply_lockingX_error(blr, status); - break; + /* + * This code can be called during the rundown of a + * file after it was already closed. In that case, + * blr->fsp==NULL and we do not need to undo any + * locks, they are already gone. + */ + if (blr->fsp != NULL) { + undo_locks_obtained(blr); + } + generic_blocking_lock_error(blr, status); + break; case SMBtrans2: case SMBtranss2: reply_nterror(blr->req, status); -- 2.34.1