ocfs2: invalidate inode if i_mode is zero after block read
A panic occurs in ocfs2_unlink due to WARN_ON(inode->i_nlink == 0) when handling a corrupted inode with i_mode=0 and i_nlink=0 in memory. This "zombie" inode is created because ocfs2_read_locked_inode proceeds even after ocfs2_validate_inode_block successfully validates a block that structurally looks okay (passes checksum, signature etc.) but contains semantically invalid data (specifically i_mode=0). The current validation function doesn't check for i_mode being zero. This results in an in-memory inode with i_mode=0 being added to the VFS cache, which later triggers the panic during unlink. Prevent this by adding an explicit check for (i_mode == 0, i_nlink == 0, non-orphan) within ocfs2_validate_inode_block. If the check is true, return -EFSCORRUPTED to signal corruption. This causes the caller (ocfs2_read_locked_inode) to invoke make_bad_inode(), correctly preventing the zombie inode from entering the cache. Link: https://lkml.kernel.org/r/20251202224507.53452-2-eraykrdg1@gmail.com Co-developed-by: Albin Babu Varghese <albinbabuvarghese20@gmail.com> Signed-off-by: Albin Babu Varghese <albinbabuvarghese20@gmail.com> Signed-off-by: Ahmet Eray Karadag <eraykrdg1@gmail.com> Reported-by: syzbot+55c40ae8a0e5f3659f2b@syzkaller.appspotmail.com Fixes: https://syzkaller.appspot.com/bug?extid=55c40ae8a0e5f3659f2b Link: https://lore.kernel.org/all/20251022222752.46758-2-eraykrdg1@gmail.com/T/ Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> Cc: David Hunter <david.hunter.linux@gmail.com> Cc: Mark Fasheh <mark@fasheh.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Changwei Ge <gechangwei@live.cn> Cc: Jun Piao <piaojun@huawei.com> Cc: Heming Zhao <heming.zhao@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>master
parent
76b9701a54
commit
7efb45f968
|
|
@ -1461,6 +1461,14 @@ int ocfs2_validate_inode_block(struct super_block *sb,
|
|||
goto bail;
|
||||
}
|
||||
|
||||
if ((!di->i_links_count && !di->i_links_count_hi) || !di->i_mode) {
|
||||
mlog(ML_ERROR, "Invalid dinode #%llu: "
|
||||
"Corrupt state (nlink = %u or mode = %u) detected!\n",
|
||||
(unsigned long long)bh->b_blocknr,
|
||||
ocfs2_read_links_count(di), le16_to_cpu(di->i_mode));
|
||||
rc = -EFSCORRUPTED;
|
||||
goto bail;
|
||||
}
|
||||
/*
|
||||
* Errors after here are fatal.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue