s3: Fix a crash in reply_lockingX_error
authorVolker Lendecke <vl@samba.org>
Tue, 7 Aug 2012 23:49:52 +0000 (16:49 -0700)
committerKarolin Seeger <kseeger@samba.org>
Fri, 21 Sep 2012 07:44:41 +0000 (09:44 +0200)
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

index 3f49421f53ce12be13a23ed651e7b5d4893b490a..08af28ad0dd5e432deeb9d8bfdcadbb6418ba8cb 100644 (file)
@@ -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);