[PATCH OLK-5.10] smb: client: fix race with concurrent opens in rename(2)
From: Paulo Alcantara <pc@manguebit.org> mainline inclusion from mainline-v6.17-rc1 commit d84291fc7453df7881a970716f8256273aca5747 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/8680 CVE: CVE-2025-39825 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Besides sending the rename request to the server, the rename process also involves closing any deferred close, waiting for outstanding I/O to complete as well as marking all existing open handles as deleted to prevent them from deferring closes, which increases the race window for potential concurrent opens on the target file. Fix this by unhashing the dentry in advance to prevent any concurrent opens on the target. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: David Howells <dhowells@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com> Conflicts: fs/cifs/inode.c fs/smb/client/inode.c [Code mvoe to fs/smb/client] Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/cifs/inode.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b11a919b9cab..3f33cdd14b1a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2069,6 +2069,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; struct cifs_tcon *tcon; + bool rehash = false; FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; unsigned int xid; @@ -2078,6 +2079,18 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, return -EINVAL; cifs_sb = CIFS_SB(source_dir->i_sb); + + /* + * Prevent any concurrent opens on the target by unhashing the dentry. + * VFS already unhashes the target when renaming directories. + */ + if (d_is_positive(target_dentry) && !d_is_dir(target_dentry)) { + if (!d_unhashed(target_dentry)) { + d_drop(target_dentry); + rehash = true; + } + } + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -2103,6 +2116,8 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); + if (!rc) + rehash = false; /* * No-replace is the natural behavior for CIFS, so skip unlink hacks. @@ -2159,6 +2174,8 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, goto cifs_rename_exit; rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); + if (!rc) + rehash = false; } /* force revalidate to go get info when needed */ @@ -2168,6 +2185,8 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, target_dir->i_mtime = current_time(source_dir); cifs_rename_exit: + if (rehash) + d_rehash(target_dentry); kfree(info_buf_source); kfree(from_name); kfree(to_name); -- 2.39.2
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/20066 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/IG3... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/20066 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/IG3...
participants (2)
-
Long Li -
patchwork bot