f2fs: fix to avoid mmap vs set_compress_option case
authorChao Yu <chao@kernel.org>
Thu, 6 Jul 2023 02:06:14 +0000 (10:06 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Sep 2023 07:42:55 +0000 (09:42 +0200)
commit4d7e804f49a0b19ec4d5dd8ec6465088091be851
tree12abd7364f962ef43ee9ecdedb8f180b1234e9e7
parent3a2cf76cfb8f6edba79a4fe1bdce3a6d41821e98
f2fs: fix to avoid mmap vs set_compress_option case

[ Upstream commit b5ab3276eb69cacf44ecfb11b2bfab73096ff4e4 ]

Compression option in inode should not be changed after they have
been used, however, it may happen in below race case:

Thread A Thread B
- f2fs_ioc_set_compress_option
 - check f2fs_is_mmap_file()
 - check get_dirty_pages()
 - check F2FS_HAS_BLOCKS()
- f2fs_file_mmap
 - set_inode_flag(FI_MMAP_FILE)
- fault
 - do_page_mkwrite
  - f2fs_vm_page_mkwrite
  - f2fs_get_block_locked
 - fault_dirty_shared_page
  - set_page_dirty
 - update i_compress_algorithm
 - update i_log_cluster_size
 - update i_cluster_size

Avoid such race condition by covering f2fs_file_mmap() w/ i_sem lock,
meanwhile add mmap file check condition in f2fs_may_compress() as well.

Fixes: e1e8debec656 ("f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/f2fs/f2fs.h
fs/f2fs/file.c