From: Namjae Jeon namjae.jeon@samsung.com
mainline inclusion from mainline-5.15-rc1 commit 4b637fc18902600dfe722f9b1a45950bfc8bc7b5 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G CVE: NA
Reference: https://git.kernel.org/torvalds/linux/c/4b637fc18902
-------------------------------
Factor out a self-contained helper to find sub file/dir in use.
Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Namjae Jeon namjae.jeon@samsung.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com --- fs/cifsd/vfs.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index 1ba3fd95ba6b..ca4c6c020a8e 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -687,6 +687,29 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, return err; }
+static int ksmbd_validate_entry_in_use(struct dentry *src_dent) +{ + struct dentry *dst_dent; + + spin_lock(&src_dent->d_lock); + list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { + struct ksmbd_file *child_fp; + + if (d_really_is_negative(dst_dent)) + continue; + + child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); + if (child_fp) { + spin_unlock(&src_dent->d_lock); + ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); + return -EACCES; + } + } + spin_unlock(&src_dent->d_lock); + + return 0; +} + static int __ksmbd_vfs_rename(struct ksmbd_work *work, struct dentry *src_dent_parent, struct dentry *src_dent, @@ -698,21 +721,9 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, int err;
if (!work->tcon->posix_extensions) { - spin_lock(&src_dent->d_lock); - list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { - struct ksmbd_file *child_fp; - - if (d_really_is_negative(dst_dent)) - continue; - - child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); - if (child_fp) { - spin_unlock(&src_dent->d_lock); - ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); - return -EACCES; - } - } - spin_unlock(&src_dent->d_lock); + err = ksmbd_validate_entry_in_use(src_dent); + if (err) + return err; }
if (d_really_is_negative(src_dent_parent))