]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: (bcachefs) fix not detecting large superblocks
authorColin Gillespie <colin@cgillespie.xyz>
Wed, 9 Aug 2023 08:28:07 +0000 (18:28 +1000)
committerThomas Weißschuh <thomas@t-8ch.de>
Fri, 22 Sep 2023 18:47:02 +0000 (20:47 +0200)
Probing does not detect bcachefs filesystems with a superblock larger
than 4KiB. Bcachefs superblocks grow in size and can become much larger
than this.

Increase the superblock maximum size limit to 1MiB.

Validate the superblock isn't larger than the maximum size defined in
the superblocks layout section.

(cherry picked from commit 48d573797797650d96456979797c0155d58f61cb)

libblkid/src/superblocks/bcache.c

index 40e702d75d09498b05ea8fcea82e4b515b1783a7..2368770427ead4b822e8504c4576e2ef7e844b8c 100644 (file)
@@ -102,6 +102,15 @@ union bcachefs_sb_csum {
        uint8_t raw[16];
 } __attribute__((packed));
 
+struct bcachefs_sb_layout {
+       uint8_t         magic[16];
+       uint8_t         layout_type;
+       uint8_t         sb_max_size_bits;
+       uint8_t         nr_superblocks;
+       uint8_t         pad[5];
+       uint64_t        sb_offset[61];
+} __attribute__((packed));
+
 struct bcachefs_super_block {
        union bcachefs_sb_csum  csum;
        uint16_t        version;
@@ -123,7 +132,7 @@ struct bcachefs_super_block {
        uint64_t        flags[8];
        uint64_t        features[2];
        uint64_t        compat[2];
-       uint8_t         layout[512];
+       struct bcachefs_sb_layout layout;
        struct bcachefs_sb_field _start[];
 }  __attribute__((packed));
 
@@ -143,7 +152,7 @@ struct bcachefs_super_block {
 /* granularity of offset and length fields within superblock */
 #define BCACHEFS_SECTOR_SIZE   512
 /* maximum superblock size */
-#define BCACHEFS_SB_MAX_SIZE   4096
+#define BCACHEFS_SB_MAX_SIZE   0x100000
 /* fields offset within super block */
 #define BCACHEFS_SB_FIELDS_OFF offsetof(struct bcachefs_super_block, _start)
 /* tag value for members field */
@@ -302,6 +311,9 @@ static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
                return BLKID_PROBE_NONE;
 
        sb_size = BCACHEFS_SB_FIELDS_OFF + BYTES(bcs);
+       if (sb_size > BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits)
+               return BLKID_PROBE_NONE;
+
        if (sb_size > BCACHEFS_SB_MAX_SIZE)
                return BLKID_PROBE_NONE;