]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/f2fs-fix-to-avoid-panic-in-f2fs_inplace_write_data.patch
Linux 5.1.10
[thirdparty/kernel/stable-queue.git] / queue-4.19 / f2fs-fix-to-avoid-panic-in-f2fs_inplace_write_data.patch
1 From 93ab4f1ac925435b36cd9c3f653efca61e517da0 Mon Sep 17 00:00:00 2001
2 From: Chao Yu <yuchao0@huawei.com>
3 Date: Mon, 15 Apr 2019 15:30:52 +0800
4 Subject: f2fs: fix to avoid panic in f2fs_inplace_write_data()
5
6 [ Upstream commit 05573d6ccf702df549a7bdeabef31e4753df1a90 ]
7
8 As Jungyeon reported in bugzilla:
9
10 https://bugzilla.kernel.org/show_bug.cgi?id=203239
11
12 - Overview
13 When mounting the attached crafted image and running program, following errors are reported.
14 Additionally, it hangs on sync after running program.
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 cc poc_15.c
26 ./run.sh f2fs
27 sync
28
29 - Kernel messages
30 ------------[ cut here ]------------
31 kernel BUG at fs/f2fs/segment.c:3162!
32 RIP: 0010:f2fs_inplace_write_data+0x12d/0x160
33 Call Trace:
34 f2fs_do_write_data_page+0x3c1/0x820
35 __write_data_page+0x156/0x720
36 f2fs_write_cache_pages+0x20d/0x460
37 f2fs_write_data_pages+0x1b4/0x300
38 do_writepages+0x15/0x60
39 __filemap_fdatawrite_range+0x7c/0xb0
40 file_write_and_wait_range+0x2c/0x80
41 f2fs_do_sync_file+0x102/0x810
42 do_fsync+0x33/0x60
43 __x64_sys_fsync+0xb/0x10
44 do_syscall_64+0x43/0xf0
45 entry_SYSCALL_64_after_hwframe+0x44/0xa9
46
47 The reason is f2fs_inplace_write_data() will trigger kernel panic due
48 to data block locates in node type segment.
49
50 To avoid panic, let's just return error code and set SBI_NEED_FSCK to
51 give a hint to fsck for latter repairing.
52
53 Signed-off-by: Chao Yu <yuchao0@huawei.com>
54 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
55 Signed-off-by: Sasha Levin <sashal@kernel.org>
56 ---
57 fs/f2fs/segment.c | 9 +++++++--
58 1 file changed, 7 insertions(+), 2 deletions(-)
59
60 diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
61 index 03fa2c4d3d79..8fc3edb6760c 100644
62 --- a/fs/f2fs/segment.c
63 +++ b/fs/f2fs/segment.c
64 @@ -3069,13 +3069,18 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
65 {
66 int err;
67 struct f2fs_sb_info *sbi = fio->sbi;
68 + unsigned int segno;
69
70 fio->new_blkaddr = fio->old_blkaddr;
71 /* i/o temperature is needed for passing down write hints */
72 __get_segment_type(fio);
73
74 - f2fs_bug_on(sbi, !IS_DATASEG(get_seg_entry(sbi,
75 - GET_SEGNO(sbi, fio->new_blkaddr))->type));
76 + segno = GET_SEGNO(sbi, fio->new_blkaddr);
77 +
78 + if (!IS_DATASEG(get_seg_entry(sbi, segno)->type)) {
79 + set_sbi_flag(sbi, SBI_NEED_FSCK);
80 + return -EFAULT;
81 + }
82
83 stat_inc_inplace_blocks(fio->sbi);
84
85 --
86 2.20.1
87