diff --git a/include/crc32.h b/include/crc32.h index 0d34da0d249..c78d291b016 100644 --- a/include/crc32.h +++ b/include/crc32.h @@ -10,7 +10,8 @@ extern uint32_t ul_crc32(uint32_t seed, const unsigned char *buf, size_t len); extern uint32_t ul_crc32_exclude_offset(uint32_t seed, const unsigned char *buf, size_t len, - size_t exclude_off, size_t exclude_len); + size_t exclude_off, size_t exclude_len, + uint8_t exclude_fill); #endif diff --git a/lib/crc32.c b/lib/crc32.c index 824693d017a..b62b9f63807 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -122,7 +122,7 @@ uint32_t ul_crc32(uint32_t seed, const unsigned char *buf, size_t len) } uint32_t ul_crc32_exclude_offset(uint32_t seed, const unsigned char *buf, size_t len, - size_t exclude_off, size_t exclude_len) + size_t exclude_off, size_t exclude_len, uint8_t exclude_fill) { uint32_t crc = seed; const unsigned char *p = buf; @@ -132,7 +132,7 @@ uint32_t ul_crc32_exclude_offset(uint32_t seed, const unsigned char *buf, size_t unsigned char x = *p++; if (i >= exclude_off && i < exclude_off + exclude_len) - x = 0; + x = exclude_fill; crc = crc32_add_char(crc, x); } diff --git a/libblkid/src/partitions/gpt.c b/libblkid/src/partitions/gpt.c index a8846be21f2..dc5bcf3aa44 100644 --- a/libblkid/src/partitions/gpt.c +++ b/libblkid/src/partitions/gpt.c @@ -106,7 +106,7 @@ struct gpt_entry { static inline uint32_t count_crc32(const unsigned char *buf, size_t len, size_t exclude_off, size_t exclude_len) { - return (ul_crc32_exclude_offset(~0L, buf, len, exclude_off, exclude_len) ^ ~0L); + return (ul_crc32_exclude_offset(~0L, buf, len, exclude_off, exclude_len, 0) ^ ~0L); } static inline const unsigned char *get_lba_buffer(blkid_probe pr, diff --git a/libblkid/src/superblocks/cramfs.c b/libblkid/src/superblocks/cramfs.c index 6a8731f7bf7..d9f3ed19d8a 100644 --- a/libblkid/src/superblocks/cramfs.c +++ b/libblkid/src/superblocks/cramfs.c @@ -64,7 +64,7 @@ static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag, crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size, offsetof(struct cramfs_super, info.crc), - sizeof_member(struct cramfs_super, info.crc)); + sizeof_member(struct cramfs_super, info.crc), 0); return blkid_probe_verify_csum(pr, crc, expected); } diff --git a/libblkid/src/superblocks/ddf_raid.c b/libblkid/src/superblocks/ddf_raid.c index a7cf32cf409..bf346330f9c 100644 --- a/libblkid/src/superblocks/ddf_raid.c +++ b/libblkid/src/superblocks/ddf_raid.c @@ -13,6 +13,7 @@ #include #include +#include "crc32.h" #include "superblocks.h" /* http://www.snia.org/standards/home */ @@ -71,25 +72,39 @@ struct ddf_header { uint8_t pad4[256]; /* 0xff */ } __attribute__((packed)); +static int ddf_verify_csum(blkid_probe pr, const struct ddf_header *ddf) +{ + uint32_t expected, crc; + + expected = be32_to_cpu(ddf->crc); + + crc = ul_crc32_exclude_offset(0, + (const unsigned char *)ddf, sizeof(*ddf), + offsetof(__typeof__(*ddf), crc), + sizeof_member(__typeof__(*ddf), crc), + 0xff); + + return blkid_probe_verify_csum(pr, crc, expected); +} + static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) { int hdrs[] = { 1, 257 }; size_t i; - struct ddf_header *ddf = NULL; + const struct ddf_header *ddf = NULL; char version[DDF_REV_LENGTH + 1]; uint64_t off = 0, lba; for (i = 0; i < ARRAY_SIZE(hdrs); i++) { off = ((pr->size / 0x200) - hdrs[i]) * 0x200; - ddf = (struct ddf_header *) blkid_probe_get_buffer(pr, + ddf = (const struct ddf_header *) blkid_probe_get_buffer(pr, off, sizeof(struct ddf_header)); if (!ddf) return errno ? -errno : 1; - if (ddf->signature == cpu_to_be32(DDF_MAGIC) || - ddf->signature == cpu_to_le32(DDF_MAGIC)) + if (ddf->signature == cpu_to_be32(DDF_MAGIC) && ddf_verify_csum(pr, ddf)) break; ddf = NULL; } @@ -97,9 +112,7 @@ static int probe_ddf(blkid_probe pr, if (!ddf) return 1; - lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ? - be64_to_cpu(ddf->primary_lba) : - le64_to_cpu(ddf->primary_lba); + lba = be64_to_cpu(ddf->primary_lba); if (lba > 0) { /* check primary header */ @@ -123,7 +136,7 @@ static int probe_ddf(blkid_probe pr, return 1; if (blkid_probe_set_magic(pr, off, sizeof(ddf->signature), - (unsigned char *) &ddf->signature)) + (const unsigned char *) &ddf->signature)) return 1; return 0; } diff --git a/libblkid/src/superblocks/zonefs.c b/libblkid/src/superblocks/zonefs.c index e8fcab34fe3..8534e2ffe40 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), 0); return blkid_probe_verify_csum(pr, crc, expected); } diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 374246ce6be..2f850fa8a12 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -1043,7 +1043,7 @@ static unsigned char *gpt_read_entries(struct fdisk_context *cxt, static inline uint32_t count_crc32(const unsigned char *buf, size_t len, size_t ex_off, size_t ex_len) { - return (ul_crc32_exclude_offset(~0L, buf, len, ex_off, ex_len) ^ ~0L); + return (ul_crc32_exclude_offset(~0L, buf, len, ex_off, ex_len, 0) ^ ~0L); } static inline uint32_t gpt_header_count_crc32(struct gpt_header *header)