]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: fix jmicron checksum and LE to CPU
authorKarel Zak <kzak@redhat.com>
Fri, 21 Oct 2022 16:11:59 +0000 (18:11 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 21 Oct 2022 16:11:59 +0000 (18:11 +0200)
- don't cast packed struct to uint16_t pointer, use temporary value
- calculate real count for the loop
- convert all to LE for checksum calculation (jm_to_cpu() ignores fillers)

Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/superblocks/jmicron_raid.c

index ab2c829f0a4eba5b84d6853eba9addcd9fb45aab..580c38533b3ee5e38d8d85d5b00026aea37813e1 100644 (file)
@@ -55,35 +55,38 @@ static void jm_to_cpu(struct jm_metadata *jm)
 {
        unsigned int i;
 
-       le16_to_cpu(jm->version);
-       le16_to_cpu(jm->checksum);
-       le32_to_cpu(jm->identity);
+       jm->version = le16_to_cpu(jm->version);
+       jm->checksum = le16_to_cpu(jm->checksum);
+       jm->identity = le32_to_cpu(jm->identity);
+       jm->segment.base = le32_to_cpu(jm->segment.base);
+       jm->segment.range = le32_to_cpu(jm->segment.range);
+       jm->segment.range2 = le16_to_cpu(jm->segment.range2);
 
-       le32_to_cpu(jm->segment.base);
-       le32_to_cpu(jm->segment.range);
-       le16_to_cpu(jm->segment.range2);
-
-       le16_to_cpu(jm->attribute);
+       jm->attribute = le16_to_cpu(jm->attribute);
 
        for (i = 0; i < JM_SPARES; i++)
-               le32_to_cpu(jm->spare[i]);
+               jm->spare[i] = le32_to_cpu(jm->spare[i]);
 
        for (i = 0; i < JM_MEMBERS; i++)
-               le32_to_cpu(jm->member[i]);
+               jm->member[i] = le32_to_cpu(jm->member[i]);
 }
 
-static int jm_checksum(struct jm_metadata *jm)
+static int jm_checksum(const struct jm_metadata *jm)
 {
-       size_t count = 64;
-       char *buf = (char *) jm;
-       uint16_t *p = (uint16_t *) buf, sum = 0;
+        size_t count = sizeof(*jm) / sizeof(uint16_t);
+        uint16_t sum = 0;
+        unsigned char *ptr = (unsigned char *) jm;
+
+        while (count--) {
+                uint16_t val;
 
-       assert(count <= sizeof(struct jm_metadata));
+                memcpy(&val, ptr, sizeof(uint16_t));
+                sum += le16_to_cpu(val);
 
-       while (count--)
-               sum += *p++;
+                ptr += sizeof(uint16_t);
+        }
 
-       return !sum || sum == 1;
+        return sum == 0 || sum == 1;
 }
 
 static int probe_jmraid(blkid_probe pr,
@@ -108,9 +111,12 @@ static int probe_jmraid(blkid_probe pr,
        if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0)
                return 1;
 
+       if (!jm_checksum(jm))
+               return 1;
+
        jm_to_cpu(jm);
 
-       if (!jm_checksum(jm))
+       if (jm->mode > 5)
                return 1;
 
        if (blkid_probe_sprintf_version(pr, "%u.%u",