124 lines
3.2 KiB
Diff
124 lines
3.2 KiB
Diff
From c5c47008f240ba96c4f3b676349b64cd22eadb14 Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Mon, 13 Oct 2025 13:21:27 +0200
|
|
Subject: libblkid: (jmicron_raid) backport checksum verification
|
|
|
|
Backported from RHEL-10. The original code produces false positives.
|
|
|
|
Addresses: https://issues.redhat.com/browse/RHEL-108386
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libblkid/src/superblocks/jmicron_raid.c | 74 ++++++++++++++++++++-----
|
|
1 file changed, 61 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/libblkid/src/superblocks/jmicron_raid.c b/libblkid/src/superblocks/jmicron_raid.c
|
|
index ca7986733..4587075ca 100644
|
|
--- a/libblkid/src/superblocks/jmicron_raid.c
|
|
+++ b/libblkid/src/superblocks/jmicron_raid.c
|
|
@@ -16,23 +16,65 @@
|
|
|
|
#include "superblocks.h"
|
|
|
|
-struct jm_metadata {
|
|
- int8_t signature[2];
|
|
- uint8_t minor_version;
|
|
- uint8_t major_version;
|
|
- uint16_t checksum;
|
|
-};
|
|
-
|
|
#define JM_SIGNATURE "JM"
|
|
+#define JM_MINOR_VERSION(_x) (le16_to_cpu((_x)->version) & 0xFF)
|
|
+#define JM_MAJOR_VERSION(_x) (le16_to_cpu((_x)->version) >> 8)
|
|
+#define JM_SPARES 2
|
|
+#define JM_MEMBERS 8
|
|
+
|
|
+struct jm_metadata {
|
|
+ int8_t signature[2]; /* 0x0 - 0x01 */
|
|
+
|
|
+ uint16_t version; /* 0x03 - 0x04 JMicron version */
|
|
+
|
|
+ uint16_t checksum; /* 0x04 - 0x05 */
|
|
+ uint8_t filler[10];
|
|
+
|
|
+ uint32_t identity; /* 0x10 - 0x13 */
|
|
+
|
|
+ struct {
|
|
+ uint32_t base; /* 0x14 - 0x17 */
|
|
+ uint32_t range; /* 0x18 - 0x1B range */
|
|
+ uint16_t range2; /* 0x1C - 0x1D range2 */
|
|
+ } segment;
|
|
+
|
|
+ int8_t name[16]; /* 0x20 - 0x2F */
|
|
+
|
|
+ uint8_t mode; /* 0x30 RAID level */
|
|
+ uint8_t block; /* 0x31 stride size (2=4K, 3=8K, ...) */
|
|
+ uint16_t attribute; /* 0x32 - 0x33 */
|
|
+ uint8_t filler1[4];
|
|
+
|
|
+ uint32_t spare[JM_SPARES]; /* 0x38 - 0x3F */
|
|
+ uint32_t member[JM_MEMBERS]; /* 0x40 - 0x5F */
|
|
+
|
|
+ uint8_t filler2[0x20];
|
|
+} __attribute__ ((packed));
|
|
+
|
|
+static int jm_checksum(blkid_probe pr, const struct jm_metadata *jm)
|
|
+{
|
|
+ size_t count = sizeof(*jm) / sizeof(uint16_t);
|
|
+ uint16_t sum = 0;
|
|
+ unsigned char *ptr = (unsigned char *) jm;
|
|
+
|
|
+ while (count--) {
|
|
+ uint16_t val;
|
|
+
|
|
+ memcpy(&val, ptr, sizeof(uint16_t));
|
|
+ sum += le16_to_cpu(val);
|
|
+
|
|
+ ptr += sizeof(uint16_t);
|
|
+ }
|
|
+
|
|
+ return blkid_probe_verify_csum(pr, sum == 0 || sum == 1, 1);
|
|
+}
|
|
|
|
static int probe_jmraid(blkid_probe pr,
|
|
const struct blkid_idmag *mag __attribute__((__unused__)))
|
|
{
|
|
uint64_t off;
|
|
- struct jm_metadata *jm;
|
|
+ const struct jm_metadata *jm;
|
|
|
|
- if (pr->size < 0x10000)
|
|
- return 1;
|
|
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
|
|
return 1;
|
|
|
|
@@ -46,8 +88,15 @@ static int probe_jmraid(blkid_probe pr,
|
|
|
|
if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0)
|
|
return 1;
|
|
+
|
|
+ if (!jm_checksum(pr, jm))
|
|
+ return 1;
|
|
+
|
|
+ if (jm->mode > 5)
|
|
+ return 1;
|
|
+
|
|
if (blkid_probe_sprintf_version(pr, "%u.%u",
|
|
- jm->major_version, jm->minor_version) != 0)
|
|
+ JM_MAJOR_VERSION(jm), JM_MINOR_VERSION(jm)) != 0)
|
|
return 1;
|
|
if (blkid_probe_set_magic(pr, off, sizeof(jm->signature),
|
|
(unsigned char *) jm->signature))
|
|
@@ -58,8 +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
|
|
};
|
|
-
|
|
-
|
|
--
|
|
2.51.0
|
|
|