lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 25 Dec 2020 16:53:04 +0800 From: Chao Yu <yuchao0@...wei.com> To: <jaegeuk@...nel.org> CC: <linux-f2fs-devel@...ts.sourceforge.net>, <linux-kernel@...r.kernel.org>, <chao@...nel.org>, Chao Yu <yuchao0@...wei.com> Subject: [PATCH] f2fs: fix to keep isolation of atomic write ThreadA ThreadB - f2fs_ioc_start_atomic_write - write - f2fs_ioc_commit_atomic_write - f2fs_commit_inmem_pages - f2fs_drop_inmem_pages - f2fs_drop_inmem_pages - __revoke_inmem_pages - f2fs_vm_page_mkwrite - set_page_dirty - tag ATOMIC_WRITTEN_PAGE and add page to inmem_pages list - clear_inode_flag(FI_ATOMIC_FILE) - f2fs_vm_page_mkwrite - set_page_dirty - f2fs_update_dirty_page - f2fs_trace_pid - tag inmem page private to pid - truncate - f2fs_invalidate_page - set page->mapping to NULL then it will cause panic once we access page->mapping The root cause is we missed to keep isolation of atomic write in the case of commit_atomic_write vs mkwrite, let commit_atomic_write helds i_mmap_sem lock to avoid this issue. Signed-off-by: Chao Yu <yuchao0@...wei.com> --- fs/f2fs/file.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 22a0101538c0..1ff5fc10e1fa 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2094,10 +2094,12 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) goto err_out; } + down_write(&F2FS_I(inode)->i_mmap_sem); + if (f2fs_is_atomic_file(inode)) { ret = f2fs_commit_inmem_pages(inode); if (ret) - goto err_out; + goto up_write; ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); if (!ret) @@ -2105,6 +2107,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) } else { ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false); } +up_write: + up_write(&F2FS_I(inode)->i_mmap_sem); err_out: if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) { clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST); -- 2.29.2
Powered by blists - more mailing lists