diff options
Diffstat (limited to 'libblkid/src/superblocks')
53 files changed, 443 insertions, 327 deletions
diff --git a/libblkid/src/superblocks/adaptec_raid.c b/libblkid/src/superblocks/adaptec_raid.c index 5fc5fc4..813d30e 100644 --- a/libblkid/src/superblocks/adaptec_raid.c +++ b/libblkid/src/superblocks/adaptec_raid.c @@ -79,9 +79,6 @@ static int probe_adraid(blkid_probe pr, uint64_t off; struct adaptec_metadata *ad; - if (pr->size < 0x10000) - return BLKID_PROBE_NONE; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return BLKID_PROBE_NONE; @@ -109,6 +106,7 @@ static int probe_adraid(blkid_probe pr, const struct blkid_idinfo adraid_idinfo = { .name = "adaptec_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_adraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/apfs.c b/libblkid/src/superblocks/apfs.c index 048423a..b7f09f3 100644 --- a/libblkid/src/superblocks/apfs.c +++ b/libblkid/src/superblocks/apfs.c @@ -39,7 +39,7 @@ struct apfs_super_block { static int probe_apfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct apfs_super_block *sb; + const struct apfs_super_block *sb; sb = blkid_probe_get_sb(pr, mag, struct apfs_super_block); if (!sb) diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c index d3afc41..47d9060 100644 --- a/libblkid/src/superblocks/bcache.c +++ b/libblkid/src/superblocks/bcache.c @@ -189,7 +189,7 @@ static int bcache_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag, return 0; /* up to the end of bcs->d[] */ - csummed_size = offsetof(typeof(*bcs), d) + + csummed_size = offsetof(__typeof__(*bcs), d) + sizeof(bcs->d[0]) * le16_to_cpu(bcs->keys); csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size); csum = ul_crc64_we(csummed + BCACHE_SB_CSUMMED_START, @@ -199,7 +199,7 @@ static int bcache_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag, static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag) { - struct bcache_super_block *bcs; + const struct bcache_super_block *bcs; bcs = blkid_probe_get_sb(pr, mag, struct bcache_super_block); if (!bcs) @@ -211,9 +211,18 @@ static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag) if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512) return BLKID_PROBE_NONE; + if (blkid_probe_sprintf_version(pr, "%"PRIu64, le64_to_cpu(bcs->version)) < 0) + return BLKID_PROBE_NONE; + if (blkid_probe_set_uuid(pr, bcs->uuid) < 0) return BLKID_PROBE_NONE; + if (blkid_probe_set_label(pr, bcs->label, sizeof(bcs->label)) < 0) + return BLKID_PROBE_NONE; + + if (blkid_probe_set_block_size(pr, le16_to_cpu(bcs->block_size) * 512)) + return BLKID_PROBE_NONE; + blkid_probe_set_wiper(pr, 0, BCACHE_SB_OFF); return BLKID_PROBE_OK; @@ -229,7 +238,7 @@ static void probe_bcachefs_sb_members(blkid_probe pr, uint64_t sectors = 0; uint8_t i; - if (BYTES(field) != offsetof(typeof(*members), members[bcs->nr_devices])) + if (BYTES(field) != offsetof(__typeof__(*members), members[bcs->nr_devices])) return; blkid_probe_set_uuid_as(pr, members->members[dev_idx].uuid, "UUID_SUB"); @@ -249,7 +258,7 @@ static void probe_bcachefs_sb_disk_groups(blkid_probe pr, struct bcachefs_sb_field_disk_groups *disk_groups = (struct bcachefs_sb_field_disk_groups *) field; - if (BYTES(field) != offsetof(typeof(*disk_groups), disk_groups[bcs->nr_devices])) + if (BYTES(field) != offsetof(__typeof__(*disk_groups), disk_groups[bcs->nr_devices])) return; blkid_probe_set_id_label(pr, "LABEL_SUB", @@ -257,7 +266,7 @@ static void probe_bcachefs_sb_disk_groups(blkid_probe pr, sizeof(disk_groups->disk_groups[dev_idx].label)); } -static int is_within_range(void *start, uint64_t size, void *end) +static int is_within_range(const void *start, uint64_t size, const void *end) { ptrdiff_t diff; @@ -269,9 +278,9 @@ static int is_within_range(void *start, uint64_t size, void *end) } static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super_block *bcs, - unsigned char *sb_start, unsigned char *sb_end) + const unsigned char *sb_start, const unsigned char *sb_end) { - unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF; + const unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF; while (1) { struct bcachefs_sb_field *field = (struct bcachefs_sb_field *) field_addr; @@ -304,10 +313,10 @@ static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super } static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_super_block *bcs, - unsigned char *sb, unsigned char *sb_end) + const unsigned char *sb, const unsigned char *sb_end) { uint8_t checksum_type = be64_to_cpu(bcs->flags[0]) >> 58; - unsigned char *checksummed_data_start = sb + sizeof(bcs->csum); + const unsigned char *checksummed_data_start = sb + sizeof(bcs->csum); size_t checksummed_data_size = sb_end - checksummed_data_start; switch (checksum_type) { @@ -333,16 +342,17 @@ static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_supe static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag) { - struct bcachefs_super_block *bcs; - unsigned char *sb, *sb_end; - uint64_t sb_size, blocksize; + const struct bcachefs_super_block *bcs; + const unsigned char *sb, *sb_end; + uint64_t sb_size, blocksize, offset_sectors; uint16_t version; bcs = blkid_probe_get_sb(pr, mag, struct bcachefs_super_block); if (!bcs) return errno ? -errno : BLKID_PROBE_NONE; - if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / BCACHEFS_SECTOR_SIZE) + offset_sectors = blkid_probe_get_idmag_off(pr, mag) / BCACHEFS_SECTOR_SIZE; + if (le64_to_cpu(bcs->offset) != offset_sectors) return BLKID_PROBE_NONE; if (bcs->nr_devices == 0 || bcs->dev_idx >= bcs->nr_devices) @@ -420,6 +430,18 @@ const struct blkid_idinfo bcachefs_idinfo = .kboff = BCACHE_SB_KBOFF, .sboff = BCACHE_SB_MAGIC_OFF, }, + { + .magic = BCACHEFS_SB_MAGIC, + .len = BCACHE_SB_MAGIC_LEN, + .kboff = 1 << 11, + .sboff = BCACHE_SB_MAGIC_OFF, + }, + { + .magic = BCACHEFS_SB_MAGIC, + .len = BCACHE_SB_MAGIC_LEN, + .kboff = -(1 << 10), + .sboff = BCACHE_SB_MAGIC_OFF, + }, { NULL } } }; diff --git a/libblkid/src/superblocks/befs.c b/libblkid/src/superblocks/befs.c index 5112d44..d501eb1 100644 --- a/libblkid/src/superblocks/befs.c +++ b/libblkid/src/superblocks/befs.c @@ -122,7 +122,7 @@ struct bplustree_node { char name[0]; } __attribute__((packed)); -static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs, +static const unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs, const struct block_run *br, int fs_le) { return blkid_probe_get_buffer(pr, @@ -135,7 +135,7 @@ static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_bloc << FS32_TO_CPU(bs->block_shift, fs_le)); } -static unsigned char *get_custom_block_run(blkid_probe pr, +static const unsigned char *get_custom_block_run(blkid_probe pr, const struct befs_super_block *bs, const struct block_run *br, int64_t offset, uint32_t length, int fs_le) @@ -154,7 +154,7 @@ static unsigned char *get_custom_block_run(blkid_probe pr, length); } -static unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs, +static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs, const struct data_stream *ds, int64_t start, uint32_t length, int fs_le) { diff --git a/libblkid/src/superblocks/bluestore.c b/libblkid/src/superblocks/bluestore.c index 2ff1f35..f9178d9 100644 --- a/libblkid/src/superblocks/bluestore.c +++ b/libblkid/src/superblocks/bluestore.c @@ -31,7 +31,7 @@ struct bluestore_phdr { static int probe_bluestore(blkid_probe pr, const struct blkid_idmag *mag) { - struct bluestore_phdr *header; + const struct bluestore_phdr *header; header = blkid_probe_get_sb(pr, mag, struct bluestore_phdr); if (header == NULL) diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c index b9cf4bd..114d348 100644 --- a/libblkid/src/superblocks/btrfs.c +++ b/libblkid/src/superblocks/btrfs.c @@ -250,7 +250,7 @@ static int btrfs_verify_csum(blkid_probe pr, const struct btrfs_super_block *bfs static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct btrfs_super_block *bfs; + const struct btrfs_super_block *bfs; if (pr->zone_size) { #ifdef HAVE_LINUX_BLKZONED_H diff --git a/libblkid/src/superblocks/cramfs.c b/libblkid/src/superblocks/cramfs.c index 2a87acd..6a8731f 100644 --- a/libblkid/src/superblocks/cramfs.c +++ b/libblkid/src/superblocks/cramfs.c @@ -37,12 +37,6 @@ struct cramfs_super #define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */ -static int cramfs_is_little_endian(const struct blkid_idmag *mag) -{ - assert(mag->len == 4); - return memcmp(mag->magic, "\x45\x3d\xcd\x28", 4) == 0; -} - static uint32_t cfs32_to_cpu(int le, uint32_t value) { if (le) @@ -52,10 +46,10 @@ static uint32_t cfs32_to_cpu(int le, uint32_t value) } static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag, - struct cramfs_super *cs, int le) + const struct cramfs_super *cs, int le) { uint32_t crc, expected, csummed_size; - unsigned char *csummed; + const unsigned char *csummed; expected = cfs32_to_cpu(le, cs->info.crc); csummed_size = cfs32_to_cpu(le, cs->size); @@ -67,22 +61,23 @@ static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag, csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size); if (!csummed) return 0; - memset(csummed + offsetof(struct cramfs_super, info.crc), 0, sizeof(uint32_t)); - crc = ~ul_crc32(~0LL, csummed, csummed_size); + crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size, + offsetof(struct cramfs_super, info.crc), + sizeof_member(struct cramfs_super, info.crc)); return blkid_probe_verify_csum(pr, crc, expected); } static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct cramfs_super *cs; + const struct cramfs_super *cs; cs = blkid_probe_get_sb(pr, mag, struct cramfs_super); if (!cs) return errno ? -errno : 1; - int le = cramfs_is_little_endian(mag); + int le = mag->hint == BLKID_ENDIANNESS_LITTLE; int v2 = cfs32_to_cpu(le, cs->flags) & CRAMFS_FLAG_FSID_VERSION_2; if (v2 && !cramfs_verify_csum(pr, mag, cs, le)) @@ -91,8 +86,7 @@ static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag) blkid_probe_set_label(pr, cs->name, sizeof(cs->name)); blkid_probe_set_fssize(pr, cfs32_to_cpu(le, cs->size)); blkid_probe_sprintf_version(pr, "%d", v2 ? 2 : 1); - blkid_probe_set_fsendianness(pr, - le ? BLKID_ENDIANNESS_LITTLE : BLKID_ENDIANNESS_BIG); + blkid_probe_set_fsendianness(pr, mag->hint); return 0; } @@ -103,8 +97,10 @@ const struct blkid_idinfo cramfs_idinfo = .probefunc = probe_cramfs, .magics = { - { .magic = "\x45\x3d\xcd\x28", .len = 4 }, - { .magic = "\x28\xcd\x3d\x45", .len = 4 }, + { .magic = "\x45\x3d\xcd\x28", .len = 4, + .hint = BLKID_ENDIANNESS_LITTLE }, + { .magic = "\x28\xcd\x3d\x45", .len = 4, + .hint = BLKID_ENDIANNESS_BIG }, { NULL } } }; diff --git a/libblkid/src/superblocks/cs_fvault2.c b/libblkid/src/superblocks/cs_fvault2.c index ef2b567..187258d 100644 --- a/libblkid/src/superblocks/cs_fvault2.c +++ b/libblkid/src/superblocks/cs_fvault2.c @@ -65,7 +65,7 @@ static int cs_fvault2_verify_csum(blkid_probe pr, const struct cs_fvault2_sb *sb static int probe_cs_fvault2(blkid_probe pr, const struct blkid_idmag *mag) { - struct cs_fvault2_sb *sb; + const struct cs_fvault2_sb *sb; sb = blkid_probe_get_sb(pr, mag, struct cs_fvault2_sb); if (!sb) diff --git a/libblkid/src/superblocks/ddf_raid.c b/libblkid/src/superblocks/ddf_raid.c index 0b82e73..a7cf32c 100644 --- a/libblkid/src/superblocks/ddf_raid.c +++ b/libblkid/src/superblocks/ddf_raid.c @@ -80,9 +80,6 @@ static int probe_ddf(blkid_probe pr, char version[DDF_REV_LENGTH + 1]; uint64_t off = 0, lba; - if (pr->size < 0x30000) - return 1; - for (i = 0; i < ARRAY_SIZE(hdrs); i++) { off = ((pr->size / 0x200) - hdrs[i]) * 0x200; @@ -106,7 +103,7 @@ static int probe_ddf(blkid_probe pr, if (lba > 0) { /* check primary header */ - unsigned char *buf; + const unsigned char *buf; buf = blkid_probe_get_buffer(pr, lba << 9, sizeof(ddf->signature)); @@ -134,6 +131,7 @@ static int probe_ddf(blkid_probe pr, const struct blkid_idinfo ddfraid_idinfo = { .name = "ddf_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x30000, .probefunc = probe_ddf, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/drbd.c b/libblkid/src/superblocks/drbd.c index f360186..96a2168 100644 --- a/libblkid/src/superblocks/drbd.c +++ b/libblkid/src/superblocks/drbd.c @@ -18,18 +18,24 @@ #include "superblocks.h" +enum { + DRBD_VERSION_08, + DRBD_VERSION_09, +}; + /* - * drbd/linux/drbd.h + * drbd/drbd_int.h */ -#define DRBD_MAGIC 0x83740267 +#define BM_BLOCK_SHIFT 12 /* 4k per bit */ +#define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) /* * user/drbdmeta.c * We support v08 and v09 */ -#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4) -#define DRBD_MD_MAGIC_84_UNCLEAN (DRBD_MAGIC+5) -#define DRBD_MD_MAGIC_09 (DRBD_MAGIC+6) +#define DRBD_MD_MAGIC_08 "\x83\x74\x02\x6b" +#define DRBD_MD_MAGIC_84_UNCLEAN "\x83\x74\x02\x6c" +#define DRBD_MD_MAGIC_09 "\x83\x74\x02\x6d" /* there is no DRBD_MD_MAGIC_09_UNCLEAN */ /* @@ -70,9 +76,8 @@ struct md_on_disk_08 { uint32_t bm_bytes_per_bit; uint32_t reserved_u32[4]; - /* Unnecessary for libblkid ** - * char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)]; - */ + unsigned char padding_start[0]; + unsigned char padding_end[0] __attribute__((aligned(4096))); }; /* @@ -118,32 +123,34 @@ struct meta_data_on_disk_9 { struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX]; uint64_t history_uuids[HISTORY_UUIDS]; - /* Unnecessary for libblkid ** - * char padding[0] __attribute__((aligned(4096))); - */ + unsigned char padding_start[0]; + unsigned char padding_end[0] __attribute__((aligned(4096))); } __attribute__((packed)); -static int probe_drbd_84(blkid_probe pr) +static int is_zero_padded(const unsigned char *padding_start, + const unsigned char *padding_end) { - struct md_on_disk_08 *md; - off_t off; - - off = pr->size - DRBD_MD_OFFSET; + for (; padding_start < padding_end; padding_start++) { + if (*padding_start != 0) + return 0; + } + return 1; +} - /* Small devices cannot be drbd (?) */ - if (pr->size < 0x10000) - return 1; +static int probe_drbd_84(blkid_probe pr, const struct blkid_idmag *mag) +{ + const struct md_on_disk_08 *md; - md = (struct md_on_disk_08 *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct md_on_disk_08)); + md = blkid_probe_get_sb(pr, mag, struct md_on_disk_08); if (!md) return errno ? -errno : 1; - if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08 && - be32_to_cpu(md->magic) != DRBD_MD_MAGIC_84_UNCLEAN) + if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE) + return 1; + + if (!is_zero_padded(member_ptr(md, padding_start), + member_ptr(md, padding_end))) return 1; /* @@ -151,43 +158,27 @@ static int probe_drbd_84(blkid_probe pr) * notion of uuids (64 bit, see struct above) */ blkid_probe_sprintf_uuid(pr, - (unsigned char *) &md->device_uuid, sizeof(md->device_uuid), - "%" PRIx64, be64_to_cpu(md->device_uuid)); + member_ptr(md, device_uuid), sizeof(md->device_uuid), + "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid))); blkid_probe_set_version(pr, "v08"); - if (blkid_probe_set_magic(pr, - off + offsetof(struct md_on_disk_08, magic), - sizeof(md->magic), - (unsigned char *) &md->magic)) - return 1; - return 0; } -static int probe_drbd_90(blkid_probe pr) +static int probe_drbd_90(blkid_probe pr, const struct blkid_idmag *mag) { - struct meta_data_on_disk_9 *md; - off_t off; - - off = pr->size - DRBD_MD_OFFSET; - - /* - * Smaller ones are certainly not DRBD9 devices. - * Recent utils even refuse to generate larger ones, - * keep this as a sufficient lower bound. - */ - if (pr->size < 0x10000) - return 1; + const struct meta_data_on_disk_9 *md; - md = (struct meta_data_on_disk_9 *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct meta_data_on_disk_9)); + md = blkid_probe_get_sb(pr, mag, struct meta_data_on_disk_9); if (!md) return errno ? -errno : 1; - if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_09) + if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE) + return 1; + + if (!is_zero_padded(member_ptr(md, padding_start), + member_ptr(md, padding_end))) return 1; /* @@ -195,30 +186,23 @@ static int probe_drbd_90(blkid_probe pr) * notion of uuids (64 bit, see struct above) */ blkid_probe_sprintf_uuid(pr, - (unsigned char *) &md->device_uuid, sizeof(md->device_uuid), - "%" PRIx64, be64_to_cpu(md->device_uuid)); + member_ptr(md, device_uuid), sizeof(md->device_uuid), + "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid))); blkid_probe_set_version(pr, "v09"); - if (blkid_probe_set_magic(pr, - off + offsetof(struct meta_data_on_disk_9, magic), - sizeof(md->magic), - (unsigned char *) &md->magic)) - return 1; - return 0; } -static int probe_drbd(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) +static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag) { - int ret; + if (mag->hint == DRBD_VERSION_08) + return probe_drbd_84(pr, mag); - ret = probe_drbd_84(pr); - if (ret <= 0) /* success or fatal (-errno) */ - return ret; + if (mag->hint == DRBD_VERSION_09) + return probe_drbd_90(pr, mag); - return probe_drbd_90(pr); + return 1; } const struct blkid_idinfo drbd_idinfo = @@ -226,6 +210,35 @@ const struct blkid_idinfo drbd_idinfo = .name = "drbd", .usage = BLKID_USAGE_RAID, .probefunc = probe_drbd, - .magics = BLKID_NONE_MAGIC + /* + * Smaller ones are certainly not DRBD9 devices. + * Recent utils even refuse to generate larger ones, + * keep this as a sufficient lower bound. + */ + .minsz = 0x10000, + .magics = { + { + .magic = DRBD_MD_MAGIC_08, + .len = sizeof(DRBD_MD_MAGIC_08) - 1, + .hint = DRBD_VERSION_08, + .kboff = -(DRBD_MD_OFFSET >> 10), + .sboff = offsetof(struct md_on_disk_08, magic), + }, + { + .magic = DRBD_MD_MAGIC_84_UNCLEAN, + .len = sizeof(DRBD_MD_MAGIC_84_UNCLEAN) - 1, + .hint = DRBD_VERSION_08, + .kboff = -(DRBD_MD_OFFSET >> 10), + .sboff = offsetof(struct md_on_disk_08, magic), + }, + { + .magic = DRBD_MD_MAGIC_09, + .len = sizeof(DRBD_MD_MAGIC_09) - 1, + .hint = DRBD_VERSION_09, + .kboff = -(DRBD_MD_OFFSET >> 10), + .sboff = offsetof(struct meta_data_on_disk_9, magic), + }, + { NULL } + } }; diff --git a/libblkid/src/superblocks/erofs.c b/libblkid/src/superblocks/erofs.c index 14d272e..0582246 100644 --- a/libblkid/src/superblocks/erofs.c +++ b/libblkid/src/superblocks/erofs.c @@ -46,7 +46,7 @@ static int erofs_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag, { uint32_t expected, csum; size_t csummed_size; - unsigned char *csummed; + const unsigned char *csummed; if (!(le32_to_cpu(sb->feature_compat) & EROFS_FEATURE_SB_CSUM)) return 1; @@ -67,7 +67,7 @@ static int erofs_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag, static int probe_erofs(blkid_probe pr, const struct blkid_idmag *mag) { - struct erofs_super_block *sb; + const struct erofs_super_block *sb; sb = blkid_probe_get_sb(pr, mag, struct erofs_super_block); if (!sb) diff --git a/libblkid/src/superblocks/exfat.c b/libblkid/src/superblocks/exfat.c index fda1ecd..18a3e07 100644 --- a/libblkid/src/superblocks/exfat.c +++ b/libblkid/src/superblocks/exfat.c @@ -121,7 +121,7 @@ static struct exfat_entry_label *find_label(blkid_probe pr, } /* From https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#34-main-and-backup-boot-checksum-sub-regions */ -static uint32_t exfat_boot_checksum(unsigned char *sectors, +static uint32_t exfat_boot_checksum(const unsigned char *sectors, size_t sector_size) { uint32_t n_bytes = sector_size * 11; @@ -143,7 +143,7 @@ static int exfat_validate_checksum(blkid_probe pr, { size_t sector_size = BLOCK_SIZE(sb); /* 11 sectors will be checksummed, the 12th contains the expected */ - unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12); + const unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12); if (!data) return 0; @@ -191,7 +191,7 @@ extern int blkid_probe_is_exfat(blkid_probe pr); */ int blkid_probe_is_exfat(blkid_probe pr) { - struct exfat_super_block *sb; + const struct exfat_super_block *sb; const struct blkid_idmag *mag = NULL; int rc; @@ -213,7 +213,7 @@ int blkid_probe_is_exfat(blkid_probe pr) static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag) { - struct exfat_super_block *sb; + const struct exfat_super_block *sb; struct exfat_entry_label *label; sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block); diff --git a/libblkid/src/superblocks/exfs.c b/libblkid/src/superblocks/exfs.c index 87dc0a0..0a169bd 100644 --- a/libblkid/src/superblocks/exfs.c +++ b/libblkid/src/superblocks/exfs.c @@ -85,7 +85,7 @@ struct exfs_super_block { (s)->sb_agblocks + EXFS_MIN_AG_BLOCKS) -static void sb_from_disk(struct exfs_super_block *from, +static void sb_from_disk(const struct exfs_super_block *from, struct exfs_super_block *to) { @@ -121,7 +121,7 @@ static void sb_from_disk(struct exfs_super_block *from, to->sb_frextents = be64_to_cpu(from->sb_frextents); } -static int exfs_verify_sb(struct exfs_super_block *ondisk) +static int exfs_verify_sb(const struct exfs_super_block *ondisk) { struct exfs_super_block sb, *sbp = &sb; @@ -158,7 +158,7 @@ static int exfs_verify_sb(struct exfs_super_block *ondisk) static int probe_exfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct exfs_super_block *xs; + const struct exfs_super_block *xs; xs = blkid_probe_get_sb(pr, mag, struct exfs_super_block); if (!xs) diff --git a/libblkid/src/superblocks/f2fs.c b/libblkid/src/superblocks/f2fs.c index 980111e..4e0fdbf 100644 --- a/libblkid/src/superblocks/f2fs.c +++ b/libblkid/src/superblocks/f2fs.c @@ -67,14 +67,14 @@ static int f2fs_validate_checksum(blkid_probe pr, size_t sb_off, if (csum_off + sizeof(uint32_t) > 4096) return 0; - unsigned char *csum_data = blkid_probe_get_buffer(pr, + const unsigned char *csum_data = blkid_probe_get_buffer(pr, sb_off + csum_off, sizeof(uint32_t)); if (!csum_data) return 0; uint32_t expected = le32_to_cpu(*(uint32_t *) csum_data); - unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off); + const unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off); if (!csummed) return 0; @@ -85,7 +85,7 @@ static int f2fs_validate_checksum(blkid_probe pr, size_t sb_off, static int probe_f2fs(blkid_probe pr, const struct blkid_idmag *mag) { - struct f2fs_super_block *sb; + const struct f2fs_super_block *sb; uint16_t vermaj, vermin; sb = blkid_probe_get_sb(pr, mag, struct f2fs_super_block); diff --git a/libblkid/src/superblocks/gfs.c b/libblkid/src/superblocks/gfs.c index 445c0da..18d978a 100644 --- a/libblkid/src/superblocks/gfs.c +++ b/libblkid/src/superblocks/gfs.c @@ -59,7 +59,7 @@ struct gfs2_sb { static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct gfs2_sb *sbd; + const struct gfs2_sb *sbd; sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); if (!sbd) @@ -91,7 +91,7 @@ static inline int gfs2_multiformat_is_valid(uint32_t multi) static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag) { - struct gfs2_sb *sbd; + const struct gfs2_sb *sbd; sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); if (!sbd) diff --git a/libblkid/src/superblocks/hfs.c b/libblkid/src/superblocks/hfs.c index 68cb30e..49a0e60 100644 --- a/libblkid/src/superblocks/hfs.c +++ b/libblkid/src/superblocks/hfs.c @@ -154,7 +154,7 @@ static int hfs_set_uuid(blkid_probe pr, unsigned char const *hfs_info, size_t le static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct hfs_mdb *hfs; + const struct hfs_mdb *hfs; int size; hfs = blkid_probe_get_sb(pr, mag, struct hfs_mdb); @@ -183,11 +183,11 @@ static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag) static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) { struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; - struct hfsplus_bnode_descriptor *descr; - struct hfsplus_bheader_record *bnode; - struct hfsplus_catalog_key *key; - struct hfsplus_vol_header *hfsplus; - struct hfs_mdb *sbd; + const struct hfsplus_bnode_descriptor *descr; + const struct hfsplus_bheader_record *bnode; + const struct hfsplus_catalog_key *key; + const struct hfsplus_vol_header *hfsplus; + const struct hfs_mdb *sbd; unsigned int alloc_block_size; unsigned int alloc_first_block; unsigned int embed_first_block; @@ -203,7 +203,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) unsigned int leaf_block; int ext; uint64_t leaf_off; - unsigned char *buf; + const unsigned char *buf; sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb); if (!sbd) @@ -217,6 +217,10 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) return 1; alloc_block_size = be32_to_cpu(sbd->al_blk_size); + if (alloc_block_size < HFSPLUS_SECTOR_SIZE || + alloc_block_size % HFSPLUS_SECTOR_SIZE) + return 1; + alloc_first_block = be16_to_cpu(sbd->al_bl_st); embed_first_block = be16_to_cpu(sbd->embed_startblock); off = (alloc_first_block * 512) + @@ -225,7 +229,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) buf = blkid_probe_get_buffer(pr, off + (mag->kboff * 1024), sizeof(struct hfsplus_vol_header)); - hfsplus = (struct hfsplus_vol_header *) buf; + hfsplus = (const struct hfsplus_vol_header *) buf; } else hfsplus = blkid_probe_get_sb(pr, mag, @@ -238,17 +242,23 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) (memcmp(hfsplus->signature, "HX", 2) != 0)) return 1; - hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id)); - + /* Verify blocksize is initialized */ blocksize = be32_to_cpu(hfsplus->blocksize); - if (blocksize < HFSPLUS_SECTOR_SIZE) + if (blocksize < HFSPLUS_SECTOR_SIZE || !is_power_of_2(blocksize)) return 1; - blkid_probe_set_fsblocksize(pr, blocksize); - blkid_probe_set_block_size(pr, blocksize); - + /* Save extends (hfsplus buffer may be later overwritten) */ memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); + + /* Make sure start_block is properly initialized */ cat_block = be32_to_cpu(extents[0].start_block); + if (off + ((uint64_t) cat_block * blocksize) > pr->size) + return 1; + + hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id)); + + blkid_probe_set_fsblocksize(pr, blocksize); + blkid_probe_set_block_size(pr, blocksize); buf = blkid_probe_get_buffer(pr, off + ((uint64_t) cat_block * blocksize), 0x2000); diff --git a/libblkid/src/superblocks/highpoint_raid.c b/libblkid/src/superblocks/highpoint_raid.c index 2487930..c8b1297 100644 --- a/libblkid/src/superblocks/highpoint_raid.c +++ b/libblkid/src/superblocks/highpoint_raid.c @@ -29,8 +29,6 @@ static int probe_highpoint45x(blkid_probe pr, uint64_t off; uint32_t magic; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -62,6 +60,7 @@ static int probe_highpoint37x(blkid_probe pr, const struct blkid_idinfo highpoint45x_idinfo = { .name = "hpt45x_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_highpoint45x, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/hpfs.c b/libblkid/src/superblocks/hpfs.c index 09bf975..f7ee02d 100644 --- a/libblkid/src/superblocks/hpfs.c +++ b/libblkid/src/superblocks/hpfs.c @@ -60,9 +60,9 @@ struct hpfs_spare_super static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct hpfs_super_block *hs; - struct hpfs_spare_super *hss; - struct hpfs_boot_block *hbb; + const struct hpfs_super_block *hs; + const struct hpfs_spare_super *hss; + const struct hpfs_boot_block *hbb; uint8_t version; /* super block */ diff --git a/libblkid/src/superblocks/iso9660.c b/libblkid/src/superblocks/iso9660.c index 536704b..a7a364f 100644 --- a/libblkid/src/superblocks/iso9660.c +++ b/libblkid/src/superblocks/iso9660.c @@ -22,7 +22,7 @@ #include "cctype.h" #include "iso9660.h" -struct iso9660_date { +struct hs_date { unsigned char year[4]; unsigned char month[2]; unsigned char day[2]; @@ -30,11 +30,16 @@ struct iso9660_date { unsigned char minute[2]; unsigned char second[2]; unsigned char hundredth[2]; +} __attribute__ ((packed)); + +struct iso9660_date { + struct hs_date common; unsigned char offset; } __attribute__ ((packed)); /* PVD - Primary volume descriptor */ struct iso_volume_descriptor { + /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value, those are skipped by blkid_probe_get_buffer() */ unsigned char vd_type; unsigned char vd_id[5]; unsigned char vd_version; @@ -43,21 +48,59 @@ struct iso_volume_descriptor { unsigned char volume_id[32]; unsigned char unused[8]; unsigned char space_size[8]; - unsigned char escape_sequences[8]; - unsigned char unused2[32]; + unsigned char escape_sequences[32]; + unsigned char set_size[4]; + unsigned char vol_seq_num[4]; unsigned char logical_block_size[4]; - unsigned char unused3[58]; - unsigned char volume_set_id[128]; - unsigned char publisher_id[128]; - unsigned char data_preparer_id[128]; - unsigned char application_id[128]; - unsigned char unused4[111]; - struct iso9660_date created; - struct iso9660_date modified; + unsigned char path_table_size[8]; + union { + struct { + unsigned char type_l_path_table[4]; + unsigned char opt_type_l_path_table[4]; + unsigned char type_m_path_table[4]; + unsigned char opt_type_m_path_table[4]; + unsigned char root_dir_record[34]; + unsigned char volume_set_id[128]; + unsigned char publisher_id[128]; + unsigned char data_preparer_id[128]; + unsigned char application_id[128]; + unsigned char copyright_file_id[37]; + unsigned char abstract_file_id[37]; + unsigned char bibliographic_file_id[37]; + struct iso9660_date created; + struct iso9660_date modified; + struct iso9660_date expiration; + struct iso9660_date effective; + unsigned char std_version; + } iso; /* ISO9660 */ + struct { + unsigned char type_l_path_table[4]; + unsigned char opt1_type_l_path_table[4]; + unsigned char opt2_type_l_path_table[4]; + unsigned char opt3_type_l_path_table[4]; + unsigned char type_m_path_table[4]; + unsigned char opt1_type_m_path_table[4]; + unsigned char opt2_type_m_path_table[4]; + unsigned char opt3_type_m_path_table[4]; + unsigned char root_dir_record[34]; + unsigned char volume_set_id[128]; + unsigned char publisher_id[128]; + unsigned char data_preparer_id[128]; + unsigned char application_id[128]; + unsigned char copyright_file_id[32]; + unsigned char abstract_file_id[32]; + struct hs_date created; + struct hs_date modified; + struct hs_date expiration; + struct hs_date effective; + unsigned char std_version; + } hs; /* High Sierra */ + }; } __attribute__((packed)); /* Boot Record */ struct boot_record { + /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value, those are skipped by blkid_probe_get_buffer() */ unsigned char vd_type; unsigned char vd_id[5]; unsigned char vd_version; @@ -74,35 +117,9 @@ struct boot_record { #define ISO_VD_END 0xff #define ISO_VD_MAX 16 /* maximal string field size used anywhere in ISO; update if necessary */ -#define ISO_MAX_FIELDSIZ sizeof_member(struct iso_volume_descriptor, volume_set_id) - -struct high_sierra_volume_descriptor { - unsigned char foo[8]; - unsigned char type; - unsigned char id[5]; - unsigned char version; - unsigned char unused1; - unsigned char system_id[32]; - unsigned char volume_id[32]; -} __attribute__((packed)); - -/* old High Sierra format */ -static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct high_sierra_volume_descriptor *iso; +#define ISO_MAX_FIELDSIZ sizeof_member(struct iso_volume_descriptor, iso.volume_set_id) - iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor); - if (!iso) - return errno ? -errno : 1; - - blkid_probe_set_fsblocksize(pr, ISO_SECTOR_SIZE); - blkid_probe_set_block_size(pr, ISO_SECTOR_SIZE); - blkid_probe_set_version(pr, "High Sierra"); - blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id)); - return 0; -} - -static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *date) +static int probe_iso9660_set_uuid (blkid_probe pr, const struct hs_date *date, unsigned char offset) { unsigned char buffer[16]; unsigned int i, zeros = 0; @@ -130,7 +147,7 @@ static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *da zeros++; /* due to the iso9660 standard if all date fields are '0' and offset is 0, the date is unset */ - if (zeros == sizeof(buffer) && date->offset == 0) + if (zeros == sizeof(buffer) && offset == 0) return 0; /* generate an UUID using this date and return success */ @@ -216,9 +233,15 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) struct iso_volume_descriptor *joliet = NULL; /* space for merge_utf16be_ascii(ISO_ID_BUFSIZ bytes) */ unsigned char buf[ISO_MAX_FIELDSIZ * 5 / 2]; + const struct hs_date *modified; + const struct hs_date *created; + unsigned char modified_offset; + unsigned char created_offset; size_t len; + int is_hs; int is_unicode_empty; - int is_ascii_empty; + int is_ascii_hs_empty; + int is_ascii_iso_empty; int i; uint64_t off; @@ -228,13 +251,12 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) if (off % ISO_SECTOR_SIZE) return 1; - if (strcmp(mag->magic, "CDROM") == 0) - return probe_iso9660_hsfs(pr, mag); + is_hs = (strcmp(mag->magic, "CDROM") == 0); - for (i = 0, off += ISO_SUPERBLOCK_OFFSET; i < ISO_VD_MAX && (!boot || !pvd || !joliet); i++, off += ISO_SECTOR_SIZE) { - unsigned char *desc = + for (i = 0, off += ISO_SUPERBLOCK_OFFSET; i < ISO_VD_MAX && (!boot || !pvd || (!is_hs && !joliet)); i++, off += ISO_SECTOR_SIZE) { + const unsigned char *desc = blkid_probe_get_buffer(pr, - off, + off + (is_hs ? 8 : 0), /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value */ max(sizeof(struct boot_record), sizeof(struct iso_volume_descriptor))); @@ -244,7 +266,7 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) boot = (struct boot_record *)desc; else if (!pvd && desc[0] == ISO_VD_PRIMARY) pvd = (struct iso_volume_descriptor *)desc; - else if (!joliet && desc[0] == ISO_VD_SUPPLEMENTARY) { + else if (!is_hs && !joliet && desc[0] == ISO_VD_SUPPLEMENTARY) { joliet = (struct iso_volume_descriptor *)desc; if (memcmp(joliet->escape_sequences, "%/@", 3) != 0 && memcmp(joliet->escape_sequences, "%/C", 3) != 0 && @@ -270,43 +292,66 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) else blkid_probe_set_id_label(pr, "SYSTEM_ID", pvd->system_id, sizeof(pvd->system_id)); - if (joliet && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->volume_set_id, pvd->volume_set_id, sizeof(pvd->volume_set_id))) != 0) + if (joliet && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.volume_set_id, pvd->iso.volume_set_id, sizeof(pvd->iso.volume_set_id))) != 0) blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", buf, len, UL_ENCODE_UTF16BE); else if (joliet) - blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", joliet->volume_set_id, sizeof(joliet->volume_set_id), UL_ENCODE_UTF16BE); + blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", joliet->iso.volume_set_id, sizeof(joliet->iso.volume_set_id), UL_ENCODE_UTF16BE); + else if (is_hs) + blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->hs.volume_set_id, sizeof(pvd->hs.volume_set_id)); else - blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->volume_set_id, sizeof(pvd->volume_set_id)); + blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->iso.volume_set_id, sizeof(pvd->iso.volume_set_id)); - is_ascii_empty = (is_str_empty(pvd->publisher_id, sizeof(pvd->publisher_id)) || pvd->publisher_id[0] == '_'); - is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->publisher_id, sizeof(joliet->publisher_id)) || (joliet->publisher_id[0] == 0x00 && joliet->publisher_id[1] == '_')); - if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->publisher_id, pvd->publisher_id, sizeof(pvd->publisher_id))) != 0) + is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.publisher_id, sizeof(pvd->hs.publisher_id)) || pvd->hs.publisher_id[0] == '_'); + is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id)) || pvd->iso.publisher_id[0] == '_'); + is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.publisher_id, sizeof(joliet->iso.publisher_id)) || (joliet->iso.publisher_id[0] == 0x00 && joliet->iso.publisher_id[1] == '_')); + if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.publisher_id, pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id))) != 0) blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", buf, len, UL_ENCODE_UTF16BE); else if (!is_unicode_empty) - blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", joliet->publisher_id, sizeof(joliet->publisher_id), UL_ENCODE_UTF16BE); - else if (!is_ascii_empty) - blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->publisher_id, sizeof(pvd->publisher_id)); - - is_ascii_empty = (is_str_empty(pvd->data_preparer_id, sizeof(pvd->data_preparer_id)) || pvd->data_preparer_id[0] == '_'); - is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->data_preparer_id, sizeof(joliet->data_preparer_id)) || (joliet->data_preparer_id[0] == 0x00 && joliet->data_preparer_id[1] == '_')); - if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->data_preparer_id, pvd->data_preparer_id, sizeof(pvd->data_preparer_id))) != 0) + blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", joliet->iso.publisher_id, sizeof(joliet->iso.publisher_id), UL_ENCODE_UTF16BE); + else if (!is_ascii_hs_empty) + blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->hs.publisher_id, sizeof(pvd->hs.publisher_id)); + else if (!is_ascii_iso_empty) + blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id)); + + is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.data_preparer_id, sizeof(pvd->hs.data_preparer_id)) || pvd->hs.data_preparer_id[0] == '_'); + is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id)) || pvd->iso.data_preparer_id[0] == '_'); + is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.data_preparer_id, sizeof(joliet->iso.data_preparer_id)) || (joliet->iso.data_preparer_id[0] == 0x00 && joliet->iso.data_preparer_id[1] == '_')); + if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.data_preparer_id, pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id))) != 0) blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", buf, len, UL_ENCODE_UTF16BE); else if (!is_unicode_empty) - blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", joliet->data_preparer_id, sizeof(joliet->data_preparer_id), UL_ENCODE_UTF16BE); - else if (!is_ascii_empty) - blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->data_preparer_id, sizeof(pvd->data_preparer_id)); - - is_ascii_empty = (is_str_empty(pvd->application_id, sizeof(pvd->application_id)) || pvd->application_id[0] == '_'); - is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->application_id, sizeof(joliet->application_id)) || (joliet->application_id[0] == 0x00 && joliet->application_id[1] == '_')); - if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->application_id, pvd->application_id, sizeof(pvd->application_id))) != 0) + blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", joliet->iso.data_preparer_id, sizeof(joliet->iso.data_preparer_id), UL_ENCODE_UTF16BE); + else if (!is_ascii_hs_empty) + blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->hs.data_preparer_id, sizeof(pvd->hs.data_preparer_id)); + else if (!is_ascii_iso_empty) + blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id)); + + is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.application_id, sizeof(pvd->hs.application_id)) || pvd->hs.application_id[0] == '_'); + is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.application_id, sizeof(pvd->iso.application_id)) || pvd->iso.application_id[0] == '_'); + is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.application_id, sizeof(joliet->iso.application_id)) || (joliet->iso.application_id[0] == 0x00 && joliet->iso.application_id[1] == '_')); + if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.application_id, pvd->iso.application_id, sizeof(pvd->iso.application_id))) != 0) blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", buf, len, UL_ENCODE_UTF16BE); else if (!is_unicode_empty) - blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", joliet->application_id, sizeof(joliet->application_id), UL_ENCODE_UTF16BE); - else if (!is_ascii_empty) - blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->application_id, sizeof(pvd->application_id)); + blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", joliet->iso.application_id, sizeof(joliet->iso.application_id), UL_ENCODE_UTF16BE); + else if (!is_ascii_hs_empty) + blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->hs.application_id, sizeof(pvd->hs.application_id)); + else if (!is_ascii_iso_empty) + blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->iso.application_id, sizeof(pvd->iso.application_id)); + + if (is_hs) { + modified = &pvd->hs.modified; + created = &pvd->hs.created; + modified_offset = 0; + created_offset = 0; + } else { + modified = &pvd->iso.modified.common; + created = &pvd->iso.created.common; + modified_offset = pvd->iso.modified.offset; + created_offset = pvd->iso.created.offset; + } /* create an UUID using the modified/created date */ - if (! probe_iso9660_set_uuid(pr, &pvd->modified)) - probe_iso9660_set_uuid(pr, &pvd->created); + if (! probe_iso9660_set_uuid(pr, modified, modified_offset)) + probe_iso9660_set_uuid(pr, created, created_offset); if (boot) blkid_probe_set_id_label(pr, "BOOT_SYSTEM_ID", @@ -315,6 +360,8 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) if (joliet) blkid_probe_set_version(pr, "Joliet Extension"); + else if (is_hs) + blkid_probe_set_version(pr, "High Sierra"); /* Label in Joliet is UNICODE (UTF16BE) but can contain only 16 characters. Label in PVD is * subset of ASCII but can contain up to the 32 characters. Non-representable characters are @@ -340,6 +387,10 @@ const struct blkid_idinfo iso9660_idinfo = .flags = BLKID_IDINFO_TOLERANT, .magics = { + /* + * Due to different location of vd_id[] in ISO9660 and High Sierra, IS9660 can match + * also High Sierra vd_id[]. So always check ISO9660 (CD001) before High Sierra (CDROM). + */ { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" }, { .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9, .hoff = "session_offset" }, { NULL } diff --git a/libblkid/src/superblocks/isw_raid.c b/libblkid/src/superblocks/isw_raid.c index 81d53a1..aa03bcd 100644 --- a/libblkid/src/superblocks/isw_raid.c +++ b/libblkid/src/superblocks/isw_raid.c @@ -32,8 +32,6 @@ static int probe_iswraid(blkid_probe pr, unsigned int sector_size; struct isw_metadata *isw; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -60,6 +58,7 @@ static int probe_iswraid(blkid_probe pr, const struct blkid_idinfo iswraid_idinfo = { .name = "isw_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_iswraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/jfs.c b/libblkid/src/superblocks/jfs.c index 7b75ecb..c277375 100644 --- a/libblkid/src/superblocks/jfs.c +++ b/libblkid/src/superblocks/jfs.c @@ -36,7 +36,7 @@ struct jfs_super_block { static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct jfs_super_block *js; + const struct jfs_super_block *js; js = blkid_probe_get_sb(pr, mag, struct jfs_super_block); if (!js) diff --git a/libblkid/src/superblocks/jmicron_raid.c b/libblkid/src/superblocks/jmicron_raid.c index 65e05b6..4587075 100644 --- a/libblkid/src/superblocks/jmicron_raid.c +++ b/libblkid/src/superblocks/jmicron_raid.c @@ -75,8 +75,6 @@ static int probe_jmraid(blkid_probe pr, uint64_t off; const struct jm_metadata *jm; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -109,6 +107,7 @@ static int probe_jmraid(blkid_probe pr, const struct blkid_idinfo jmraid_idinfo = { .name = "jmicron_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_jmraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/linux_raid.c b/libblkid/src/superblocks/linux_raid.c index 360cd4e..156b0bf 100644 --- a/libblkid/src/superblocks/linux_raid.c +++ b/libblkid/src/superblocks/linux_raid.c @@ -187,15 +187,14 @@ static int raid1_verify_csum(blkid_probe pr, off_t off, { size_t csummed_size = sizeof(struct mdp1_super_block) + le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]); - unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size); + const unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size); if (!csummed) return 1; - memset(csummed + offsetof(struct mdp1_super_block, sb_csum), 0, - sizeof(mdp1->sb_csum)); - uint64_t csum = 0; + csum -= le32_to_cpu(*(uint32_t *) (csummed + offsetof(struct mdp1_super_block, sb_csum))); + while (csummed_size >= 4) { csum += le32_to_cpu(*(uint32_t *) csummed); csummed_size -= 4; diff --git a/libblkid/src/superblocks/lsi_raid.c b/libblkid/src/superblocks/lsi_raid.c index 697b0fe..2ceed9b 100644 --- a/libblkid/src/superblocks/lsi_raid.c +++ b/libblkid/src/superblocks/lsi_raid.c @@ -29,8 +29,6 @@ static int probe_lsiraid(blkid_probe pr, uint64_t off; struct lsi_metadata *lsi; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -53,6 +51,7 @@ static int probe_lsiraid(blkid_probe pr, const struct blkid_idinfo lsiraid_idinfo = { .name = "lsi_mega_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_lsiraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c index 0230b34..4623c98 100644 --- a/libblkid/src/superblocks/luks.c +++ b/libblkid/src/superblocks/luks.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Karel Zak <kzak@redhat.com> - * Copyright (C) 2018 Milan Broz <gmazyland@gmail.com> + * Copyright (C) 2018-2024 Milan Broz <gmazyland@gmail.com> * * Inspired by libvolume_id by * Kay Sievers <kay.sievers@vrfy.org> @@ -15,6 +15,7 @@ #include <errno.h> #include <ctype.h> #include <stdint.h> +#include <stdbool.h> #include "superblocks.h" @@ -96,6 +97,19 @@ static int luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t o return BLKID_PROBE_OK; } +static bool luks_valid(struct luks2_phdr *header, const char *magic, uint64_t offset) +{ + if (memcmp(header->magic, magic, LUKS_MAGIC_L)) + return false; + + /* LUKS2 header is not at expected offset */ + if (be16_to_cpu(header->version) == 2 && + be64_to_cpu(header->hdr_offset) != offset) + return false; + + return true; +} + static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) { struct luks2_phdr *header; @@ -105,7 +119,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_ if (!header) return errno ? -errno : BLKID_PROBE_NONE; - if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) { + if (luks_valid(header, LUKS_MAGIC, 0)) { /* LUKS primary header was found. */ return luks_attributes(pr, header, 0); } @@ -118,7 +132,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_ if (!header) return errno ? -errno : BLKID_PROBE_NONE; - if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L)) + if (luks_valid(header, LUKS_MAGIC_2, secondary_offsets[i])) return luks_attributes(pr, header, secondary_offsets[i]); } diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c index eea74d6..0a3d505 100644 --- a/libblkid/src/superblocks/lvm.c +++ b/libblkid/src/superblocks/lvm.c @@ -76,11 +76,11 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag) int sector = mag->kboff << 1; struct lvm2_pv_label_header *label; char uuid[LVM2_ID_LEN + 7]; - unsigned char *buf; + const unsigned char *buf; buf = blkid_probe_get_buffer(pr, mag->kboff << 10, - 512 + sizeof(struct lvm2_pv_label_header)); + 512 + LVM2_LABEL_SIZE); if (!buf) return errno ? -errno : 1; @@ -122,7 +122,7 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag) static int probe_lvm1(blkid_probe pr, const struct blkid_idmag *mag) { - struct lvm1_pv_label_header *label; + const struct lvm1_pv_label_header *label; char uuid[LVM2_ID_LEN + 7]; unsigned int version; @@ -158,7 +158,7 @@ struct verity_sb { static int probe_verity(blkid_probe pr, const struct blkid_idmag *mag) { - struct verity_sb *sb; + const struct verity_sb *sb; unsigned int version; sb = blkid_probe_get_sb(pr, mag, struct verity_sb); @@ -187,7 +187,7 @@ struct integrity_sb { static int probe_integrity(blkid_probe pr, const struct blkid_idmag *mag) { - struct integrity_sb *sb; + const struct integrity_sb *sb; sb = blkid_probe_get_sb(pr, mag, struct integrity_sb); if (sb == NULL) diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c index c68ade9..dba299d 100644 --- a/libblkid/src/superblocks/minix.c +++ b/libblkid/src/superblocks/minix.c @@ -74,7 +74,7 @@ static int get_minix_version(const unsigned char *data, int *other_endian) static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) { - unsigned char *ext; + const unsigned char *ext; const unsigned char *data; int version = 0, swabme = 0; unsigned long zones, ninodes, imaps, zmaps; diff --git a/libblkid/src/superblocks/mpool.c b/libblkid/src/superblocks/mpool.c index b27569e..8a2e29c 100644 --- a/libblkid/src/superblocks/mpool.c +++ b/libblkid/src/superblocks/mpool.c @@ -26,7 +26,7 @@ struct omf_sb_descriptor { static int probe_mpool(blkid_probe pr, const struct blkid_idmag *mag) { - struct omf_sb_descriptor *osd; + const struct omf_sb_descriptor *osd; uint32_t sb_crc; osd = blkid_probe_get_sb(pr, mag, struct omf_sb_descriptor); diff --git a/libblkid/src/superblocks/netware.c b/libblkid/src/superblocks/netware.c index af81cf5..a8c20cb 100644 --- a/libblkid/src/superblocks/netware.c +++ b/libblkid/src/superblocks/netware.c @@ -67,7 +67,7 @@ struct netware_super_block { static int probe_netware(blkid_probe pr, const struct blkid_idmag *mag) { - struct netware_super_block *nw; + const struct netware_super_block *nw; nw = blkid_probe_get_sb(pr, mag, struct netware_super_block); if (!nw) diff --git a/libblkid/src/superblocks/ntfs.c b/libblkid/src/superblocks/ntfs.c index ab8c921..8ce557a 100644 --- a/libblkid/src/superblocks/ntfs.c +++ b/libblkid/src/superblocks/ntfs.c @@ -80,13 +80,13 @@ struct file_attribute { static int __probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag, int save_info) { - struct ntfs_super_block *ns; - struct master_file_table_record *mft; + const struct ntfs_super_block *ns; + const struct master_file_table_record *mft; uint32_t sectors_per_cluster, mft_record_size; uint16_t sector_size; uint64_t nr_clusters, off, attr_off; - unsigned char *buf_mft; + const unsigned char *buf_mft; ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block); if (!ns) diff --git a/libblkid/src/superblocks/nvidia_raid.c b/libblkid/src/superblocks/nvidia_raid.c index d930f72..1a88dbd 100644 --- a/libblkid/src/superblocks/nvidia_raid.c +++ b/libblkid/src/superblocks/nvidia_raid.c @@ -41,8 +41,6 @@ static int probe_nvraid(blkid_probe pr, uint64_t off; struct nv_metadata *nv; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -71,6 +69,7 @@ static int probe_nvraid(blkid_probe pr, const struct blkid_idinfo nvraid_idinfo = { .name = "nvidia_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_nvraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/ocfs.c b/libblkid/src/superblocks/ocfs.c index e213d66..f2b2ca2 100644 --- a/libblkid/src/superblocks/ocfs.c +++ b/libblkid/src/superblocks/ocfs.c @@ -100,7 +100,7 @@ struct oracle_asm_disk_label { static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) { - unsigned char *buf; + const unsigned char *buf; struct ocfs_volume_header ovh; struct ocfs_volume_label ovl; uint32_t maj, min; @@ -142,7 +142,7 @@ static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) { - struct ocfs2_super_block *osb; + const struct ocfs2_super_block *osb; osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block); if (!osb) @@ -165,7 +165,7 @@ static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag) { - struct oracle_asm_disk_label *dl; + const struct oracle_asm_disk_label *dl; dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label); if (!dl) diff --git a/libblkid/src/superblocks/promise_raid.c b/libblkid/src/superblocks/promise_raid.c index 75f3a20..f891b37 100644 --- a/libblkid/src/superblocks/promise_raid.c +++ b/libblkid/src/superblocks/promise_raid.c @@ -33,8 +33,6 @@ static int probe_pdcraid(blkid_probe pr, }; uint64_t nsectors; - if (pr->size < 0x40000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -70,6 +68,7 @@ static int probe_pdcraid(blkid_probe pr, const struct blkid_idinfo pdcraid_idinfo = { .name = "promise_fasttrack_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x40000, .probefunc = probe_pdcraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/reiserfs.c b/libblkid/src/superblocks/reiserfs.c index 23d10e2..dac5f0c 100644 --- a/libblkid/src/superblocks/reiserfs.c +++ b/libblkid/src/superblocks/reiserfs.c @@ -41,7 +41,7 @@ struct reiser4_super_block { static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag) { - struct reiserfs_super_block *rs; + const struct reiserfs_super_block *rs; unsigned int blocksize; rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block); @@ -82,7 +82,7 @@ static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag) static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag) { - struct reiser4_super_block *rs4; + const struct reiser4_super_block *rs4; unsigned int blocksize; rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block); diff --git a/libblkid/src/superblocks/romfs.c b/libblkid/src/superblocks/romfs.c index 456cbfb..86c09ad 100644 --- a/libblkid/src/superblocks/romfs.c +++ b/libblkid/src/superblocks/romfs.c @@ -29,7 +29,7 @@ static int romfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag, { uint32_t csummed_size = min((uint32_t) 512, be32_to_cpu(ros->ros_full_size)); - unsigned char *csummed; + const unsigned char *csummed; uint32_t csum; if (csummed_size % sizeof(uint32_t) != 0) @@ -50,7 +50,7 @@ static int romfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag, static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct romfs_super_block *ros; + const struct romfs_super_block *ros; ros = blkid_probe_get_sb(pr, mag, struct romfs_super_block); if (!ros) diff --git a/libblkid/src/superblocks/silicon_raid.c b/libblkid/src/superblocks/silicon_raid.c index 399eea8..0fc223d 100644 --- a/libblkid/src/superblocks/silicon_raid.c +++ b/libblkid/src/superblocks/silicon_raid.c @@ -91,8 +91,6 @@ static int probe_silraid(blkid_probe pr, uint64_t off; struct silicon_metadata *sil; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -127,6 +125,7 @@ static int probe_silraid(blkid_probe pr, const struct blkid_idinfo silraid_idinfo = { .name = "silicon_medley_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_silraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/squashfs.c b/libblkid/src/superblocks/squashfs.c index 92ab77a..8246583 100644 --- a/libblkid/src/superblocks/squashfs.c +++ b/libblkid/src/superblocks/squashfs.c @@ -40,7 +40,7 @@ struct sqsh_super_block { static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct sqsh_super_block *sq; + const struct sqsh_super_block *sq; uint16_t vermaj; uint16_t vermin; @@ -63,10 +63,10 @@ static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag) static int probe_squashfs3(blkid_probe pr, const struct blkid_idmag *mag) { - struct sqsh_super_block *sq; + const struct sqsh_super_block *sq; uint16_t vermaj; uint16_t vermin; - enum BLKID_ENDIANNESS endianness; + enum blkid_endianness endianness; sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block); if (!sq) diff --git a/libblkid/src/superblocks/stratis.c b/libblkid/src/superblocks/stratis.c index fe4a452..2651107 100644 --- a/libblkid/src/superblocks/stratis.c +++ b/libblkid/src/superblocks/stratis.c @@ -22,7 +22,7 @@ /* Macro to avoid error in struct declaration. */ #define STRATIS_UUID_LEN 32 /* Contains 4 hyphens and trailing null byte. */ -const int STRATIS_UUID_STR_LEN = 37; +#define STRATIS_UUID_STR_LEN 37 struct stratis_sb { uint32_t crc32; @@ -49,7 +49,7 @@ const char STRATIS_MAGIC[] = "!Stra0tis\x86\xff\x02^\x41rh"; #define MAGIC_OFFSET_COPY_1 (FIRST_COPY_OFFSET + _MAGIC_OFFSET) #define MAGIC_OFFSET_COPY_2 (SECOND_COPY_OFFSET + _MAGIC_OFFSET) -static int stratis_valid_sb(uint8_t *p) +static int stratis_valid_sb(const uint8_t *p) { const struct stratis_sb *stratis = (const struct stratis_sb *)p; uint32_t crc = 0; @@ -83,7 +83,7 @@ static int probe_stratis(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) { const struct stratis_sb *stratis = NULL; - uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE); + const uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE); unsigned char uuid[STRATIS_UUID_STR_LEN]; if (!buf) diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c index 96bc0ef..dd1e6dc 100644 --- a/libblkid/src/superblocks/superblocks.c +++ b/libblkid/src/superblocks/superblocks.c @@ -94,11 +94,6 @@ static int blkid_probe_set_usage(blkid_probe pr, int usage); */ static const struct blkid_idinfo *idinfos[] = { - /* In case the volume is locked with OPAL we are going to get - * an I/O error when reading past the LUKS header, so try it - * first. */ - &luks_idinfo, - /* RAIDs */ &linuxraid_idinfo, &ddfraid_idinfo, @@ -124,6 +119,7 @@ static const struct blkid_idinfo *idinfos[] = &snapcow_idinfo, &verity_hash_idinfo, &integrity_idinfo, + &luks_idinfo, &vmfs_volume_idinfo, &ubi_idinfo, &vdo_idinfo, @@ -423,6 +419,7 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) DBG(LOWPROBE, ul_debug("\tcall probefunc()")); errno = 0; rc = id->probefunc(pr, mag); + blkid_probe_prune_buffers(pr); if (rc != BLKID_PROBE_OK) { blkid_probe_chain_reset_values(pr, chn); if (rc < 0) @@ -629,7 +626,7 @@ int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size) block_size); } -int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness) +int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness) { struct blkid_chain *chn = blkid_probe_get_chain(pr); const char *value; diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h index a990058..dc669e0 100644 --- a/libblkid/src/superblocks/superblocks.h +++ b/libblkid/src/superblocks/superblocks.h @@ -9,7 +9,7 @@ #include "blkidP.h" -enum BLKID_ENDIANNESS { +enum blkid_endianness { BLKID_ENDIANNESS_LITTLE, BLKID_ENDIANNESS_BIG, }; @@ -128,9 +128,21 @@ int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size); int blkid_probe_set_fssize(blkid_probe pr, uint64_t size); int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock); int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size); -int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness); +int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness); extern int blkid_probe_is_bitlocker(blkid_probe pr); extern int blkid_probe_is_ntfs(blkid_probe pr); +/* + * utility functions + */ +static inline int blkid32_to_cpu(enum blkid_endianness e, uint32_t i) +{ + if (e == BLKID_ENDIANNESS_LITTLE) + return le32_to_cpu(i); + else if (e == BLKID_ENDIANNESS_BIG) + return be32_to_cpu(i); + abort(); +} + #endif /* _BLKID_SUPERBLOCKS_H */ diff --git a/libblkid/src/superblocks/swap.c b/libblkid/src/superblocks/swap.c index 67224bc..4876905 100644 --- a/libblkid/src/superblocks/swap.c +++ b/libblkid/src/superblocks/swap.c @@ -40,7 +40,7 @@ static void swap_set_info_swap1(blkid_probe pr, const struct blkid_idmag *mag, const struct swap_header_v1_2 *hdr) { - enum BLKID_ENDIANNESS endianness = le32_to_cpu(hdr->version) == 1 ? + enum blkid_endianness endianness = le32_to_cpu(hdr->version) == 1 ? BLKID_ENDIANNESS_LITTLE : BLKID_ENDIANNESS_BIG; blkid_probe_set_fsendianness(pr, endianness); @@ -91,7 +91,7 @@ static int swap_set_info(blkid_probe pr, const struct blkid_idmag *mag, static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag) { - unsigned char *buf; + const unsigned char *buf; if (!mag) return 1; diff --git a/libblkid/src/superblocks/sysv.c b/libblkid/src/superblocks/sysv.c index 421660e..a9085c4 100644 --- a/libblkid/src/superblocks/sysv.c +++ b/libblkid/src/superblocks/sysv.c @@ -76,7 +76,7 @@ struct sysv_super_block static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag) { - struct xenix_super_block *sb; + const struct xenix_super_block *sb; sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block); if (!sb) diff --git a/libblkid/src/superblocks/ubi.c b/libblkid/src/superblocks/ubi.c index fbb7c5e..b15199b 100644 --- a/libblkid/src/superblocks/ubi.c +++ b/libblkid/src/superblocks/ubi.c @@ -35,7 +35,7 @@ static int ubi_verify_csum(blkid_probe pr, const struct ubi_ec_hdr *hdr) static int probe_ubi(blkid_probe pr, const struct blkid_idmag *mag) { - struct ubi_ec_hdr *hdr; + const struct ubi_ec_hdr *hdr; hdr = blkid_probe_get_sb(pr, mag, struct ubi_ec_hdr); if (!hdr) diff --git a/libblkid/src/superblocks/ubifs.c b/libblkid/src/superblocks/ubifs.c index 8dece28..c9733a9 100644 --- a/libblkid/src/superblocks/ubifs.c +++ b/libblkid/src/superblocks/ubifs.c @@ -105,7 +105,7 @@ static int ubifs_verify_csum(blkid_probe pr, const struct ubifs_sb_node *sb) static int probe_ubifs(blkid_probe pr, const struct blkid_idmag *mag) { - struct ubifs_sb_node *sb; + const struct ubifs_sb_node *sb; sb = blkid_probe_get_sb(pr, mag, struct ubifs_sb_node); if (!sb) diff --git a/libblkid/src/superblocks/udf.c b/libblkid/src/superblocks/udf.c index 36adf60..76d4236 100644 --- a/libblkid/src/superblocks/udf.c +++ b/libblkid/src/superblocks/udf.c @@ -233,6 +233,7 @@ static int probe_udf(blkid_probe pr, size_t i; uint32_t vsd_len; uint16_t udf_rev = 0; + int is_udf = 0; int vsd_2048_valid = -1; int have_label = 0; int have_uuid = 0; @@ -343,6 +344,8 @@ anchor: return 1; real_blksz: + /* At this stage we detected ISO/IEC 13346 or ECMA-167 filesystem recognition sequence, it does not have to be UDF */ + /* Use the actual block size from here on out */ bs = pbs[i]; @@ -454,11 +457,17 @@ real_blksz: lvid_loc = le32_to_cpu(vd->type.logical.lvid_location); } } - if (!udf_rev) { - /* UDF-2.60: 2.1.5.3: UDF revision field shall indicate revision of UDF document - * We use maximal value from this field and from LVIDIU fields for ID_FS_VERSION */ - if (strncmp(vd->type.logical.domain_id, "*OSTA UDF Compliant", sizeof(vd->type.logical.domain_id)) == 0) - udf_rev = le16_to_cpu(vd->type.logical.udf_rev); + if (!is_udf || !udf_rev) { + /* UDF-2.60: 2.2.4.3: This field shall indicate that the contents of + * this logical volume conforms to the domain defined in this document. + * This distinguish UDF from all other ISO/IEC 13346 and ECMA-167 filesystems. */ + if (strncmp(vd->type.logical.domain_id, "*OSTA UDF Compliant", sizeof(vd->type.logical.domain_id)) == 0) { + is_udf = 1; + /* UDF-2.60: 2.1.5.3: UDF revision field shall indicate revision of UDF document + * We use maximal value from this field and from LVIDIU fields for ID_FS_VERSION */ + if (!udf_rev) + udf_rev = le16_to_cpu(vd->type.logical.udf_rev); + } } if ((!have_logvolid || !have_label) && is_charset_udf(vd->type.logical.desc_charset)) { /* LogicalVolumeIdentifier in UDF 2.01 specification: @@ -520,10 +529,15 @@ real_blksz: vd->type.imp_use_volume.lvinfo1.c, clen, enc); } } - if (have_volid && have_uuid && have_volsetid && have_logvolid && have_label && lvid_len && lvid_loc && have_applicationid && have_publisherid) + if (is_udf && have_volid && have_uuid && have_volsetid && have_logvolid && have_label && lvid_len && lvid_loc && have_applicationid && have_publisherid) break; } + if (!is_udf) { + /* We detected some other ISO/IEC 13346 or ECMA-167 filesystem, not UDF */ + return 1; + } + /* Pick the first logical volume integrity descriptor and read UDF revision */ if (lvid_loc && lvid_len >= sizeof(*vd)) { vd = (struct volume_descriptor *) @@ -584,6 +598,7 @@ const struct blkid_idinfo udf_idinfo = .flags = BLKID_IDINFO_TOLERANT, .magics = { + /* These magics are generic to all ISO/IEC 13346 and ECMA-167 filesystems, not just UDF */ { .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" }, { .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" }, { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" }, diff --git a/libblkid/src/superblocks/vdo.c b/libblkid/src/superblocks/vdo.c index bec686f..4e9f445 100644 --- a/libblkid/src/superblocks/vdo.c +++ b/libblkid/src/superblocks/vdo.c @@ -25,7 +25,7 @@ struct vdo_super_block { static int probe_vdo(blkid_probe pr, const struct blkid_idmag *mag) { - struct vdo_super_block *vsb; + const struct vdo_super_block *vsb; vsb = blkid_probe_get_sb(pr, mag, struct vdo_super_block); if (!vsb) diff --git a/libblkid/src/superblocks/vfat.c b/libblkid/src/superblocks/vfat.c index 6b4a3ad..5644d89 100644 --- a/libblkid/src/superblocks/vfat.c +++ b/libblkid/src/superblocks/vfat.c @@ -183,8 +183,8 @@ static int search_fat_label(blkid_probe pr, uint64_t offset, uint32_t entries, u static int fat_valid_superblock(blkid_probe pr, const struct blkid_idmag *mag, - struct msdos_super_block *ms, - struct vfat_super_block *vs, + const struct msdos_super_block *ms, + const struct vfat_super_block *vs, uint32_t *cluster_count, uint32_t *fat_size, uint32_t *sect_count) { @@ -276,8 +276,8 @@ extern int blkid_probe_is_vfat(blkid_probe pr); */ int blkid_probe_is_vfat(blkid_probe pr) { - struct vfat_super_block *vs; - struct msdos_super_block *ms; + const struct vfat_super_block *vs; + const struct msdos_super_block *ms; const struct blkid_idmag *mag = NULL; int rc; @@ -301,11 +301,12 @@ int blkid_probe_is_vfat(blkid_probe pr) * Sievers's volume_id library */ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) { - struct vfat_super_block *vs; - struct msdos_super_block *ms; + const struct vfat_super_block *vs; + const struct msdos_super_block *ms; const unsigned char *vol_label = NULL; const unsigned char *boot_label = NULL; - unsigned char *vol_serno = NULL, vol_label_buf[11]; + const unsigned char *vol_serno = NULL; + unsigned char vol_label_buf[11]; uint16_t sector_size = 0, reserved; uint32_t cluster_count, fat_size, sect_count; const char *version = NULL; @@ -348,7 +349,7 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) version = "FAT16"; } else if (vs->vs_fat32_length) { - unsigned char *buf; + const unsigned char *buf; uint16_t fsinfo_sect; int maxloop = 100; diff --git a/libblkid/src/superblocks/via_raid.c b/libblkid/src/superblocks/via_raid.c index ee3ab65..16e7fc2 100644 --- a/libblkid/src/superblocks/via_raid.c +++ b/libblkid/src/superblocks/via_raid.c @@ -51,8 +51,6 @@ static int probe_viaraid(blkid_probe pr, uint64_t off; struct via_metadata *v; - if (pr->size < 0x10000) - return 1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return 1; @@ -84,6 +82,7 @@ static int probe_viaraid(blkid_probe pr, const struct blkid_idinfo viaraid_idinfo = { .name = "via_raid_member", .usage = BLKID_USAGE_RAID, + .minsz = 0x10000, .probefunc = probe_viaraid, .magics = BLKID_NONE_MAGIC }; diff --git a/libblkid/src/superblocks/vmfs.c b/libblkid/src/superblocks/vmfs.c index fac87ab..3017768 100644 --- a/libblkid/src/superblocks/vmfs.c +++ b/libblkid/src/superblocks/vmfs.c @@ -24,7 +24,7 @@ struct vmfs_volume_info { static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag) { - struct vmfs_fs_info *header; + const struct vmfs_fs_info *header; header = blkid_probe_get_sb(pr, mag, struct vmfs_fs_info); if (header == NULL) @@ -48,8 +48,8 @@ static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag) static int probe_vmfs_volume(blkid_probe pr, const struct blkid_idmag *mag) { - struct vmfs_volume_info *header; - unsigned char *lvm_uuid; + const struct vmfs_volume_info *header; + const unsigned char *lvm_uuid; header = blkid_probe_get_sb(pr, mag, struct vmfs_volume_info); if (header == NULL) diff --git a/libblkid/src/superblocks/vxfs.c b/libblkid/src/superblocks/vxfs.c index be66831..c933861 100644 --- a/libblkid/src/superblocks/vxfs.c +++ b/libblkid/src/superblocks/vxfs.c @@ -25,23 +25,19 @@ struct vxfs_super_block { static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct vxfs_super_block *vxs; + const struct vxfs_super_block *vxs; + enum blkid_endianness e = mag->hint; vxs = blkid_probe_get_sb(pr, mag, struct vxfs_super_block); if (!vxs) return errno ? -errno : 1; - if (le32_to_cpu(vxs->vs_magic) == 0xa501fcf5) { - blkid_probe_sprintf_version(pr, "%u", (unsigned int)le32_to_cpu(vxs->vs_version)); - blkid_probe_set_fsblocksize(pr, le32_to_cpu(vxs->vs_bsize)); - blkid_probe_set_block_size(pr, le32_to_cpu(vxs->vs_bsize)); - blkid_probe_set_fsendianness(pr, BLKID_ENDIANNESS_LITTLE); - } else if (be32_to_cpu(vxs->vs_magic) == 0xa501fcf5) { - blkid_probe_sprintf_version(pr, "%u", (unsigned int)be32_to_cpu(vxs->vs_version)); - blkid_probe_set_fsblocksize(pr, be32_to_cpu(vxs->vs_bsize)); - blkid_probe_set_block_size(pr, be32_to_cpu(vxs->vs_bsize)); - blkid_probe_set_fsendianness(pr, BLKID_ENDIANNESS_BIG); - } + blkid_probe_sprintf_version(pr, "%d", + (unsigned int)blkid32_to_cpu(e, vxs->vs_version)); + blkid_probe_set_fsblocksize(pr, blkid32_to_cpu(e, vxs->vs_bsize)); + blkid_probe_set_block_size(pr, blkid32_to_cpu(e, vxs->vs_bsize)); + blkid_probe_set_fsendianness(pr, e); + return 0; } @@ -53,8 +49,10 @@ const struct blkid_idinfo vxfs_idinfo = .probefunc = probe_vxfs, .magics = { - { .magic = "\365\374\001\245", .len = 4, .kboff = 1 }, - { .magic = "\245\001\374\365", .len = 4, .kboff = 8 }, + { .magic = "\xf5\xfc\x01\xa5", .len = 4, .kboff = 1, + .hint = BLKID_ENDIANNESS_LITTLE }, + { .magic = "\xa5\x01\xfc\xf5", .len = 4, .kboff = 8, + .hint = BLKID_ENDIANNESS_BIG }, { NULL } } }; diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c index f0e099e..0c35982 100644 --- a/libblkid/src/superblocks/xfs.c +++ b/libblkid/src/superblocks/xfs.c @@ -111,7 +111,7 @@ struct xfs_super_block { #define XFS_SB_VERSION2_CRCBIT 0x00000100 -static void sb_from_disk(struct xfs_super_block *from, +static void sb_from_disk(const struct xfs_super_block *from, struct xfs_super_block *to) { @@ -170,7 +170,7 @@ static void sb_from_disk(struct xfs_super_block *from, to->sb_rrmapino = be64_to_cpu(from->sb_rrmapino); } -static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr, +static int xfs_verify_sb(const struct xfs_super_block *ondisk, blkid_probe pr, const struct blkid_idmag *mag) { struct xfs_super_block sb, *sbp = &sb; @@ -206,7 +206,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr, if ((sbp->sb_versionnum & 0x0f) == 5) { uint32_t expected, crc; - unsigned char *csummed; + const unsigned char *csummed; if (!(sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT)) return 0; @@ -230,7 +230,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr, return 1; } -static uint64_t xfs_fssize(struct xfs_super_block *xs) +static uint64_t xfs_fssize(const struct xfs_super_block *xs) { uint32_t lsize = xs->sb_logstart ? xs->sb_logblocks : 0; uint64_t avail_blocks = be64_to_cpu(xs->sb_dblocks) - be32_to_cpu(lsize); @@ -241,7 +241,7 @@ static uint64_t xfs_fssize(struct xfs_super_block *xs) static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag) { - struct xfs_super_block *xs; + const struct xfs_super_block *xs; xs = blkid_probe_get_sb(pr, mag, struct xfs_super_block); if (!xs) @@ -331,7 +331,7 @@ static int probe_xfs_log(blkid_probe pr, { int i; struct xlog_rec_header *rhead; - unsigned char *buf; + const unsigned char *buf; buf = blkid_probe_get_buffer(pr, 0, 256*1024); if (!buf) diff --git a/libblkid/src/superblocks/zfs.c b/libblkid/src/superblocks/zfs.c index 1fcc384..008a200 100644 --- a/libblkid/src/superblocks/zfs.c +++ b/libblkid/src/superblocks/zfs.c @@ -71,13 +71,13 @@ struct nvlist { struct nvpair nvl_nvpair; }; -static void zfs_process_value(blkid_probe pr, char *name, size_t namelen, - void *value, size_t max_value_size, unsigned directory_level) +static void zfs_process_value(blkid_probe pr, const char *name, size_t namelen, + const void *value, size_t max_value_size, unsigned directory_level) { if (strncmp(name, "name", namelen) == 0 && sizeof(struct nvstring) <= max_value_size && !directory_level) { - struct nvstring *nvs = value; + const struct nvstring *nvs = value; uint32_t nvs_type = be32_to_cpu(nvs->nvs_type); uint32_t nvs_strlen = be32_to_cpu(nvs->nvs_strlen); @@ -92,7 +92,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen, } else if (strncmp(name, "guid", namelen) == 0 && sizeof(struct nvuint64) <= max_value_size && !directory_level) { - struct nvuint64 *nvu = value; + const struct nvuint64 *nvu = value; uint32_t nvu_type = be32_to_cpu(nvu->nvu_type); uint64_t nvu_value; @@ -110,7 +110,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen, } else if (strncmp(name, "pool_guid", namelen) == 0 && sizeof(struct nvuint64) <= max_value_size && !directory_level) { - struct nvuint64 *nvu = value; + const struct nvuint64 *nvu = value; uint32_t nvu_type = be32_to_cpu(nvu->nvu_type); uint64_t nvu_value; @@ -128,7 +128,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen, "%"PRIu64, nvu_value); } else if (strncmp(name, "ashift", namelen) == 0 && sizeof(struct nvuint64) <= max_value_size) { - struct nvuint64 *nvu = value; + const struct nvuint64 *nvu = value; uint32_t nvu_type = be32_to_cpu(nvu->nvu_type); uint64_t nvu_value; @@ -147,9 +147,9 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen, static void zfs_extract_guid_name(blkid_probe pr, loff_t offset) { - unsigned char *p; - struct nvlist *nvl; - struct nvpair *nvp; + const unsigned char *p; + const struct nvlist *nvl; + const struct nvpair *nvp; size_t left = 4096; unsigned directory_level = 0; @@ -166,16 +166,16 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset) DBG(LOWPROBE, ul_debug("zfs_extract: nvlist offset %jd", (intmax_t)offset)); - nvl = (struct nvlist *) p; + nvl = (const struct nvlist *) p; nvp = &nvl->nvl_nvpair; - left -= (unsigned char *)nvp - p; /* Already used up 12 bytes */ + left -= (const unsigned char *)nvp - p; /* Already used up 12 bytes */ while (left > sizeof(*nvp)) { uint32_t nvp_size = be32_to_cpu(nvp->nvp_size); uint32_t nvp_namelen = be32_to_cpu(nvp->nvp_namelen); uint64_t namesize = ((uint64_t)nvp_namelen + 3) & ~3; size_t max_value_size; - void *value; + const void *value; if (!nvp->nvp_size) { if (!directory_level) @@ -201,7 +201,7 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset) value = nvp->nvp_name + namesize; if (sizeof(struct nvdirectory) <= max_value_size) { - struct nvdirectory *nvu = value; + const struct nvdirectory *nvu = value; if (be32_to_cpu(nvu->nvd_type) == DATA_TYPE_DIRECTORY) { nvp_size = sizeof(*nvp) + namesize + sizeof(*nvu); directory_level++; @@ -259,7 +259,7 @@ static int probe_zfs(blkid_probe pr, struct zfs_uberblock *ub = NULL; loff_t offset = 0, ub_offset = 0; int label_no, found = 0, found_in_label; - void *label; + const void *label; loff_t blk_align = (pr->size % (256 * 1024ULL)); DBG(PROBE, ul_debug("probe_zfs")); diff --git a/libblkid/src/superblocks/zonefs.c b/libblkid/src/superblocks/zonefs.c index 8aa45b0..e8fcab3 100644 --- a/libblkid/src/superblocks/zonefs.c +++ b/libblkid/src/superblocks/zonefs.c @@ -54,7 +54,7 @@ static int zonefs_verify_csum(blkid_probe pr, const struct zonefs_super *sb) uint32_t expected = le32_to_cpu(sb->s_crc); uint32_t crc = ul_crc32_exclude_offset( ~0LL, (unsigned char *) sb, sizeof(*sb), - offsetof(typeof(*sb), s_crc), sizeof(sb->s_crc)); + offsetof(__typeof__(*sb), s_crc), sizeof(sb->s_crc)); return blkid_probe_verify_csum(pr, crc, expected); } |