From dd34be277116055fa68e62bc0b6f5955d2e37ffc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Feb 2025 16:04:01 +0100 Subject: [PATCH 1/2] vfs: Fix a lock order violation in unlinkat_acl_tdb() unlinkat is called when the share mode record is locked. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15791 Signed-off-by: Volker Lendecke --- source3/modules/vfs_acl_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index f2d2692159f..4a7965c7e9f 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -58,7 +58,7 @@ static bool acl_tdb_init(void) become_root(); acl_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600, - DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE); + DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE); unbecome_root(); if (acl_db == NULL) { -- 2.39.5 From 31c032b4909d544cecc31cf6acf1631f43043390 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 28 Jan 2025 14:03:49 +0100 Subject: [PATCH 2/2] vfs: Fix Bug 15791, vfs_acl_tdb unlinkat() Bug: https://bugzilla.samba.org/show_bug.cgi?id=15791 Signed-off-by: Volker Lendecke --- source3/modules/vfs_acl_tdb.c | 49 +++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 4a7965c7e9f..b054f159f87 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -195,38 +195,43 @@ static int unlinkat_acl_tdb(vfs_handle_struct *handle, const struct smb_filename *smb_fname, int flags) { - struct smb_filename *smb_fname_tmp = NULL; - struct db_context *db = acl_db; - int ret = -1; - - smb_fname_tmp = cp_smb_filename_nostream(talloc_tos(), smb_fname); - if (smb_fname_tmp == NULL) { - errno = ENOMEM; - goto out; - } + struct stat_ex st = {}; + int ret; - ret = vfs_stat(handle->conn, smb_fname_tmp); - if (ret == -1) { - goto out; + if (!is_named_stream(smb_fname)) { + if (VALID_STAT(smb_fname->st)) { + st = smb_fname->st; + } else { + ret = SMB_VFS_NEXT_FSTATAT(handle, + dirfsp, + smb_fname, + &st, + AT_SYMLINK_NOFOLLOW); + if (ret == -1) { + return ret; + } + } } if (flags & AT_REMOVEDIR) { - ret = rmdir_acl_common(handle, - dirfsp, - smb_fname_tmp); + ret = rmdir_acl_common(handle, dirfsp, smb_fname); } else { - ret = unlink_acl_common(handle, - dirfsp, - smb_fname_tmp, - flags); + ret = unlink_acl_common(handle, dirfsp, smb_fname, flags); } if (ret == -1) { - goto out; + return -1; } - acl_tdb_delete(handle, db, &smb_fname_tmp->st); - out: + if (is_named_stream(smb_fname)) { + /* + * ACLs only stored for basenames + */ + return ret; + } + + acl_tdb_delete(handle, acl_db, &st); + return ret; } -- 2.39.5