]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: linux_raid: add checksum support
authorThomas Weißschuh <thomas@t-8ch.de>
Sun, 11 Sep 2022 15:05:09 +0000 (17:05 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Tue, 13 Sep 2022 08:05:25 +0000 (10:05 +0200)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
libblkid/src/superblocks/linux_raid.c

index 4388e5650842cf622bd4e7121a35dad970cff2b8..360cd4eb3491559da6d18ff6c34d05a165332198 100644 (file)
@@ -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,