From: Thomas Weißschuh Date: Sun, 27 Nov 2022 19:47:04 +0000 (+0100) Subject: libblkid: bcachefs: validate device fields X-Git-Tag: v2.39-rc1~156 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ba5c3e7387719dffed0179424c39b62c4a5c7246;p=thirdparty%2Futil-linux.git libblkid: bcachefs: validate device fields Signed-off-by: Thomas Weißschuh --- diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c index 128635bc94..323e0f0106 100644 --- a/libblkid/src/superblocks/bcache.c +++ b/libblkid/src/superblocks/bcache.c @@ -34,9 +34,14 @@ struct bcachefs_sb_field { } __attribute__((packed)); struct bcachefs_sb_member { - uint8_t uuid[16]; - uint8_t padding[40]; -} __attribute__((packed)); + uint8_t uuid[16]; + uint64_t nbuckets; + uint16_t first_bucket; + uint16_t bucket_size; + uint32_t pad; + uint64_t last_mount; + uint64_t flags[2]; +} __attribute__((packed)); struct bcachefs_sb_field_members { struct bcachefs_sb_field field; @@ -123,15 +128,34 @@ static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag) return BLKID_PROBE_OK; } -static void probe_bcachefs_sb_members(blkid_probe pr, struct bcachefs_sb_field *field, - uint8_t dev_idx, unsigned char *sb_end) +static unsigned char *member_field_end( + const struct bcachefs_sb_field_members *field, size_t idx) +{ + return (unsigned char *) &field->members + (sizeof(*field->members) * idx); +} + +static void probe_bcachefs_sb_members(blkid_probe pr, + const struct bcachefs_super_block *bcs, + const struct bcachefs_sb_field *field, + uint8_t dev_idx, + const unsigned char *sb_end) { struct bcachefs_sb_field_members *members = (struct bcachefs_sb_field_members *) field; - if ((unsigned char *) &members->members + (sizeof(*members->members) * dev_idx) > sb_end) + if (member_field_end(members, dev_idx) > sb_end) return; blkid_probe_set_uuid_as(pr, members->members[dev_idx].uuid, "UUID_SUB"); + + if (member_field_end(members, bcs->nr_devices - 1) > sb_end) + return; + + uint64_t sectors = 0; + for (uint8_t i = 0; i < bcs->nr_devices; i++) { + struct bcachefs_sb_member *member = &members->members[i]; + sectors += le64_to_cpu(member->nbuckets) * le16_to_cpu(member->bucket_size); + } + blkid_probe_set_fssize(pr, sectors * BCACHEFS_SECTOR_SIZE); } static void probe_bcachefs_sb_fields(blkid_probe pr, const struct blkid_idmag *mag, @@ -158,7 +182,7 @@ static void probe_bcachefs_sb_fields(blkid_probe pr, const struct blkid_idmag *m break; if (type == BCACHEFS_SB_FIELD_TYPE_MEMBERS) - probe_bcachefs_sb_members(pr, field, bcs->dev_idx, sb_end); + probe_bcachefs_sb_members(pr, bcs, field, bcs->dev_idx, sb_end); field_addr += BYTES(field); } @@ -176,11 +200,15 @@ static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag) if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / BCACHEFS_SECTOR_SIZE) return BLKID_PROBE_NONE; + if (bcs->nr_devices == 0 || bcs->dev_idx >= bcs->nr_devices) + return BLKID_PROBE_NONE; + blkid_probe_set_uuid(pr, bcs->user_uuid); blkid_probe_set_label(pr, bcs->label, sizeof(bcs->label)); blkid_probe_sprintf_version(pr, "%d", le16_to_cpu(bcs->version)); blocksize = le16_to_cpu(bcs->block_size); blkid_probe_set_block_size(pr, blocksize * BCACHEFS_SECTOR_SIZE); + blkid_probe_set_fsblocksize(pr, blocksize * BCACHEFS_SECTOR_SIZE); blkid_probe_set_wiper(pr, 0, BCACHE_SB_OFF); probe_bcachefs_sb_fields(pr, mag, bcs); diff --git a/tests/expected/blkid/low-probe-bcachefs b/tests/expected/blkid/low-probe-bcachefs index 7b1226a1cb..70fddbee8e 100644 --- a/tests/expected/blkid/low-probe-bcachefs +++ b/tests/expected/blkid/low-probe-bcachefs @@ -1,4 +1,6 @@ ID_FS_BLOCK_SIZE=4096 +ID_FS_FSBLOCKSIZE=4096 +ID_FS_FSSIZE=4194304 ID_FS_LABEL=Label ID_FS_LABEL_ENC=Label ID_FS_TYPE=bcachefs diff --git a/tests/expected/blkid/low-probe-bcachefs-2 b/tests/expected/blkid/low-probe-bcachefs-2 index ea817b260f..7f053b2c1a 100644 --- a/tests/expected/blkid/low-probe-bcachefs-2 +++ b/tests/expected/blkid/low-probe-bcachefs-2 @@ -1,4 +1,6 @@ ID_FS_BLOCK_SIZE=512 +ID_FS_FSBLOCKSIZE=512 +ID_FS_FSSIZE=4194304 ID_FS_LABEL=Label ID_FS_LABEL_ENC=Label ID_FS_TYPE=bcachefs