Re: [PATCH v2] ocfs2: don't BUG_ON an invalid journal dinode

Joseph Qi <[email protected]>
Newsgroups dev.linux.lists.ocfs2-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

On 5/12/26 10:41 AM, ZhengYuan Huang wrote:
> [BUG]
> A fuzzed OCFS2 image can corrupt the current slot journal dinode while
> mount is still in progress. The mount path first reports the invalid
> journal block and then crashes in shutdown:
> 
> kernel BUG at fs/ocfs2/journal.c:1034!
> Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> RIP: 0010:ocfs2_journal_toggle_dirty+0x2d6/0x340 fs/ocfs2/journal.c:1034
> Call Trace:
>  ocfs2_journal_shutdown+0x414/0xc30 fs/ocfs2/journal.c:1116
>  ocfs2_mount_volume fs/ocfs2/super.c:1785 [inline]
>  ocfs2_fill_super+0x30a9/0x3cd0 fs/ocfs2/super.c:1083
>  get_tree_bdev_flags+0x38b/0x640 fs/super.c:1698
>  get_tree_bdev+0x24/0x40 fs/super.c:1721
>  ocfs2_get_tree+0x21/0x30 fs/ocfs2/super.c:1184
>  vfs_get_tree+0x9a/0x370 fs/super.c:1758
>  fc_mount fs/namespace.c:1199 [inline]
>  do_new_mount_fc fs/namespace.c:3642 [inline]
>  do_new_mount fs/namespace.c:3718 [inline]
>  path_mount+0x5b8/0x1ea0 fs/namespace.c:4028
>  do_mount fs/namespace.c:4041 [inline]
>  __do_sys_mount fs/namespace.c:4229 [inline]
>  __se_sys_mount fs/namespace.c:4206 [inline]
>  __x64_sys_mount+0x282/0x320 fs/namespace.c:4206
>  ...
> 
> [CAUSE]
> ocfs2_journal_toggle_dirty() used to return -EIO when journal->j_bh no
> longer contained a valid dinode, because the startup and shutdown paths
> already handled that failure. Commit 10995aa2451a
> ("ocfs2: Morph the haphazard OCFS2_IS_VALID_DINODE() checks.") changed
> the check to a BUG_ON() under the assumption that the journal dinode had
> already been validated. That turns an unexpected invalid journal dinode
> during mount teardown into a kernel crash instead of a normal mount
> failure.
> 
> [FIX]
> Replace the BUG_ON() with WARN_ON() and return -EIO. This keeps the
> invariant warning for debugging, but restores the original behavior of
> failing startup or shutdown cleanly instead of panicking the kernel.
> 
> Fixes: 10995aa2451a ("ocfs2: Morph the haphazard OCFS2_IS_VALID_DINODE() checks.")
> Signed-off-by: ZhengYuan Huang <[email protected]>

The 'Fixes' tag may not needed. Other looks fine to me.
Reviewed-by: Joseph Qi <[email protected]>
> ---
> v2:
> - Drop the full dinode revalidation and use WARN_ON plus -EIO instead
> - Rework the rationale around the historical BUG_ON conversion
> - Add a Fixes tag for the commit that replaced the old error return
> ---
>  fs/ocfs2/journal.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
> index f9bf3bac085d..fc54cc798ce3 100644
> --- a/fs/ocfs2/journal.c
> +++ b/fs/ocfs2/journal.c
> @@ -1022,11 +1022,8 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
>  	struct ocfs2_dinode *fe;
>  
>  	fe = (struct ocfs2_dinode *)bh->b_data;
> -
> -	/* The journal bh on the osb always comes from ocfs2_journal_init()
> -	 * and was validated there inside ocfs2_inode_lock_full().  It's a
> -	 * code bug if we mess it up. */
> -	BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
> +	if (WARN_ON(!OCFS2_IS_VALID_DINODE(fe)))
> +		return -EIO;
>  
>  	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
>  	if (dirty)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.