This is a note to let you know that I've just added the patch titled SMB3: EBADF/EIO errors in rename/open caused by race condition in smb2_compound_op to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: smb3-ebadf-eio-errors-in-rename-open-caused-by-race-condition-in-smb2_compound_op.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 0a55cf74ffb5d004b93647e4389096880ce37d6b Mon Sep 17 00:00:00 2001 From: Steve French <stfrench@xxxxxxxxxxxxx> Date: Thu, 12 May 2022 10:18:00 -0500 Subject: SMB3: EBADF/EIO errors in rename/open caused by race condition in smb2_compound_op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Steve French <stfrench@xxxxxxxxxxxxx> commit 0a55cf74ffb5d004b93647e4389096880ce37d6b upstream. There is a race condition in smb2_compound_op: after_close: num_rqst++; if (cfile) { cifsFileInfo_put(cfile); // sends SMB2_CLOSE to the server cfile = NULL; This is triggered by smb2_query_path_info operation that happens during revalidate_dentry. In smb2_query_path_info, get_readable_path is called to load the cfile, increasing the reference counter. If in the meantime, this reference becomes the very last, this call to cifsFileInfo_put(cfile) will trigger a SMB2_CLOSE request sent to the server just before sending this compound request – and so then the compound request fails either with EBADF/EIO depending on the timing at the server, because the handle is already closed. In the first scenario, the race seems to be happening between smb2_query_path_info triggered by the rename operation, and between “cleanup” of asynchronous writes – while fsync(fd) likely waits for the asynchronous writes to complete, releasing the writeback structures can happen after the close(fd) call. So the EBADF/EIO errors will pop up if the timing is such that: 1) There are still outstanding references after close(fd) in the writeback structures 2) smb2_query_path_info successfully fetches the cfile, increasing the refcounter by 1 3) All writeback structures release the same cfile, reducing refcounter to 1 4) smb2_compound_op is called with that cfile In the second scenario, the race seems to be similar – here open triggers the smb2_query_path_info operation, and if all other threads in the meantime decrease the refcounter to 1 similarly to the first scenario, again SMB2_CLOSE will be sent to the server just before issuing the compound request. This case is harder to reproduce. See https://bugzilla.samba.org/show_bug.cgi?id=15051 Cc: stable@xxxxxxxxxxxxxxx Fixes: 8de9e86c67ba ("cifs: create a helper to find a writeable handle by path name") Signed-off-by: Ondrej Hubsch <ohubsch@xxxxxxxxxxxxxxx> Reviewed-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx> Reviewed-by: Paulo Alcantara (SUSE) <pc@xxxxxx> Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/cifs/smb2inode.c | 2 -- 1 file changed, 2 deletions(-) --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -358,8 +358,6 @@ smb2_compound_op(const unsigned int xid, num_rqst++; if (cfile) { - cifsFileInfo_put(cfile); - cfile = NULL; rc = compound_send_recv(xid, ses, server, flags, num_rqst - 2, &rqst[1], &resp_buftype[1], Patches currently in stable-queue which might be from stfrench@xxxxxxxxxxxxx are queue-5.15/smb3-check-for-null-tcon.patch queue-5.15/cifs-when-extending-a-file-with-falloc-we-should-make-files-not-sparse.patch queue-5.15/ksmbd-fix-outstanding-credits-related-bugs.patch queue-5.15/smb3-ebadf-eio-errors-in-rename-open-caused-by-race-condition-in-smb2_compound_op.patch queue-5.15/cifs-fix-potential-double-free-during-failed-mount.patch