76 lines
2.2 KiB
Diff
76 lines
2.2 KiB
Diff
|
|
From 2011a616aa533c336f9242f25017ce7043557e4c Mon Sep 17 00:00:00 2001
|
||
|
|
From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas@t-8ch.de>
|
||
|
|
Date: Tue, 6 Aug 2024 19:07:48 +0200
|
||
|
|
Subject: [PATCH] libblkid: apfs: validate checksums
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
The apfs superblock contains a checksum based on Fletcher-64.
|
||
|
|
Validate the checksum to make the probing more robust.
|
||
|
|
|
||
|
|
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
|
||
|
|
Reference:https://github.com/util-linux/util-linux/commit/2011a616aa533c336f9242f25017ce7043557e4c
|
||
|
|
Conflict:NA
|
||
|
|
---
|
||
|
|
libblkid/src/superblocks/apfs.c | 36 ++++++++++++++++++++++++++++++++-
|
||
|
|
1 file changed, 35 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/libblkid/src/superblocks/apfs.c b/libblkid/src/superblocks/apfs.c
|
||
|
|
index b7f09f33..4557abcb 100644
|
||
|
|
--- a/libblkid/src/superblocks/apfs.c
|
||
|
|
+++ b/libblkid/src/superblocks/apfs.c
|
||
|
|
@@ -35,7 +35,38 @@ struct apfs_super_block {
|
||
|
|
uint64_t read_only_features;
|
||
|
|
uint64_t incompatible_features;
|
||
|
|
uint8_t uuid[16];
|
||
|
|
-};
|
||
|
|
+
|
||
|
|
+ uint8_t padding[4008]; // Pad to 4096 bytes for checksum
|
||
|
|
+} __attribute__((packed));
|
||
|
|
+
|
||
|
|
+static uint64_t apfs_fletcher64(const uint8_t *buf, size_t size)
|
||
|
|
+{
|
||
|
|
+ uint64_t lo32 = 0, hi32 = 0, csum_hi;
|
||
|
|
+ uint32_t csum_low;
|
||
|
|
+ size_t i;
|
||
|
|
+
|
||
|
|
+ for (i = 0; i < size / 4; i++) {
|
||
|
|
+ lo32 += le32_to_cpu(((uint32_t *)buf)[i]);
|
||
|
|
+ hi32 += lo32;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ csum_low = ~((lo32 + hi32) % UINT32_MAX);
|
||
|
|
+ csum_hi = ~((lo32 + csum_low) % UINT32_MAX);
|
||
|
|
+
|
||
|
|
+ return csum_hi << 32 | csum_low;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int apfs_verify_checksum(blkid_probe pr,
|
||
|
|
+ const struct apfs_super_block *sb)
|
||
|
|
+{
|
||
|
|
+ const size_t csummed_start_offset = offsetof(__typeof__(*sb), oid);
|
||
|
|
+ uint64_t csum;
|
||
|
|
+
|
||
|
|
+ csum = apfs_fletcher64(((const uint8_t *)sb) + csummed_start_offset,
|
||
|
|
+ sizeof(*sb) - csummed_start_offset);
|
||
|
|
+
|
||
|
|
+ return blkid_probe_verify_csum(pr, csum, le64_to_cpu(sb->checksum));
|
||
|
|
+}
|
||
|
|
|
||
|
|
static int probe_apfs(blkid_probe pr, const struct blkid_idmag *mag)
|
||
|
|
{
|
||
|
|
@@ -45,6 +76,9 @@ static int probe_apfs(blkid_probe pr, const struct blkid_idmag *mag)
|
||
|
|
if (!sb)
|
||
|
|
return errno ? -errno : BLKID_PROBE_NONE;
|
||
|
|
|
||
|
|
+ if (!apfs_verify_checksum(pr, sb))
|
||
|
|
+ return BLKID_PROBE_NONE;
|
||
|
|
+
|
||
|
|
if (le16_to_cpu(sb->type) != APFS_CONTAINER_SUPERBLOCK_TYPE)
|
||
|
|
return BLKID_PROBE_NONE;
|
||
|
|
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|