Re: [PATCH v2] ocfs2: validate inline dir size during inode reads
From: ZhengYuan Huang
Date: Thu Apr 16 2026 - 00:35:39 EST
On Mon, Apr 13, 2026 at 3:19 PM Heming Zhao <heming.zhao@xxxxxxxx> wrote:
>
> On Fri, Apr 10, 2026 at 07:32:29PM +0800, ZhengYuan Huang wrote:
> > [BUG]
> > A crafted inline-data directory can store i_size larger than id_count.
> > Once such a dinode is instantiated, readdir walks past data->id_data
> > and KASAN reports:
> >
> > BUG: KASAN: use-after-free in ocfs2_check_dir_entry.isra.0+0x31f/0x370 fs/ocfs2/dir.c:305
> > Read of size 2 at addr ffff8880088f0008 by task syz.0.1936/4656
> > Call Trace:
> > ...
> > ocfs2_check_dir_entry.isra.0+0x31f/0x370 fs/ocfs2/dir.c:305
> > ocfs2_dir_foreach_blk_id+0x203/0xa70 fs/ocfs2/dir.c:1805
> > ocfs2_dir_foreach_blk fs/ocfs2/dir.c:1933 [inline]
> > ocfs2_readdir+0x4ba/0x520 fs/ocfs2/dir.c:1977
> > wrap_directory_iterator+0x9c/0xe0 fs/readdir.c:65
> > shared_ocfs2_readdir+0x29/0x40 fs/ocfs2/file.c:2822
> > iterate_dir+0x276/0x9e0 fs/readdir.c:108
> > __do_sys_getdents64 fs/readdir.c:410 [inline]
> > __se_sys_getdents64 fs/readdir.c:396 [inline]
> > __x64_sys_getdents64+0x143/0x2a0 fs/readdir.c:396
> > ...
> >
> > [CAUSE]
> > The inline-dir invariant i_size <= id_count is never validated when a
> > dinode is read. ocfs2_validate_inode_block() accepts the corrupted
> > metadata, then ocfs2_populate_inode() or ocfs2_refresh_inode() copies
> > that unchecked on-disk i_size into inode->i_size.
> >
> > JBD2-managed buffers can also bypass ocfs2_validate_inode_block(), so
> > the same unchecked size can still reach ocfs2_populate_inode() and
> > ocfs2_refresh_inode() through those read paths.
> >
> > [FIX]
> > Introduce a shared helper that validates inline directory i_size
> > against id_count. Call it from ocfs2_validate_inode_block() so corrupt
> > inline-dir dinodes are rejected in the cold metadata-read path, and add
> > matching guards in ocfs2_read_locked_inode() and ocfs2_inode_lock_update()
> > for the JBD2-managed buffer paths that skip the validator.
> >
> > This blocks the corrupted metadata before it reaches VFS inode state
> > and keeps the hot readdir path unchanged.
> >
> > Fixes: 23193e513d1c ("ocfs2: Read support for directories with inline data")
> > Signed-off-by: ZhengYuan Huang <gality369@xxxxxxxxx>
> > ---
> > v2:
> > - Move the validation from ocfs2_dir_foreach_blk_id() to inode read paths
> > - Add JBD2-managed buffer guards in ocfs2_read_locked_inode() and ocfs2_inode_lock_update()
> > - Reword the changelog to describe unchecked on-disk i_size rather than corrupted in-memory state
>
> ocfs2_validate_inode_block() already has the logic to check inline-data size.
> You can find it by searching for:
> "if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {"
>
> - Heming
My mistake.
I reran my reproducer on the latest upstream kernel and could not
reproduce the issue there, so based on the current repro results, it
appears that the bug has already been fixed.
Although code inspection still suggests that JBD-managed buffers may
bypass that validation path, my current reproducer has not been able
to trigger the bug on the latest kernel. We will continue testing to
determine whether there is still a reachable path here or whether the
issue has in fact already been fixed by another change.
Thanks,
ZhengYuan Huang