Skip to content

Commit dce8477

Browse files
committed
SMB3: Close all deferred handles of inode in case of handle lease break
jira VULN-131073 cve-pre CVE-2025-38527 commit-author Bharath SM <bharathsm@microsoft.com> commit 47592fa Oplock break may occur for different file handle than the deferred handle. Check for inode deferred closes list, if it's not empty then close all the deferred handles of inode because we should not cache handles if we dont have handle lease. Eg: If openfilelist has one deferred file handle and another open file handle from app for a same file, then on a lease break we choose the first handle in openfile list. The first handle in list can be deferred handle or actual open file handle from app. In case if it is actual open handle then today, we don't close deferred handles if we lose handle lease on a file. Problem with this is, later if app decides to close the existing open handle then we still be caching deferred handles until deferred close timeout. Leaving open handle may result in sharing violation when windows client tries to open a file with limited file share access. So we should check for deferred list of inode and walk through the list of deferred files in inode and close all deferred files. Fixes: 9e31678 ("SMB3: fix lease break timeout when multiple deferred close handles for the same file.") Cc: stable@kernel.org Signed-off-by: Bharath SM <bharathsm@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit 47592fa) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
1 parent c2de732 commit dce8477

File tree

1 file changed

+1
-8
lines changed

1 file changed

+1
-8
lines changed

fs/cifs/file.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5053,8 +5053,6 @@ void cifs_oplock_break(struct work_struct *work)
50535053
struct TCP_Server_Info *server = tcon->ses->server;
50545054
int rc = 0;
50555055
bool purge_cache = false;
5056-
struct cifs_deferred_close *dclose;
5057-
bool is_deferred = false;
50585056

50595057
wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
50605058
TASK_UNINTERRUPTIBLE);
@@ -5095,14 +5093,9 @@ void cifs_oplock_break(struct work_struct *work)
50955093
* file handles but cached, then schedule deferred close immediately.
50965094
* So, new open will not use cached handle.
50975095
*/
5098-
spin_lock(&CIFS_I(inode)->deferred_lock);
5099-
is_deferred = cifs_is_deferred_close(cfile, &dclose);
5100-
spin_unlock(&CIFS_I(inode)->deferred_lock);
51015096

5102-
if (!CIFS_CACHE_HANDLE(cinode) && is_deferred &&
5103-
cfile->deferred_close_scheduled && delayed_work_pending(&cfile->deferred)) {
5097+
if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes))
51045098
cifs_close_deferred_file(cinode);
5105-
}
51065099

51075100
/*
51085101
* releasing stale oplock after recent reconnect of smb session using

0 commit comments

Comments
 (0)