Re: [PATCH v2] ocfs2: validate global bitmap cl_bpc before resize

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

On 8/4/26 2:44 PM, ZhengYuan Huang wrote:
> [BUG]
> A corrupted global bitmap inode can make online group extension scan past
> the end of a group descriptor bitmap:
> 
> BUG: KASAN: use-after-free in _find_next_bit+0xef/0x120 lib/find_bit.c:157
> Read of size 8 at addr ffff888021b52000 by task syz.0.34/409
> Call Trace:
>  ...
>  _find_next_bit+0xef/0x120 lib/find_bit.c:157
>  find_next_bit include/linux/find.h:73 [inline]
>  find_next_bit_le include/linux/find.h:518 [inline]
>  ocfs2_find_max_contig_free_bits+0x53/0xb0 fs/ocfs2/suballoc.c:1292
>  ocfs2_update_last_group_and_inode fs/ocfs2/resize.c:127 [inline]
>  ocfs2_group_extend+0x83e/0x1ae0 fs/ocfs2/resize.c:350
>  ocfs2_ioctl+0x175/0x6e0 fs/ocfs2/ioctl.c:869
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:597 [inline]
>  __se_sys_ioctl fs/ioctl.c:583 [inline]
>  __x64_sys_ioctl+0x197/0x1e0 fs/ioctl.c:583
>  ...
> 
> [CAUSE]
> ocfs2_group_extend() consumes the global bitmap dinode's cl_bpc value in
> resize arithmetic. The existing inode validation checked cl_bpc only for
> non-global chain allocators, so a corrupted global bitmap value could reach
> the resize path. With cl_bpc changed from 1 to 51457, extending by seven
> clusters wraps the u16 bit count and grows a 2048-bit group to 34567 bits,
> exceeding its 32256-bit bitmap capacity.
> 
> [FIX]
> Validate cl_bpc in ocfs2_validate_inode_block() for every chain allocator,
> including the global bitmap, against the value derived from the
> filesystem's cluster and block sizes. This rejects the corrupted dinode
> when it is read and removes the resize-local check that incorrectly assumed
> cl_bpc is always one. The resize path still uses the validated value for
> its arithmetic.
> 
> Fixes: d659072f7368 ("[PATCH 1/2] ocfs2: Add group extend for online resize")
> Signed-off-by: ZhengYuan Huang <[email protected]>
> ---
> v2:
> - Derive the expected cl_bpc from the filesystem block and cluster sizes.
> - Extend the existing inode-block validation to cover the global bitmap.
> - Remove the resize-local hardcoded cl_bpc check.
> ---
> ---
>  fs/ocfs2/inode.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
> index 41db7dd39ed9..0e1f9ae0eb73 100644
> --- a/fs/ocfs2/inode.c
> +++ b/fs/ocfs2/inode.c
> @@ -1683,12 +1683,11 @@ int ocfs2_validate_inode_block(struct super_block *sb,
>  					 le16_to_cpu(cl->cl_next_free_rec));
>  			goto bail;
>  		}
> -		if (OCFS2_SB(sb)->bitmap_blkno &&
> -		    OCFS2_SB(sb)->bitmap_blkno != le64_to_cpu(di->i_blkno) &&
> -		    le16_to_cpu(cl->cl_bpc) != bpc) {
> -			rc = ocfs2_error(sb, "Invalid dinode %llu: bits per cluster %u\n",
> +		if (le16_to_cpu(cl->cl_bpc) != bpc) {

For global bitmap inode, its cl_bpc is legitimately 1.
So this is wrong and will break mount during fill super.
NAK.

Thanks,
Joseph

> +			rc = ocfs2_error(sb,
> +					 "Invalid dinode %llu: bits per cluster %u (expected %u)\n",
>  					 (unsigned long long)bh->b_blocknr,
> -					 le16_to_cpu(cl->cl_bpc));
> +					 le16_to_cpu(cl->cl_bpc), bpc);
>  			goto bail;
>  		}
>  	}
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.