| From: Mike Rapoport <rppt@linux.ibm.com> |
| Subject: secretmem: fix unhandled fault in truncate |
| Date: Thu, 14 Jul 2022 12:13:37 +0300 |
| |
| v3: use invalidate_lock rather than inode_lock |
| v2: use inode_lock_shared() rather than add a new rw_sem to secretmem |
| |
| Link: https://lkml.kernel.org/r/20220714091337.412297-1-rppt@kernel.org |
| Reported-by: syzbot+9bd2b7adbd34b30b87e4@syzkaller.appspotmail.com |
| Signed-off-by: Mike Rapoport <rppt@linux.ibm.com> |
| Suggested-by: Eric Biggers <ebiggers@kernel.org> |
| Reviewed-by: Axel Rasmussen <axelrasmussen@google.com> |
| Cc: Hillf Danton <hdanton@sina.com> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/secretmem.c | 16 ++++++++++++---- |
| 1 file changed, 12 insertions(+), 4 deletions(-) |
| |
| --- a/mm/secretmem.c~secretmem-fix-unhandled-fault-in-truncate-v3 |
| +++ a/mm/secretmem.c |
| @@ -61,7 +61,7 @@ static vm_fault_t secretmem_fault(struct |
| if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode)) |
| return vmf_error(-EINVAL); |
| |
| - inode_lock_shared(inode); |
| + filemap_invalidate_lock_shared(mapping); |
| |
| retry: |
| page = find_lock_page(mapping, offset); |
| @@ -104,7 +104,7 @@ retry: |
| ret = VM_FAULT_LOCKED; |
| |
| out: |
| - inode_unlock_shared(inode); |
| + filemap_invalidate_unlock_shared(mapping); |
| return ret; |
| } |
| |
| @@ -173,12 +173,20 @@ static int secretmem_setattr(struct user |
| struct dentry *dentry, struct iattr *iattr) |
| { |
| struct inode *inode = d_inode(dentry); |
| + struct address_space *mapping = inode->i_mapping; |
| unsigned int ia_valid = iattr->ia_valid; |
| + int ret; |
| + |
| + filemap_invalidate_lock(mapping); |
| |
| if ((ia_valid & ATTR_SIZE) && inode->i_size) |
| - return -EINVAL; |
| + ret = -EINVAL; |
| + else |
| + ret = simple_setattr(mnt_userns, dentry, iattr); |
| |
| - return simple_setattr(mnt_userns, dentry, iattr); |
| + filemap_invalidate_unlock(mapping); |
| + |
| + return ret; |
| } |
| |
| static const struct inode_operations secretmem_iops = { |
| _ |