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>
This commit is contained in:
parent
d80afefb17
commit
fcc2d8cc96
@ -487,6 +487,12 @@ static int do_read_inode(struct inode *inode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino)
|
||||
{
|
||||
return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) ||
|
||||
ino == F2FS_COMPRESS_INO(sbi);
|
||||
}
|
||||
|
||||
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_SB(sb);
|
||||
@ -498,16 +504,21 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (!(inode->i_state & I_NEW)) {
|
||||
if (is_meta_ino(sbi, ino)) {
|
||||
f2fs_err(sbi, "inaccessible inode: %lu, run fsck to repair", ino);
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
ret = -EFSCORRUPTED;
|
||||
trace_f2fs_iget_exit(inode, ret);
|
||||
iput(inode);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
trace_f2fs_iget(inode);
|
||||
return inode;
|
||||
}
|
||||
if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi))
|
||||
goto make_now;
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
||||
if (ino == F2FS_COMPRESS_INO(sbi))
|
||||
if (is_meta_ino(sbi, ino))
|
||||
goto make_now;
|
||||
#endif
|
||||
|
||||
ret = do_read_inode(inode);
|
||||
if (ret)
|
||||
|
Loading…
x
Reference in New Issue
Block a user