Skip to content

Commit 7efb45f

Browse files
eraykaradagakpm00
authored andcommitted
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>
1 parent 76b9701 commit 7efb45f

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

fs/ocfs2/inode.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,14 @@ int ocfs2_validate_inode_block(struct super_block *sb,
14611461
goto bail;
14621462
}
14631463

1464+
if ((!di->i_links_count && !di->i_links_count_hi) || !di->i_mode) {
1465+
mlog(ML_ERROR, "Invalid dinode #%llu: "
1466+
"Corrupt state (nlink = %u or mode = %u) detected!\n",
1467+
(unsigned long long)bh->b_blocknr,
1468+
ocfs2_read_links_count(di), le16_to_cpu(di->i_mode));
1469+
rc = -EFSCORRUPTED;
1470+
goto bail;
1471+
}
14641472
/*
14651473
* Errors after here are fatal.
14661474
*/

0 commit comments

Comments
 (0)