]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Fix failure to check dstdir for delete on close
authorVolker Lendecke <vl@samba.org>
Thu, 19 Nov 2020 11:38:06 +0000 (12:38 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 20 Nov 2020 00:20:06 +0000 (00:20 +0000)
In smb2_setinfo.c the call to smbd_do_setfilepathinfo() to perform the
rename takes place while holding a share mode lock. The function
check_parent_access() called below tries to query the destination
directory's locking.tdb entry to check whether the delete on close
flag is set on the destination directory. This fails because the
file to be renamed already has the share mode entry locked, we can't
lock two share mode entries simultaneously.

Convert the check to use fetch_share_mode_unlocked(). This might
introduce races, but this whole check is racy anyway. It does not
really matter whether we do the check for delete_on_close under a lock
or not, fetch_share_mode_unlocked() retrieves a consistent status of
the locking.tdb entry at some point in time as well.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Nov 20 00:20:06 UTC 2020 on sn-devel-184

selftest/knownfail.d/rename_to_del_on_close_dir [deleted file]
source3/smbd/open.c

diff --git a/selftest/knownfail.d/rename_to_del_on_close_dir b/selftest/knownfail.d/rename_to_del_on_close_dir
deleted file mode 100644 (file)
index dc450e0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.libsmb.samba.tests.libsmb.LibsmbTestCase.test_RenameDstDelOnClose\(nt4_dc_smb1\)
\ No newline at end of file
index 95934e2e3211922411d08a1aa1c543f6410b9a85..11ddfc6eb0911fdc01830947273a8fe12e721288 100644 (file)
@@ -373,7 +373,12 @@ NTSTATUS check_parent_access(struct connection_struct *conn,
                goto out;
        }
 
-       lck = get_existing_share_mode_lock(frame, id);
+       /*
+        * Don't take a lock here. We just need a snapshot
+        * of the current state of delete on close and someone
+        * else may already have a lock on this id.
+        */
+       lck = fetch_share_mode_unlocked(frame, id);
        if (lck == NULL) {
                status = NT_STATUS_OK;
                goto out;