]>
Commit | Line | Data |
---|---|---|
37554d48 SL |
1 | From 407f50197c6ac5d5943d549ce439aef0ad5caac8 Mon Sep 17 00:00:00 2001 |
2 | From: Chao Yu <yuchao0@huawei.com> | |
3 | Date: Mon, 15 Apr 2019 15:28:33 +0800 | |
4 | Subject: f2fs: fix to clear dirty inode in error path of f2fs_iget() | |
5 | ||
6 | [ Upstream commit 546d22f070d64a7b96f57c93333772085d3a5e6d ] | |
7 | ||
8 | As Jungyeon reported in bugzilla: | |
9 | ||
10 | https://bugzilla.kernel.org/show_bug.cgi?id=203217 | |
11 | ||
12 | - Overview | |
13 | When mounting the attached crafted image and running program, I got this error. | |
14 | Additionally, it hangs on sync after running the program. | |
15 | ||
16 | The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on. | |
17 | ||
18 | - Reproduces | |
19 | cc poc_test_05.c | |
20 | mkdir test | |
21 | mount -t f2fs tmp.img test | |
22 | sudo ./a.out | |
23 | sync | |
24 | ||
25 | - Messages | |
26 | kernel BUG at fs/f2fs/inode.c:707! | |
27 | RIP: 0010:f2fs_evict_inode+0x33f/0x3a0 | |
28 | Call Trace: | |
29 | evict+0xba/0x180 | |
30 | f2fs_iget+0x598/0xdf0 | |
31 | f2fs_lookup+0x136/0x320 | |
32 | __lookup_slow+0x92/0x140 | |
33 | lookup_slow+0x30/0x50 | |
34 | walk_component+0x1c1/0x350 | |
35 | path_lookupat+0x62/0x200 | |
36 | filename_lookup+0xb3/0x1a0 | |
37 | do_readlinkat+0x56/0x110 | |
38 | __x64_sys_readlink+0x16/0x20 | |
39 | do_syscall_64+0x43/0xf0 | |
40 | entry_SYSCALL_64_after_hwframe+0x44/0xa9 | |
41 | ||
42 | During inode loading, __recover_inline_status() can recovery inode status | |
43 | and set inode dirty, once we failed in following process, it will fail | |
44 | the check in f2fs_evict_inode, result in trigger BUG_ON(). | |
45 | ||
46 | Let's clear dirty inode in error path of f2fs_iget() to avoid 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/inode.c | 1 + | |
53 | 1 file changed, 1 insertion(+) | |
54 | ||
55 | diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c | |
56 | index dd608b819a3c..fae9570e6860 100644 | |
57 | --- a/fs/f2fs/inode.c | |
58 | +++ b/fs/f2fs/inode.c | |
59 | @@ -476,6 +476,7 @@ make_now: | |
60 | return inode; | |
61 | ||
62 | bad_inode: | |
63 | + f2fs_inode_synced(inode); | |
64 | iget_failed(inode); | |
65 | trace_f2fs_iget_exit(inode, ret); | |
66 | return ERR_PTR(ret); | |
67 | -- | |
68 | 2.20.1 | |
69 |