Blame SOURCES/0001-libblkid-Check-for-a-secondary-LUKS2-header.patch

cbc4cf
From 768b91ef6f68661462494bed800505064eb97bc8 Mon Sep 17 00:00:00 2001
cbc4cf
From: Milan Broz <gmazyland@gmail.com>
cbc4cf
Date: Wed, 11 Jul 2018 12:34:39 +0200
cbc4cf
Subject: [PATCH 1/6] libblkid: Check for a secondary LUKS2 header.
cbc4cf
cbc4cf
This patch adds search for a secondary LUKS2 header,
cbc4cf
if the primary one is corrupted.
cbc4cf
cbc4cf
This patch is primarily needed for wipefs that should wipe
cbc4cf
both signatures (otherwise LUKS2 header recovery can use
cbc4cf
secondary header and revert wipefs action).
cbc4cf
cbc4cf
Signed-off-by: Milan Broz <gmazyland@gmail.com>
cbc4cf
Upstream: http://github.com/karelzak/util-linux/commit/8bee1a220db8effbe5a75ba9bc68840e019ea89a
cbc4cf
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1595882
cbc4cf
---
cbc4cf
 libblkid/src/superblocks/luks.c | 60 ++++++++++++++++++++++++++++++++---------
cbc4cf
 1 file changed, 47 insertions(+), 13 deletions(-)
cbc4cf
cbc4cf
diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c
cbc4cf
index bc3d7f558..67d7cfcc5 100644
cbc4cf
--- a/libblkid/src/superblocks/luks.c
cbc4cf
+++ b/libblkid/src/superblocks/luks.c
cbc4cf
@@ -1,5 +1,6 @@
cbc4cf
 /*
cbc4cf
  * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
cbc4cf
+ * Copyright (C) 2018 Milan Broz <gmazyland@gmail.com>
cbc4cf
  *
cbc4cf
  * Inspired by libvolume_id by
cbc4cf
  *     Kay Sievers <kay.sievers@vrfy.org>
cbc4cf
@@ -29,6 +30,15 @@
cbc4cf
 #define LUKS2_CHECKSUM_ALG_L		32
cbc4cf
 #define LUKS2_CHECKSUM_L		64
cbc4cf
 
cbc4cf
+#define LUKS_MAGIC	"LUKS\xba\xbe"
cbc4cf
+#define LUKS_MAGIC_2	"SKUL\xba\xbe"
cbc4cf
+
cbc4cf
+/* Offsets for secondary header (for scan if primary header is corrupted). */
cbc4cf
+#define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \
cbc4cf
+                             0x40000, 0x080000, 0x100000, 0x200000, 0x400000 }
cbc4cf
+
cbc4cf
+static const uint64_t secondary_offsets[] = LUKS2_HDR2_OFFSETS;
cbc4cf
+
cbc4cf
 struct luks_phdr {
cbc4cf
 	uint8_t		magic[LUKS_MAGIC_L];
cbc4cf
 	uint16_t	version;
cbc4cf
@@ -59,18 +69,16 @@ struct luks2_phdr {
cbc4cf
 	/* Padding to 4k, then JSON area */
cbc4cf
 } __attribute__ ((packed));
cbc4cf
 
cbc4cf
-static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag)
cbc4cf
+static int luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t offset)
cbc4cf
 {
cbc4cf
-	struct luks_phdr *header_v1;
cbc4cf
-	struct luks2_phdr *header;
cbc4cf
 	int version;
cbc4cf
+	struct luks_phdr *header_v1;
cbc4cf
 
cbc4cf
-	header = blkid_probe_get_sb(pr, mag, struct luks2_phdr);
cbc4cf
-	if (header == NULL)
cbc4cf
-		return errno ? -errno : 1;
cbc4cf
+	if (blkid_probe_set_magic(pr, offset, LUKS_MAGIC_L, (unsigned char *) &header->magic))
cbc4cf
+		return BLKID_PROBE_NONE;
cbc4cf
 
cbc4cf
 	version = be16_to_cpu(header->version);
cbc4cf
-	blkid_probe_sprintf_version(pr, "%u", be16_to_cpu(header->version));
cbc4cf
+	blkid_probe_sprintf_version(pr, "%u", version);
cbc4cf
 
cbc4cf
 	if (version == 1) {
cbc4cf
 		header_v1 = (struct luks_phdr *)header;
cbc4cf
@@ -84,7 +92,37 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag)
cbc4cf
 		blkid_probe_set_id_label(pr, "SUBSYSTEM",
cbc4cf
 			(unsigned char *) header->subsystem, LUKS2_LABEL_L);
cbc4cf
 	}
cbc4cf
-	return 0;
cbc4cf
+
cbc4cf
+	return BLKID_PROBE_OK;
cbc4cf
+}
cbc4cf
+
cbc4cf
+static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__)))
cbc4cf
+{
cbc4cf
+	struct luks2_phdr *header;
cbc4cf
+	size_t i;
cbc4cf
+
cbc4cf
+	header = (struct luks2_phdr *) blkid_probe_get_buffer(pr, 0, sizeof(struct luks2_phdr));
cbc4cf
+	if (!header)
cbc4cf
+		return errno ? -errno : BLKID_PROBE_NONE;
cbc4cf
+
cbc4cf
+	if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) {
cbc4cf
+		/* LUKS primary header was found. */
cbc4cf
+		return luks_attributes(pr, header, 0);
cbc4cf
+	} else {
cbc4cf
+		/* No primary header, scan for known offsets of LUKS2 secondary header. */
cbc4cf
+		for (i = 0; i < ARRAY_SIZE(secondary_offsets); i++) {
cbc4cf
+			header = (struct luks2_phdr *) blkid_probe_get_buffer(pr,
cbc4cf
+				  secondary_offsets[i], sizeof(struct luks2_phdr));
cbc4cf
+
cbc4cf
+			if (!header)
cbc4cf
+				return errno ? -errno : BLKID_PROBE_NONE;
cbc4cf
+
cbc4cf
+			if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L))
cbc4cf
+				return luks_attributes(pr, header, secondary_offsets[i]);
cbc4cf
+		}
cbc4cf
+	}
cbc4cf
+
cbc4cf
+	return BLKID_PROBE_NONE;
cbc4cf
 }
cbc4cf
 
cbc4cf
 const struct blkid_idinfo luks_idinfo =
cbc4cf
@@ -92,9 +130,5 @@ const struct blkid_idinfo luks_idinfo =
cbc4cf
 	.name		= "crypto_LUKS",
cbc4cf
 	.usage		= BLKID_USAGE_CRYPTO,
cbc4cf
 	.probefunc	= probe_luks,
cbc4cf
-	.magics		=
cbc4cf
-	{
cbc4cf
-		{ .magic = "LUKS\xba\xbe", .len = 6 },
cbc4cf
-		{ NULL }
cbc4cf
-	}
cbc4cf
+	.magics		= BLKID_NONE_MAGIC
cbc4cf
 };
cbc4cf
-- 
cbc4cf
2.14.4
cbc4cf