From: Christian Brauner christian.brauner@ubuntu.com
mainline inclusion from mainline-5.15-rc1 commit db7fb6fe3d7a8eb05f2b74c6252771c9362f3b74 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G CVE: NA
Reference: https://git.kernel.org/torvalds/linux/c/db7fb6fe3d7a
-------------------------------
Permission checking and copying over ownership information is the task of the underlying filesystem not ksmbd. The order is also wrong here. This modifies the inode before notify_change(). If notify_change() fails this will have changed ownership nonetheless. All of this is unnecessary though since the underlying filesystem's ->setattr handler will do all this (if required) by itself.
Cc: Steve French stfrench@microsoft.com Cc: Christoph Hellwig hch@infradead.org Cc: Namjae Jeon namjae.jeon@samsung.com Cc: Hyunchul Lee hyc.lee@gmail.com Cc: Sergey Senozhatsky senozhatsky@chromium.org Cc: linux-cifs@vger.kernel.org Signed-off-by: Christian Brauner christian.brauner@ubuntu.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org 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/ksmbd/smb2pdu.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-)
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index d51b436af523..445fa0843232 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -5395,7 +5395,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, { struct smb2_file_all_info *file_info; struct iattr attrs; - struct iattr temp_attrs; + struct timespec64 ctime; struct file *filp; struct inode *inode; int rc; @@ -5417,11 +5417,11 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, }
if (file_info->ChangeTime) { - temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); - attrs.ia_ctime = temp_attrs.ia_ctime; + attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); + ctime = attrs.ia_ctime; attrs.ia_valid |= ATTR_CTIME; } else { - temp_attrs.ia_ctime = inode->i_ctime; + ctime = inode->i_ctime; }
if (file_info->LastWriteTime) { @@ -5459,13 +5459,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, rc = 0; }
- /* - * HACK : set ctime here to avoid ctime changed - * when file_info->ChangeTime is zero. - */ - attrs.ia_ctime = temp_attrs.ia_ctime; - attrs.ia_valid |= ATTR_CTIME; - if (attrs.ia_valid) { struct dentry *dentry = filp->f_path.dentry; struct inode *inode = d_inode(dentry); @@ -5473,14 +5466,12 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EACCES;
- rc = setattr_prepare(dentry, &attrs); - if (rc) - return -EINVAL; - inode_lock(inode); - setattr_copy(inode, &attrs); - attrs.ia_valid &= ~ATTR_CTIME; rc = notify_change(dentry, &attrs, NULL); + if (!rc) { + inode->i_ctime = ctime; + mark_inode_dirty(inode); + } inode_unlock(inode); } return rc;