]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: Check offset in LUKS2 header
authorMilan Broz <gmazyland@gmail.com>
Fri, 16 Feb 2024 15:44:12 +0000 (16:44 +0100)
committerMilan Broz <gmazyland@gmail.com>
Fri, 16 Feb 2024 16:53:30 +0000 (17:53 +0100)
LUKS2 binary header contains offset field that describes where
the header should be located.

If this offset is not correct, blkid should tread this header
as invalid.

This patch fixes problem when both swap and LUKS headers are
present (LUKS header was swapped out) and detected LUKS header
is at a wrong offset.
As LUKS has higher priority, it confuses detection.

Signed-off-by: Milan Broz <gmazyland@gmail.com>
libblkid/src/superblocks/luks.c
tests/expected/blkid/low-probe-swap-luks [new file with mode: 0644]
tests/ts/blkid/images-fs/swap-luks.img.xz [new file with mode: 0644]

index 0230b349267081966641122a0dbbecc57df47e6d..4623c98fc9d64db75504a7b09b4566cec2f2dc30 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
- * Copyright (C) 2018 Milan Broz <gmazyland@gmail.com>
+ * Copyright (C) 2018-2024 Milan Broz <gmazyland@gmail.com>
  *
  * Inspired by libvolume_id by
  *     Kay Sievers <kay.sievers@vrfy.org>
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "superblocks.h"
 
@@ -96,6 +97,19 @@ static int luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t o
        return BLKID_PROBE_OK;
 }
 
+static bool luks_valid(struct luks2_phdr *header, const char *magic, uint64_t offset)
+{
+       if (memcmp(header->magic, magic, LUKS_MAGIC_L))
+               return false;
+
+       /* LUKS2 header is not at expected offset */
+       if (be16_to_cpu(header->version) == 2 &&
+           be64_to_cpu(header->hdr_offset) != offset)
+               return false;
+
+       return true;
+}
+
 static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__)))
 {
        struct luks2_phdr *header;
@@ -105,7 +119,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_
        if (!header)
                return errno ? -errno : BLKID_PROBE_NONE;
 
-       if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) {
+       if (luks_valid(header, LUKS_MAGIC, 0)) {
                /* LUKS primary header was found. */
                return luks_attributes(pr, header, 0);
        }
@@ -118,7 +132,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_
                if (!header)
                        return errno ? -errno : BLKID_PROBE_NONE;
 
-               if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L))
+               if (luks_valid(header, LUKS_MAGIC_2, secondary_offsets[i]))
                        return luks_attributes(pr, header, secondary_offsets[i]);
        }
 
diff --git a/tests/expected/blkid/low-probe-swap-luks b/tests/expected/blkid/low-probe-swap-luks
new file mode 100644 (file)
index 0000000..97cd5de
--- /dev/null
@@ -0,0 +1,8 @@
+ID_FS_ENDIANNESS=LITTLE
+ID_FS_FSBLOCKSIZE=4096
+ID_FS_FSSIZE=258048
+ID_FS_TYPE=swap
+ID_FS_USAGE=other
+ID_FS_UUID=0eb5f96f-188d-4d61-9e9c-d89ce8206846
+ID_FS_UUID_ENC=0eb5f96f-188d-4d61-9e9c-d89ce8206846
+ID_FS_VERSION=1
diff --git a/tests/ts/blkid/images-fs/swap-luks.img.xz b/tests/ts/blkid/images-fs/swap-luks.img.xz
new file mode 100644 (file)
index 0000000..9b5cb65
Binary files /dev/null and b/tests/ts/blkid/images-fs/swap-luks.img.xz differ