* [PATCH AUTOSEL 5.1 043/186] f2fs: fix to avoid panic in do_recover_data()
[not found] <20190601131653.24205-1-sashal@kernel.org>
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 044/186] f2fs: fix to avoid panic in f2fs_inplace_write_data() Sasha Levin
` (11 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 22d61e286e2d9097dae36f75ed48801056b77cac ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203227
- Overview
When mounting the attached crafted image, following errors are reported.
Additionally, it hangs on sync after trying to mount it.
The image is intentionally fuzzed from a normal f2fs image for testing.
Compile options for F2FS are as follows.
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_CHECK_FS=y
- Reproduces
mkdir test
mount -t f2fs tmp.img test
sync
- Messages
kernel BUG at fs/f2fs/recovery.c:549!
RIP: 0010:recover_data+0x167a/0x1780
Call Trace:
f2fs_recover_fsync_data+0x613/0x710
f2fs_fill_super+0x1043/0x1aa0
mount_bdev+0x16d/0x1a0
mount_fs+0x4a/0x170
vfs_kern_mount+0x5d/0x100
do_mount+0x200/0xcf0
ksys_mount+0x79/0xc0
__x64_sys_mount+0x1c/0x20
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
During recovery, if ofs_of_node is inconsistent in between recovered
node page and original checkpointed node page, let's just fail recovery
instead of making kernel panic.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/recovery.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index e3883db868d81..73338c432e7e4 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -546,7 +546,15 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
goto err;
f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
- f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
+
+ if (ofs_of_node(dn.node_page) != ofs_of_node(page)) {
+ f2fs_msg(sbi->sb, KERN_WARNING,
+ "Inconsistent ofs_of_node, ino:%lu, ofs:%u, %u",
+ inode->i_ino, ofs_of_node(dn.node_page),
+ ofs_of_node(page));
+ err = -EFAULT;
+ goto err;
+ }
for (; start < end; start++, dn.ofs_in_node++) {
block_t src, dest;
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 044/186] f2fs: fix to avoid panic in f2fs_inplace_write_data()
[not found] <20190601131653.24205-1-sashal@kernel.org>
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 043/186] f2fs: fix to avoid panic in do_recover_data() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 045/186] f2fs: fix error path of recovery Sasha Levin
` (10 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 05573d6ccf702df549a7bdeabef31e4753df1a90 ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203239
- Overview
When mounting the attached crafted image and running program, following errors are reported.
Additionally, it hangs on sync after running program.
The image is intentionally fuzzed from a normal f2fs image for testing.
Compile options for F2FS are as follows.
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_CHECK_FS=y
- Reproduces
cc poc_15.c
./run.sh f2fs
sync
- Kernel messages
------------[ cut here ]------------
kernel BUG at fs/f2fs/segment.c:3162!
RIP: 0010:f2fs_inplace_write_data+0x12d/0x160
Call Trace:
f2fs_do_write_data_page+0x3c1/0x820
__write_data_page+0x156/0x720
f2fs_write_cache_pages+0x20d/0x460
f2fs_write_data_pages+0x1b4/0x300
do_writepages+0x15/0x60
__filemap_fdatawrite_range+0x7c/0xb0
file_write_and_wait_range+0x2c/0x80
f2fs_do_sync_file+0x102/0x810
do_fsync+0x33/0x60
__x64_sys_fsync+0xb/0x10
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason is f2fs_inplace_write_data() will trigger kernel panic due
to data block locates in node type segment.
To avoid panic, let's just return error code and set SBI_NEED_FSCK to
give a hint to fsck for latter repairing.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/segment.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index ddfa2eb7ec587..3d6efbfe180fd 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3188,13 +3188,18 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
{
int err;
struct f2fs_sb_info *sbi = fio->sbi;
+ unsigned int segno;
fio->new_blkaddr = fio->old_blkaddr;
/* i/o temperature is needed for passing down write hints */
__get_segment_type(fio);
- f2fs_bug_on(sbi, !IS_DATASEG(get_seg_entry(sbi,
- GET_SEGNO(sbi, fio->new_blkaddr))->type));
+ segno = GET_SEGNO(sbi, fio->new_blkaddr);
+
+ if (!IS_DATASEG(get_seg_entry(sbi, segno)->type)) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ return -EFAULT;
+ }
stat_inc_inplace_blocks(fio->sbi);
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 045/186] f2fs: fix error path of recovery
[not found] <20190601131653.24205-1-sashal@kernel.org>
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 043/186] f2fs: fix to avoid panic in do_recover_data() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 044/186] f2fs: fix to avoid panic in f2fs_inplace_write_data() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 046/186] f2fs: fix to avoid panic in f2fs_remove_inode_page() Sasha Levin
` (9 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 988385795c7f46b231982d54750587f204bd558b ]
There are some places in where we missed to unlock page or unlock page
incorrectly, fix them.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/recovery.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 73338c432e7e4..b14c718139a96 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -325,8 +325,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
break;
}
- if (!is_recoverable_dnode(page))
+ if (!is_recoverable_dnode(page)) {
+ f2fs_put_page(page, 1);
break;
+ }
if (!is_fsync_dnode(page))
goto next;
@@ -338,8 +340,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
if (!check_only &&
IS_INODE(page) && is_dent_dnode(page)) {
err = f2fs_recover_inode_page(sbi, page);
- if (err)
+ if (err) {
+ f2fs_put_page(page, 1);
break;
+ }
quota_inode = true;
}
@@ -355,6 +359,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
err = 0;
goto next;
}
+ f2fs_put_page(page, 1);
break;
}
}
@@ -370,6 +375,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
"%s: detect looped node chain, "
"blkaddr:%u, next:%u",
__func__, blkaddr, next_blkaddr_of_node(page));
+ f2fs_put_page(page, 1);
err = -EINVAL;
break;
}
@@ -380,7 +386,6 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
f2fs_ra_meta_pages_cond(sbi, blkaddr);
}
- f2fs_put_page(page, 1);
return err;
}
@@ -674,8 +679,10 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
*/
if (IS_INODE(page)) {
err = recover_inode(entry->inode, page);
- if (err)
+ if (err) {
+ f2fs_put_page(page, 1);
break;
+ }
}
if (entry->last_dentry == blkaddr) {
err = recover_dentry(entry->inode, page, dir_list);
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 046/186] f2fs: fix to avoid panic in f2fs_remove_inode_page()
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (2 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 045/186] f2fs: fix error path of recovery Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 047/186] f2fs: fix to do sanity check on free nid Sasha Levin
` (8 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Chao Yu, Jaegeuk Kim, Sasha Levin, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 8b6810f8acfe429fde7c7dad4714692cc5f75651 ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203219
- Overview
When mounting the attached crafted image and running program, I got this error.
Additionally, it hangs on sync after running the program.
The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on.
- Reproduces
cc poc_06.c
mkdir test
mount -t f2fs tmp.img test
cp a.out test
cd test
sudo ./a.out
sync
- Messages
kernel BUG at fs/f2fs/node.c:1183!
RIP: 0010:f2fs_remove_inode_page+0x294/0x2d0
Call Trace:
f2fs_evict_inode+0x2a3/0x3a0
evict+0xba/0x180
__dentry_kill+0xbe/0x160
dentry_kill+0x46/0x180
dput+0xbb/0x100
do_renameat2+0x3c9/0x550
__x64_sys_rename+0x17/0x20
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason is f2fs_remove_inode_page() will trigger kernel panic due to
inconsistent i_blocks value of inode.
To avoid panic, let's just print debug message and set SBI_NEED_FSCK to
give a hint to fsck for latter repairing of potential image corruption.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: fix build warning and add unlikely]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/node.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 3f99ab2886955..d45ecef751165 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1179,8 +1179,14 @@ int f2fs_remove_inode_page(struct inode *inode)
f2fs_put_dnode(&dn);
return -EIO;
}
- f2fs_bug_on(F2FS_I_SB(inode),
- inode->i_blocks != 0 && inode->i_blocks != 8);
+
+ if (unlikely(inode->i_blocks != 0 && inode->i_blocks != 8)) {
+ f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
+ "Inconsistent i_blocks, ino:%lu, iblocks:%llu",
+ inode->i_ino,
+ (unsigned long long)inode->i_blocks);
+ set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
+ }
/* will put inode & node pages */
err = truncate_node(&dn);
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 047/186] f2fs: fix to do sanity check on free nid
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (3 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 046/186] f2fs: fix to avoid panic in f2fs_remove_inode_page() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 048/186] f2fs: fix to clear dirty inode in error path of f2fs_iget() Sasha Levin
` (7 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 626bcf2b7ce87211dba565f2bfa7842ba5be5c1b ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203225
- Overview
When mounting the attached crafted image and unmounting it, following errors are reported.
Additionally, it hangs on sync after unmounting.
The image is intentionally fuzzed from a normal f2fs image for testing.
Compile options for F2FS are as follows.
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_CHECK_FS=y
- Reproduces
mkdir test
mount -t f2fs tmp.img test
touch test/t
umount test
sync
- Messages
kernel BUG at fs/f2fs/node.c:3073!
RIP: 0010:f2fs_destroy_node_manager+0x2f0/0x300
Call Trace:
f2fs_put_super+0xf4/0x270
generic_shutdown_super+0x62/0x110
kill_block_super+0x1c/0x50
kill_f2fs_super+0xad/0xd0
deactivate_locked_super+0x35/0x60
cleanup_mnt+0x36/0x70
task_work_run+0x75/0x90
exit_to_usermode_loop+0x93/0xa0
do_syscall_64+0xba/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0010:f2fs_destroy_node_manager+0x2f0/0x300
NAT table is corrupted, so reserved meta/node inode ids were added into
free list incorrectly, during file creation, since reserved id has cached
in inode hash, so it fails the creation and preallocated nid can not be
released later, result in kernel panic.
To fix this issue, let's do nid boundary check during free nid loading.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/node.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d45ecef751165..63bb6134d39ae 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2082,6 +2082,9 @@ static bool add_free_nid(struct f2fs_sb_info *sbi,
if (unlikely(nid == 0))
return false;
+ if (unlikely(f2fs_check_nid_range(sbi, nid)))
+ return false;
+
i = f2fs_kmem_cache_alloc(free_nid_slab, GFP_NOFS);
i->nid = nid;
i->state = FREE_NID;
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 048/186] f2fs: fix to clear dirty inode in error path of f2fs_iget()
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (4 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 047/186] f2fs: fix to do sanity check on free nid Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 049/186] f2fs: fix to avoid panic in dec_valid_block_count() Sasha Levin
` (6 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 546d22f070d64a7b96f57c93333772085d3a5e6d ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203217
- Overview
When mounting the attached crafted image and running program, I got this error.
Additionally, it hangs on sync after running the program.
The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on.
- Reproduces
cc poc_test_05.c
mkdir test
mount -t f2fs tmp.img test
sudo ./a.out
sync
- Messages
kernel BUG at fs/f2fs/inode.c:707!
RIP: 0010:f2fs_evict_inode+0x33f/0x3a0
Call Trace:
evict+0xba/0x180
f2fs_iget+0x598/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_readlinkat+0x56/0x110
__x64_sys_readlink+0x16/0x20
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
During inode loading, __recover_inline_status() can recovery inode status
and set inode dirty, once we failed in following process, it will fail
the check in f2fs_evict_inode, result in trigger BUG_ON().
Let's clear dirty inode in error path of f2fs_iget() to avoid panic.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/inode.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index e7f2e87593156..4edd6f2bb4910 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -488,6 +488,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
return inode;
bad_inode:
+ f2fs_inode_synced(inode);
iget_failed(inode);
trace_f2fs_iget_exit(inode, ret);
return ERR_PTR(ret);
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 049/186] f2fs: fix to avoid panic in dec_valid_block_count()
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (5 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 048/186] f2fs: fix to clear dirty inode in error path of f2fs_iget() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 050/186] f2fs: fix to use inline space only if inline_xattr is enable Sasha Levin
` (5 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Chao Yu, Jaegeuk Kim, Sasha Levin, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 5e159cd349bf3a31fb7e35c23a93308eb30f4f71 ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203209
- Overview
When mounting the attached crafted image and running program, I got this error.
Additionally, it hangs on sync after the this script.
The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on.
- Reproduces
cc poc_01.c
./run.sh f2fs
sync
kernel BUG at fs/f2fs/f2fs.h:1788!
RIP: 0010:f2fs_truncate_data_blocks_range+0x342/0x350
Call Trace:
f2fs_truncate_blocks+0x36d/0x3c0
f2fs_truncate+0x88/0x110
f2fs_setattr+0x3e1/0x460
notify_change+0x2da/0x400
do_truncate+0x6d/0xb0
do_sys_ftruncate+0xf1/0x160
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason is dec_valid_block_count() will trigger kernel panic due to
inconsistent count in between inode.i_blocks and actual block.
To avoid panic, let's just print debug message and set SBI_NEED_FSCK to
give a hint to fsck for latter repairing.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: fix build warning and add unlikely]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/f2fs.h | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 7bea1bc6589fd..74f06f12110f1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1789,6 +1789,7 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
return -ENOSPC;
}
+void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...);
static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode,
block_t count)
@@ -1797,13 +1798,21 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
spin_lock(&sbi->stat_lock);
f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
- f2fs_bug_on(sbi, inode->i_blocks < sectors);
sbi->total_valid_block_count -= (block_t)count;
if (sbi->reserved_blocks &&
sbi->current_reserved_blocks < sbi->reserved_blocks)
sbi->current_reserved_blocks = min(sbi->reserved_blocks,
sbi->current_reserved_blocks + count);
spin_unlock(&sbi->stat_lock);
+ if (unlikely(inode->i_blocks < sectors)) {
+ f2fs_msg(sbi->sb, KERN_WARNING,
+ "Inconsistent i_blocks, ino:%lu, iblocks:%llu, sectors:%llu",
+ inode->i_ino,
+ (unsigned long long)inode->i_blocks,
+ (unsigned long long)sectors);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ return;
+ }
f2fs_i_blocks_write(inode, count, false, true);
}
@@ -2817,7 +2826,6 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type);
-void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...);
static inline void verify_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
{
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 050/186] f2fs: fix to use inline space only if inline_xattr is enable
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (6 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 049/186] f2fs: fix to avoid panic in dec_valid_block_count() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 051/186] f2fs: fix to avoid panic in dec_valid_node_count() Sasha Levin
` (4 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Chao Yu, Jaegeuk Kim, Sasha Levin, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 622927f3b8809206f6da54a6a7ed4df1a7770fce ]
With below mkfs and mount option:
MKFS_OPTIONS -- -O extra_attr -O project_quota -O inode_checksum -O flexible_inline_xattr -O inode_crtime -f
MOUNT_OPTIONS -- -o noinline_xattr
We may miss xattr data with below testcase:
- mkdir dir
- setfattr -n "user.name" -v 0 dir
- for ((i = 0; i < 190; i++)) do touch dir/$i; done
- umount
- mount
- getfattr -n "user.name" dir
user.name: No such attribute
The root cause is that we persist xattr data into reserved inline xattr
space, even if inline_xattr is not enable in inline directory inode, after
inline dentry conversion, reserved space no longer exists, so that xattr
data missed.
Let's use inline xattr space only if inline_xattr flag is set on inode
to fix this iusse.
Fixes: 6afc662e68b5 ("f2fs: support flexible inline xattr size")
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/f2fs.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 74f06f12110f1..10240fbdd396d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2579,7 +2579,9 @@ static inline void *inline_xattr_addr(struct inode *inode, struct page *page)
static inline int inline_xattr_size(struct inode *inode)
{
- return get_inline_xattr_addrs(inode) * sizeof(__le32);
+ if (f2fs_has_inline_xattr(inode))
+ return get_inline_xattr_addrs(inode) * sizeof(__le32);
+ return 0;
}
static inline int f2fs_has_inline_data(struct inode *inode)
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 051/186] f2fs: fix to avoid panic in dec_valid_node_count()
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (7 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 050/186] f2fs: fix to use inline space only if inline_xattr is enable Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 052/186] f2fs: fix to do sanity check on valid block count of segment Sasha Levin
` (3 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit ea6d7e72fea49402aa445345aade7a26b81732e3 ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203213
- Overview
When mounting the attached crafted image and running program, I got this error.
Additionally, it hangs on sync after running the this script.
The image is intentionally fuzzed from a normal f2fs image for testing and I enabled option CONFIG_F2FS_CHECK_FS on.
- Reproduces
mkdir test
mount -t f2fs tmp.img test
cp a.out test
cd test
sudo ./a.out
sync
kernel BUG at fs/f2fs/f2fs.h:2012!
RIP: 0010:truncate_node+0x2c9/0x2e0
Call Trace:
f2fs_truncate_xattr_node+0xa1/0x130
f2fs_remove_inode_page+0x82/0x2d0
f2fs_evict_inode+0x2a3/0x3a0
evict+0xba/0x180
__dentry_kill+0xbe/0x160
dentry_kill+0x46/0x180
dput+0xbb/0x100
do_renameat2+0x3c9/0x550
__x64_sys_rename+0x17/0x20
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason is dec_valid_node_count() will trigger kernel panic due to
inconsistent count in between inode.i_blocks and actual block.
To avoid panic, let's just print debug message and set SBI_NEED_FSCK to
give a hint to fsck for latter repairing.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: fix build warning and add unlikely]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/f2fs.h | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 10240fbdd396d..e2cf567dcbd7c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2029,7 +2029,6 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
f2fs_bug_on(sbi, !sbi->total_valid_block_count);
f2fs_bug_on(sbi, !sbi->total_valid_node_count);
- f2fs_bug_on(sbi, !is_inode && !inode->i_blocks);
sbi->total_valid_node_count--;
sbi->total_valid_block_count--;
@@ -2039,10 +2038,19 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
spin_unlock(&sbi->stat_lock);
- if (is_inode)
+ if (is_inode) {
dquot_free_inode(inode);
- else
+ } else {
+ if (unlikely(inode->i_blocks == 0)) {
+ f2fs_msg(sbi->sb, KERN_WARNING,
+ "Inconsistent i_blocks, ino:%lu, iblocks:%llu",
+ inode->i_ino,
+ (unsigned long long)inode->i_blocks);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ return;
+ }
f2fs_i_blocks_write(inode, 1, false, true);
+ }
}
static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi)
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 052/186] f2fs: fix to do sanity check on valid block count of segment
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (8 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 051/186] f2fs: fix to avoid panic in dec_valid_node_count() Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 053/186] f2fs: fix to avoid deadloop in foreground GC Sasha Levin
` (2 subsequent siblings)
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit e95bcdb2fefa129f37bd9035af1d234ca92ee4ef ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203233
- Overview
When mounting the attached crafted image and running program, following errors are reported.
Additionally, it hangs on sync after running program.
The image is intentionally fuzzed from a normal f2fs image for testing.
Compile options for F2FS are as follows.
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_CHECK_FS=y
- Reproduces
cc poc_13.c
mkdir test
mount -t f2fs tmp.img test
cp a.out test
cd test
sudo ./a.out
sync
- Kernel messages
F2FS-fs (sdb): Bitmap was wrongly set, blk:4608
kernel BUG at fs/f2fs/segment.c:2102!
RIP: 0010:update_sit_entry+0x394/0x410
Call Trace:
f2fs_allocate_data_block+0x16f/0x660
do_write_page+0x62/0x170
f2fs_do_write_node_page+0x33/0xa0
__write_node_page+0x270/0x4e0
f2fs_sync_node_pages+0x5df/0x670
f2fs_write_checkpoint+0x372/0x1400
f2fs_sync_fs+0xa3/0x130
f2fs_do_sync_file+0x1a6/0x810
do_fsync+0x33/0x60
__x64_sys_fsync+0xb/0x10
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
sit.vblocks and sum valid block count in sit.valid_map may be
inconsistent, segment w/ zero vblocks will be treated as free
segment, while allocating in free segment, we may allocate a
free block, if its bitmap is valid previously, it can cause
kernel crash due to bitmap verification failure.
Anyway, to avoid further serious metadata inconsistence and
corruption, it is necessary and worth to detect SIT
inconsistence. So let's enable check_block_count() to verify
vblocks and valid_map all the time rather than do it only
CONFIG_F2FS_CHECK_FS is enabled.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/segment.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 5c7ed0442d6e2..6f48e07632792 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -672,7 +672,6 @@ static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr)
static inline int check_block_count(struct f2fs_sb_info *sbi,
int segno, struct f2fs_sit_entry *raw_sit)
{
-#ifdef CONFIG_F2FS_CHECK_FS
bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false;
int valid_blocks = 0;
int cur_pos = 0, next_pos;
@@ -699,7 +698,7 @@ static inline int check_block_count(struct f2fs_sb_info *sbi,
set_sbi_flag(sbi, SBI_NEED_FSCK);
return -EINVAL;
}
-#endif
+
/* check segment usage, and check boundary of a given segment number */
if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
|| segno > TOTAL_SEGS(sbi) - 1)) {
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 053/186] f2fs: fix to avoid deadloop in foreground GC
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (9 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 052/186] f2fs: fix to do sanity check on valid block count of segment Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 054/186] f2fs: fix to retrieve inline xattr space Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 055/186] f2fs: fix to do checksum even if inode page is uptodate Sasha Levin
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Chao Yu, Jaegeuk Kim, Sasha Levin, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 793ab1c8a792f8bccd7ae4c5be02bd275410b3af ]
As Jungyeon reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=203211
- Overview
When mounting the attached crafted image and making a new file, I got this error and the error messages keep repeating.
The image is intentionally fuzzed from a normal f2fs image for testing and I run with option CONFIG_F2FS_CHECK_FS on.
- Reproduces
mkdir test
mount -t f2fs tmp.img test
cd test
touch t
- Messages
[ 58.820451] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.821485] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.822530] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.823571] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.824616] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.825640] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.826663] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.827698] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.828719] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.829759] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.830783] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.831828] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.832869] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.833888] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.834945] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.835996] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.837028] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.838051] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.839072] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.840100] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.841147] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.842186] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.843214] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.844267] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.845282] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.846305] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
[ 58.847341] F2FS-fs (sdb): Inconsistent segment (1) type [1, 0] in SSA and SIT
... (repeating)
During GC, if segment type stored in SSA and SIT is inconsistent, we just
skip migrating current segment directly, since we need to know the exact
type to decide the migration function we use.
So in foreground GC, we will easily run into a infinite loop as we may
select the same victim segment which has inconsistent type due to greedy
policy. In order to end up this, we choose to shutdown filesystem. For
backgrond GC, we need to do that as well, so that we can avoid latter
potential infinite looped foreground GC.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/gc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index ab764bd106de1..a66a8752e5f65 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1175,6 +1175,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
"type [%d, %d] in SSA and SIT",
segno, type, GET_SUM_TYPE((&sum->footer)));
set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_stop_checkpoint(sbi, false);
goto skip;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 054/186] f2fs: fix to retrieve inline xattr space
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (10 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 053/186] f2fs: fix to avoid deadloop in foreground GC Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 055/186] f2fs: fix to do checksum even if inode page is uptodate Sasha Levin
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit 45a746881576977f85504c21a75547f10c5c0a8e ]
With below mkfs and mount option, generic/339 of fstest will report that
scratch image becomes corrupted.
MKFS_OPTIONS -- -O extra_attr -O project_quota -O inode_checksum -O flexible_inline_xattr -O inode_crtime -f /dev/zram1
MOUNT_OPTIONS -- -o acl,user_xattr -o discard,noinline_xattr /dev/zram1 /mnt/scratch_f2fs
[ASSERT] (f2fs_check_dirent_position:1315) --> Wrong position of dirent pino:1970, name: (...)
level:8, dir_level:0, pgofs:951, correct range:[900, 901]
In old kernel, inline data and directory always reserved 200 bytes in
inode layout, even if inline_xattr is disabled, then new kernel tries
to retrieve that space for non-inline xattr inode, but for inline dentry,
its layout size should be fixed, so we just keep that reserved space.
But the problem here is that, after inline dentry conversion, inline
dentry layout no longer exists, if we still reserve inline xattr space,
after dents updates, there will be a hole in inline xattr space, which
can break hierarchy hash directory structure.
This patch fixes this issue by retrieving inline xattr space after
inline dentry conversion.
Fixes: 6afc662e68b5 ("f2fs: support flexible inline xattr size")
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/inline.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index bb6a152310ef4..404d2462a0fe6 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -420,6 +420,14 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY);
+ /*
+ * should retrieve reserved space which was used to keep
+ * inline_dentry's structure for backward compatibility.
+ */
+ if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) &&
+ !f2fs_has_inline_xattr(dir))
+ F2FS_I(dir)->i_inline_xattr_size = 0;
+
f2fs_i_depth_write(dir, 1);
if (i_size_read(dir) < PAGE_SIZE)
f2fs_i_size_write(dir, PAGE_SIZE);
@@ -501,6 +509,15 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY);
+
+ /*
+ * should retrieve reserved space which was used to keep
+ * inline_dentry's structure for backward compatibility.
+ */
+ if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) &&
+ !f2fs_has_inline_xattr(dir))
+ F2FS_I(dir)->i_inline_xattr_size = 0;
+
kvfree(backup_dentry);
return 0;
recover:
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH AUTOSEL 5.1 055/186] f2fs: fix to do checksum even if inode page is uptodate
[not found] <20190601131653.24205-1-sashal@kernel.org>
` (11 preceding siblings ...)
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 054/186] f2fs: fix to retrieve inline xattr space Sasha Levin
@ 2019-06-01 13:14 ` Sasha Levin
12 siblings, 0 replies; 13+ messages in thread
From: Sasha Levin @ 2019-06-01 13:14 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Jaegeuk Kim, linux-f2fs-devel
From: Chao Yu <yuchao0@huawei.com>
[ Upstream commit b42b179bda9ff11075a6fc2bac4d9e400513679a ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/inode.c | 4 ++--
fs/f2fs/node.c | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 4edd6f2bb4910..b53952a15ffae 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -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;
}
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 63bb6134d39ae..e29d5f6735ae9 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -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;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2019-06-01 13:19 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20190601131653.24205-1-sashal@kernel.org>
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 043/186] f2fs: fix to avoid panic in do_recover_data() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 044/186] f2fs: fix to avoid panic in f2fs_inplace_write_data() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 045/186] f2fs: fix error path of recovery Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 046/186] f2fs: fix to avoid panic in f2fs_remove_inode_page() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 047/186] f2fs: fix to do sanity check on free nid Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 048/186] f2fs: fix to clear dirty inode in error path of f2fs_iget() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 049/186] f2fs: fix to avoid panic in dec_valid_block_count() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 050/186] f2fs: fix to use inline space only if inline_xattr is enable Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 051/186] f2fs: fix to avoid panic in dec_valid_node_count() Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 052/186] f2fs: fix to do sanity check on valid block count of segment Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 053/186] f2fs: fix to avoid deadloop in foreground GC Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 054/186] f2fs: fix to retrieve inline xattr space Sasha Levin
2019-06-01 13:14 ` [PATCH AUTOSEL 5.1 055/186] f2fs: fix to do checksum even if inode page is uptodate Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).