[lvc-project] [PATCH 2/2] ocfs2: validate cl_bpc in allocator inodes to prevent divide-by-zero
Dmitry Antipov
dmantipov at yandex.ru
Thu Oct 30 11:34:13 MSK 2025
On 10/30/25 11:11 AM, Dmitry Antipov wrote:
> This is what happens in ocfs2_initialize_super(), and, IIUC, the global (cluster) bitmap
> is the only dinode which can have cl_bpc set to 1. So what about the following:
>
> diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
> index 709afbfd1f9f..a8138c150d81 100644
> --- a/fs/ocfs2/inode.c
> +++ b/fs/ocfs2/inode.c
> @@ -1520,7 +1520,18 @@ int ocfs2_validate_inode_block(struct super_block *sb,
> le16_to_cpu(cl->cl_next_free_rec));
> goto bail;
> }
> - if (le16_to_cpu(cl->cl_bpc) != bpc) {
> +
> + if (OCFS2_SB(sb)->bitmap_blkno == 0 && le16_to_cpu(cl->cl_bpc) == 1)
> + /* This dinode represents a cluster bitmap, and we're reading
> + * it for the first time from ocfs2_initialize_super().
> + */
> + ;
> + else if (OCFS2_SB(sb)->bitmap_blkno == le64_to_cpu(di->i_blkno))
> + /* This dinode represents a cluster bitmap, and we can
> + * recognize it by using the known block number.
> + */
> + ;
> + else if (le16_to_cpu(cl->cl_bpc) != bpc) {
> rc = ocfs2_error(sb, "Invalid dinode %llu: bits per cluster %u\n",
> (unsigned long long)bh->b_blocknr,
> le16_to_cpu(cl->cl_bpc));
Blah. This one looks much better:
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 709afbfd1f9f..a6f419f0dd39 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -1520,7 +1520,11 @@ int ocfs2_validate_inode_block(struct super_block *sb,
le16_to_cpu(cl->cl_next_free_rec));
goto bail;
}
- if (le16_to_cpu(cl->cl_bpc) != bpc) {
+ if ((le16_to_cpu(cl->cl_bpc) == 1) &&
+ (le16_to_cpu(cl->cl_cpg) == ocfs2_group_bitmap_size(sb, 0, 0) * 8))
+ /* This dinode represents the valid cluster bitmap. */
+ ;
+ else if (le16_to_cpu(cl->cl_bpc) != bpc) {
rc = ocfs2_error(sb, "Invalid dinode %llu: bits per cluster %u\n",
(unsigned long long)bh->b_blocknr,
le16_to_cpu(cl->cl_bpc));
Dmitry
More information about the lvc-project
mailing list