dcavalca / rpms / util-linux

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