[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