From c68a29cabfd49052f1ec7fd50e99a03a5252ed01 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sun, 11 Sep 2022 17:05:09 +0200 Subject: [PATCH] libblkid: linux_raid: add checksum support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Weißschuh --- libblkid/src/superblocks/linux_raid.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/libblkid/src/superblocks/linux_raid.c b/libblkid/src/superblocks/linux_raid.c index 4388e56508..360cd4eb34 100644 --- a/libblkid/src/superblocks/linux_raid.c +++ b/libblkid/src/superblocks/linux_raid.c @@ -182,6 +182,32 @@ static int probe_raid0(blkid_probe pr, uint64_t off) return 0; } +static int raid1_verify_csum(blkid_probe pr, off_t off, + const struct mdp1_super_block *mdp1) +{ + 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); + if (!csummed) + return 1; + + memset(csummed + offsetof(struct mdp1_super_block, sb_csum), 0, + sizeof(mdp1->sb_csum)); + + uint64_t csum = 0; + + while (csummed_size >= 4) { + csum += le32_to_cpu(*(uint32_t *) csummed); + csummed_size -= 4; + csummed += 4; + } + if (csummed_size == 2) + csum += le16_to_cpu(*(uint16_t *) csummed); + + csum = (csum >> 32) + (uint32_t) csum; + return blkid_probe_verify_csum(pr, csum, le32_to_cpu(mdp1->sb_csum)); +} + static int probe_raid1(blkid_probe pr, off_t off) { struct mdp1_super_block *mdp1; @@ -198,6 +224,8 @@ static int probe_raid1(blkid_probe pr, off_t off) return 1; if (le64_to_cpu(mdp1->super_offset) != (uint64_t) off >> 9) return 1; + if (!raid1_verify_csum(pr, off, mdp1)) + return 1; if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0) return 1; if (blkid_probe_set_uuid_as(pr, -- 2.47.3