f2fs: fix to do checksum even if inode page is uptodate
As Jungyeon reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203221 - Overview When mounting the attached crafted image and running program, this error is reported. The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on. - Reproduces cc poc_07.c mkdir test mount -t f2fs tmp.img test cp a.out test cd test sudo ./a.out - Messages kernel BUG at fs/f2fs/node.c:1279! RIP: 0010:read_node_page+0xcf/0xf0 Call Trace: __get_node_page+0x6b/0x2f0 f2fs_iget+0x8f/0xdf0 f2fs_lookup+0x136/0x320 __lookup_slow+0x92/0x140 lookup_slow+0x30/0x50 walk_component+0x1c1/0x350 path_lookupat+0x62/0x200 filename_lookup+0xb3/0x1a0 do_fchmodat+0x3e/0xa0 __x64_sys_chmod+0x12/0x20 do_syscall_64+0x43/0xf0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 On below paths, we can have opportunity to readahead inode page - gc_node_segment -> f2fs_ra_node_page - gc_data_segment -> f2fs_ra_node_page - f2fs_fill_dentries -> f2fs_ra_node_page Unlike synchronized read, on readahead path, we can set page uptodate before verifying page's checksum, then read_node_page() will trigger kernel panic once it encounters a uptodated page w/ incorrect checksum. So considering readahead scenario, we have to do checksum each time when loading inode page even if it is uptodated. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
8b6810f8ac
commit
b42b179bda
|
@ -177,8 +177,8 @@ bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page)
|
|||
|
||||
if (provided != calculated)
|
||||
f2fs_msg(sbi->sb, KERN_WARNING,
|
||||
"checksum invalid, ino = %x, %x vs. %x",
|
||||
ino_of_node(page), provided, calculated);
|
||||
"checksum invalid, nid = %lu, ino_of_node = %x, %x vs. %x",
|
||||
page->index, ino_of_node(page), provided, calculated);
|
||||
|
||||
return provided == calculated;
|
||||
}
|
||||
|
|
|
@ -1281,9 +1281,10 @@ static int read_node_page(struct page *page, int op_flags)
|
|||
int err;
|
||||
|
||||
if (PageUptodate(page)) {
|
||||
#ifdef CONFIG_F2FS_CHECK_FS
|
||||
f2fs_bug_on(sbi, !f2fs_inode_chksum_verify(sbi, page));
|
||||
#endif
|
||||
if (!f2fs_inode_chksum_verify(sbi, page)) {
|
||||
ClearPageUptodate(page);
|
||||
return -EBADMSG;
|
||||
}
|
||||
return LOCKED_PAGE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue