]>
Commit | Line | Data |
---|---|---|
cd033818 SL |
1 | From c72b7d90b9c246380fb910e0162881d472138e77 Mon Sep 17 00:00:00 2001 |
2 | From: Chao Yu <yuchao0@huawei.com> | |
3 | Date: Mon, 15 Apr 2019 15:28:37 +0800 | |
4 | Subject: f2fs: fix to avoid panic in do_recover_data() | |
5 | ||
6 | [ Upstream commit 22d61e286e2d9097dae36f75ed48801056b77cac ] | |
7 | ||
8 | As Jungyeon reported in bugzilla: | |
9 | ||
10 | https://bugzilla.kernel.org/show_bug.cgi?id=203227 | |
11 | ||
12 | - Overview | |
13 | When mounting the attached crafted image, following errors are reported. | |
14 | Additionally, it hangs on sync after trying to mount it. | |
15 | ||
16 | The image is intentionally fuzzed from a normal f2fs image for testing. | |
17 | Compile options for F2FS are as follows. | |
18 | CONFIG_F2FS_FS=y | |
19 | CONFIG_F2FS_STAT_FS=y | |
20 | CONFIG_F2FS_FS_XATTR=y | |
21 | CONFIG_F2FS_FS_POSIX_ACL=y | |
22 | CONFIG_F2FS_CHECK_FS=y | |
23 | ||
24 | - Reproduces | |
25 | mkdir test | |
26 | mount -t f2fs tmp.img test | |
27 | sync | |
28 | ||
29 | - Messages | |
30 | kernel BUG at fs/f2fs/recovery.c:549! | |
31 | RIP: 0010:recover_data+0x167a/0x1780 | |
32 | Call Trace: | |
33 | f2fs_recover_fsync_data+0x613/0x710 | |
34 | f2fs_fill_super+0x1043/0x1aa0 | |
35 | mount_bdev+0x16d/0x1a0 | |
36 | mount_fs+0x4a/0x170 | |
37 | vfs_kern_mount+0x5d/0x100 | |
38 | do_mount+0x200/0xcf0 | |
39 | ksys_mount+0x79/0xc0 | |
40 | __x64_sys_mount+0x1c/0x20 | |
41 | do_syscall_64+0x43/0xf0 | |
42 | entry_SYSCALL_64_after_hwframe+0x44/0xa9 | |
43 | ||
44 | During recovery, if ofs_of_node is inconsistent in between recovered | |
45 | node page and original checkpointed node page, let's just fail recovery | |
46 | instead of making kernel panic. | |
47 | ||
48 | Signed-off-by: Chao Yu <yuchao0@huawei.com> | |
49 | Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> | |
50 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
51 | --- | |
52 | fs/f2fs/recovery.c | 10 +++++++++- | |
53 | 1 file changed, 9 insertions(+), 1 deletion(-) | |
54 | ||
55 | diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c | |
56 | index 2878be3e448f..410354c334d7 100644 | |
57 | --- a/fs/f2fs/recovery.c | |
58 | +++ b/fs/f2fs/recovery.c | |
59 | @@ -413,7 +413,15 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, | |
60 | ||
61 | get_node_info(sbi, dn.nid, &ni); | |
62 | f2fs_bug_on(sbi, ni.ino != ino_of_node(page)); | |
63 | - f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page)); | |
64 | + | |
65 | + if (ofs_of_node(dn.node_page) != ofs_of_node(page)) { | |
66 | + f2fs_msg(sbi->sb, KERN_WARNING, | |
67 | + "Inconsistent ofs_of_node, ino:%lu, ofs:%u, %u", | |
68 | + inode->i_ino, ofs_of_node(dn.node_page), | |
69 | + ofs_of_node(page)); | |
70 | + err = -EFAULT; | |
71 | + goto err; | |
72 | + } | |
73 | ||
74 | for (; start < end; start++, dn.ofs_in_node++) { | |
75 | block_t src, dest; | |
76 | -- | |
77 | 2.20.1 | |
78 |