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