From: Namjae Jeon linkinjeon@kernel.org
mainline inclusion from mainline-5.15-rc5 commit 64e7875560270b8f669fca9fcd6a689fea56fbeb category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G CVE: NA
Reference: https://git.kernel.org/torvalds/linux/c/64e787556027
-------------------------------
Marios reported kernel oops from fuse driver when ksmbd call mark_inode_dirty(). This patch directly update ->i_ctime after removing mark_inode_ditry() and notify_change will put inode to dirty list.
Cc: Tom Talpey tom@talpey.com Cc: Ronnie Sahlberg ronniesahlberg@gmail.com Cc: Ralph Böhme slow@samba.org Cc: Hyunchul Lee hyc.lee@gmail.com Reported-by: Marios Makassikis mmakassikis@freebox.fr Tested-by: Marios Makassikis mmakassikis@freebox.fr Acked-by: Hyunchul Lee hyc.lee@gmail.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 | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 55d39459437d..ec07cc459f4f 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -5438,7 +5438,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, struct ksmbd_share_config *share) { struct iattr attrs; - struct timespec64 ctime; struct file *filp; struct inode *inode; int rc = 0; @@ -5458,13 +5457,11 @@ static int set_file_basic_info(struct ksmbd_file *fp, attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); }
- if (file_info->ChangeTime) { + attrs.ia_valid |= ATTR_CTIME; + if (file_info->ChangeTime) attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); - ctime = attrs.ia_ctime; - attrs.ia_valid |= ATTR_CTIME; - } else { - ctime = inode->i_ctime; - } + else + attrs.ia_ctime = inode->i_ctime;
if (file_info->LastWriteTime) { attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime); @@ -5509,11 +5506,9 @@ static int set_file_basic_info(struct ksmbd_file *fp, return -EACCES;
inode_lock(inode); + inode->i_ctime = attrs.ia_ctime; + 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;