Re: [PATCH 1/2] ocfs2: validate orphan slot during inode read

From: Joseph Qi

Date: Tue Aug 04 2026 - 03:26:29 EST




On 8/3/26 11:00 AM, ZhengYuan Huang wrote:
> [BUG]
> A corrupted dinode with OCFS2_ORPHANED_FL can carry an
> i_orphaned_slot outside the mounted filesystem slot range.
> ocfs2_wipe_inode() uses it to index osb_orphan_wipes before looking
> up the orphan directory, causing an out-of-bounds memory access.
>
> BUG: KASAN: slab-use-after-free in ocfs2_get_system_file_inode+0x780/0x820 fs/ocfs2/sysfile.c:102
> Read of size 8 at addr ffff88800b767c00 by task kworker/u8:3/85
> Call Trace:
> ...
> ocfs2_get_system_file_inode+0x780/0x820 fs/ocfs2/sysfile.c:102
> ocfs2_wipe_inode+0x292/0xf70 fs/ocfs2/inode.c:840
> ocfs2_delete_inode fs/ocfs2/inode.c:1155 [inline]
> ocfs2_evict_inode+0x6c9/0x1170 fs/ocfs2/inode.c:1295
> evict+0x38e/0x8f0 fs/inode.c:810
> iput_final fs/inode.c:1914 [inline]
> iput fs/inode.c:1966 [inline]
> iput+0x55b/0x8b0 fs/inode.c:1926
> ocfs2_recover_orphans+0x610/0xe40 fs/ocfs2/journal.c:2374
> ocfs2_complete_recovery+0x5af/0xd00 fs/ocfs2/journal.c:1373
> ...
>
> [CAUSE]
> ocfs2_validate_inode_block() validates i_suballoc_slot but leaves
> the active ordinary orphan slot unchecked. Downstream consumers
> assume that the value is smaller than osb->max_slots.
>
> [FIX]
> Reject an active i_orphaned_slot outside the slot range during
> dinode validation, before the inode reaches orphan wipe processing.
>
> Fixes: b4df6ed8db0c ("[PATCH] ocfs2: fix orphan recovery deadlock")
> Signed-off-by: ZhengYuan Huang <gality369@xxxxxxxxx>

Reviewed-by: Joseph Qi <joseph.qi@xxxxxxxxxxxxxxxxx>
> ---
> fs/ocfs2/inode.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
> index 41db7dd39ed9..358ab3535366 100644
> --- a/fs/ocfs2/inode.c
> +++ b/fs/ocfs2/inode.c
> @@ -1528,6 +1528,14 @@ int ocfs2_validate_inode_block(struct super_block *sb,
> goto bail;
> }
>
> + if ((le32_to_cpu(di->i_flags) & OCFS2_ORPHANED_FL) &&
> + le16_to_cpu(di->i_orphaned_slot) >= OCFS2_SB(sb)->max_slots) {
> + rc = ocfs2_error(sb, "Invalid dinode %llu: orphaned slot %u\n",
> + (unsigned long long)bh->b_blocknr,
> + le16_to_cpu(di->i_orphaned_slot));
> + goto bail;
> + }
> +
> /*
> * Reject dinodes whose i_mode does not name one of the seven
> * canonical POSIX file types. ocfs2_populate_inode() copies