Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: fix to avoid accessing uninitialized field of inode page in is_alive()

If inode is newly created, inode page may not synchronize with inode cache,
so fields like .i_inline or .i_extra_isize could be wrong, in below call
path, we may access such wrong fields, result in failing to migrate valid
target block.

Thread A Thread B
- f2fs_create
- f2fs_add_link
- f2fs_add_dentry
- f2fs_init_inode_metadata
- f2fs_add_inline_entry
- f2fs_new_inode_page
- f2fs_put_page
: inode page wasn't updated with inode cache
- gc_data_segment
- is_alive
- f2fs_get_node_page
- datablock_addr
- offset_in_addr
: access uninitialized fields

Fixes: 7a2af766af15 ("f2fs: enhance on-disk inode structure scalability")
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Chao Yu and committed by
Jaegeuk Kim
98194030 743b620c

+10
+5
fs/f2fs/dir.c
··· 682 682 683 683 if (inode) { 684 684 f2fs_i_pino_write(inode, dir->i_ino); 685 + 686 + /* synchronize inode page's data from inode cache */ 687 + if (is_inode_flag_set(inode, FI_NEW_INODE)) 688 + f2fs_update_inode(inode, page); 689 + 685 690 f2fs_put_page(page, 1); 686 691 } 687 692
+5
fs/f2fs/inline.c
··· 589 589 /* we don't need to mark_inode_dirty now */ 590 590 if (inode) { 591 591 f2fs_i_pino_write(inode, dir->i_ino); 592 + 593 + /* synchronize inode page's data from inode cache */ 594 + if (is_inode_flag_set(inode, FI_NEW_INODE)) 595 + f2fs_update_inode(inode, page); 596 + 592 597 f2fs_put_page(page, 1); 593 598 } 594 599