Skip to content

Commit fcc2d8c

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: fix to detect corrupted meta ino
It is possible that ino of dirent or orphan inode is corrupted in a fuzzed image, occasionally, if corrupted ino is equal to meta ino: meta_ino, node_ino or compress_ino, caller of f2fs_iget() from below call paths will get meta inode directly, it's not allowed, let's add sanity check to detect such cases. case #1 - recover_dentry - __f2fs_find_entry - f2fs_iget_retry case #2 - recover_orphan_inode - f2fs_iget_retry Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent d80afef commit fcc2d8c

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

fs/f2fs/inode.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ static int do_read_inode(struct inode *inode)
487487
return 0;
488488
}
489489

490+
static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino)
491+
{
492+
return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) ||
493+
ino == F2FS_COMPRESS_INO(sbi);
494+
}
495+
490496
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
491497
{
492498
struct f2fs_sb_info *sbi = F2FS_SB(sb);
@@ -498,16 +504,21 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
498504
return ERR_PTR(-ENOMEM);
499505

500506
if (!(inode->i_state & I_NEW)) {
507+
if (is_meta_ino(sbi, ino)) {
508+
f2fs_err(sbi, "inaccessible inode: %lu, run fsck to repair", ino);
509+
set_sbi_flag(sbi, SBI_NEED_FSCK);
510+
ret = -EFSCORRUPTED;
511+
trace_f2fs_iget_exit(inode, ret);
512+
iput(inode);
513+
return ERR_PTR(ret);
514+
}
515+
501516
trace_f2fs_iget(inode);
502517
return inode;
503518
}
504-
if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi))
505-
goto make_now;
506519

507-
#ifdef CONFIG_F2FS_FS_COMPRESSION
508-
if (ino == F2FS_COMPRESS_INO(sbi))
520+
if (is_meta_ino(sbi, ino))
509521
goto make_now;
510-
#endif
511522

512523
ret = do_read_inode(inode);
513524
if (ret)

0 commit comments

Comments
 (0)