]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ocfs2: invalidate inode if i_mode is zero after block read
authorAhmet Eray Karadag <eraykrdg1@gmail.com>
Tue, 2 Dec 2025 22:45:08 +0000 (01:45 +0300)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 11 Dec 2025 00:07:43 +0000 (16:07 -0800)
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>
fs/ocfs2/inode.c

index 5986d90b007e41d116d1ccad17d4922c075c055c..ae938fb7c5213cc6e6f9152438085925c3be9488 100644 (file)
@@ -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.
         */