Skip to contentSkip to conversation

FAILED: patch "[PATCH] smb: client: avoid leaking refcount when cifs_sb_tlink()" failed to apply to 5.15-stable tree

PATCH New [email protected] 2 participants 2 messages Sep 16 – Sep 17

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 23b26f4408ac3f35a482d2e5cf6fc865d4201b71
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091628-uniquely-reborn-a640@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 23b26f4408ac3f35a482d2e5cf6fc865d4201b71 Mon Sep 17 00:00:00 2001
From: Bjoern Doebel <[email protected]>
Date: Fri, 4 Sep 2026 10:42:36 +0000
Subject: [PATCH] smb: client: avoid leaking refcount when cifs_sb_tlink()
fails

cifs_oplock_break() takes over the reference that cifs_queue_oplock_break() acquired when it queued the work, and drops it with _cifsFileInfo_put() once the break has been processed.

Only in setups with "-o multiuser", cifs_sb_tlink() may fail, at which point cifs_oplock_break() returns without putting the file reference, mirroring the reference leak we already fixed in the companion patch to cifs_queue_oplock_break().

This would trigger a crash due to busy inodes on the next unmount:

  BUG: Dentry ... still in use (1) [unmount of cifs cifs]
  VFS: Busy inodes after unmount of cifs (cifs)

Drop the reference on that path as well. Doing so before the out label mirrors the normal path, which also puts the reference before cifs_done_oplock_break().

Found by Sashiko code review. The failure path was not exercised at runtime.

Fixes e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break")
Assisted-by Kiro:claude-opus-5
fs/smb/client/file.c +4 -1
index d7b0a9512dfa..27b58d907203 100644
@@ -3348,8 +3348,11 @@ void cifs_oplock_break(struct work_struct *work)
 			TASK_UNINTERRUPTIBLE);
 
 	tlink = cifs_sb_tlink(cifs_sb);
-	if (IS_ERR(tlink))
+	if (IS_ERR(tlink)) {
+		/* drop the reference taken when the break was queued */
+		_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
 		goto out;
+	}
 	tcon = tlink_tcon(tlink);
 	server = tcon->ses->server;
 
maintainer
#1 lore raw

PATCH 1/1 smb: client: avoid leaking refcount when cifs_sb_tlink() fails

From: Bjoern Doebel <[email protected]>

[ Upstream commit 23b26f4408ac3f35a482d2e5cf6fc865d4201b71 ]

cifs_oplock_break() takes over the reference that cifs_queue_oplock_break() acquired when it queued the work, and drops it with _cifsFileInfo_put() once the break has been processed.

Only in setups with "-o multiuser", cifs_sb_tlink() may fail, at which point cifs_oplock_break() returns without putting the file reference, mirroring the reference leak we already fixed in the companion patch to cifs_queue_oplock_break().

This would trigger a crash due to busy inodes on the next unmount:

  BUG: Dentry ... still in use (1) [unmount of cifs cifs]
  VFS: Busy inodes after unmount of cifs (cifs)

Drop the reference on that path as well. Doing so before the out label mirrors the normal path, which also puts the reference before cifs_done_oplock_break().

Found by Sashiko code review. The failure path was not exercised at runtime.

Fixes e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break")
Assisted-by Kiro:claude-opus-5
[ Changed the target path from fs/smb/client/file.c to fs/cifs/file.c. ]
---
 fs/cifs/file.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/cifs/file.c +4 -1
index 71f585a41d456..aa740478fe78c 100644
@@ -4886,8 +4886,11 @@ void cifs_oplock_break(struct work_struct *work)
 			TASK_UNINTERRUPTIBLE);
 
 	tlink = cifs_sb_tlink(cifs_sb);
-	if (IS_ERR(tlink))
+	if (IS_ERR(tlink)) {
+		/* drop the reference taken when the break was queued */
+		_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
 		goto out;
+	}
 	tcon = tlink_tcon(tlink);
 	server = tcon->ses->server;
 
Signature · 1 line
2.53.0