Blame SOURCES/cryptsetup-2.0.4-make-LUKS2-auto-recovery-aware-of-device-signatures.patch

7cdc99
From 078ed81d14904f48a6237646050ba5eb74d702b7 Mon Sep 17 00:00:00 2001
7cdc99
From: Ondrej Kozina <okozina@redhat.com>
7cdc99
Date: Wed, 4 Jul 2018 15:58:09 +0200
7cdc99
Subject: [PATCH 2/6] Make LUKS2 auto-recovery aware of device signatures.
7cdc99
7cdc99
auto-recovery triggers any time when only single correct LUKS2
7cdc99
header instance was found. That may be dangerous.
7cdc99
7cdc99
We should suppress auto-recovery in case blkid decided the
7cdc99
device is no longer LUKS device. For example if secondary (intact)
7cdc99
LUKS2 header was left behind and blkid declares the device is LVM2
7cdc99
member.
7cdc99
7cdc99
Moreover if at least one header instance is corrupted and blkid
7cdc99
declares device non-empty and non-LUKS in the same time, header load
7cdc99
operation will be aborted with error.
7cdc99
---
7cdc99
 lib/internal.h                  |  1 +
7cdc99
 lib/luks2/luks2_disk_metadata.c | 61 ++++++++++++++++++++++++++++++++++++++++-
7cdc99
 lib/luks2/luks2_internal.h      |  2 +-
7cdc99
 lib/luks2/luks2_json_metadata.c |  4 +--
7cdc99
 4 files changed, 64 insertions(+), 4 deletions(-)
7cdc99
7cdc99
diff --git a/lib/internal.h b/lib/internal.h
7cdc99
index 07a1a08..e6d2323 100644
7cdc99
--- a/lib/internal.h
7cdc99
+++ b/lib/internal.h
7cdc99
@@ -32,6 +32,7 @@
7cdc99
 
7cdc99
 #include "nls.h"
7cdc99
 #include "bitops.h"
7cdc99
+#include "utils_blkid.h"
7cdc99
 #include "utils_crypt.h"
7cdc99
 #include "utils_loop.h"
7cdc99
 #include "utils_dm.h"
7cdc99
diff --git a/lib/luks2/luks2_disk_metadata.c b/lib/luks2/luks2_disk_metadata.c
7cdc99
index 4d9bce2..6ca9d5e 100644
7cdc99
--- a/lib/luks2/luks2_disk_metadata.c
7cdc99
+++ b/lib/luks2/luks2_disk_metadata.c
7cdc99
@@ -531,12 +531,59 @@ static json_object *parse_and_validate_json(const char *json_area, int length)
7cdc99
 	return jobj;
7cdc99
 }
7cdc99
 
7cdc99
+static int detect_device_signatures(const char *path)
7cdc99
+{
7cdc99
+	blk_probe_status prb_state;
7cdc99
+	int r;
7cdc99
+	struct blkid_handle *h;
7cdc99
+
7cdc99
+	if (!blk_supported()) {
7cdc99
+		log_dbg("Blkid probing of device signatures disabled.");
7cdc99
+		return 0;
7cdc99
+	}
7cdc99
+
7cdc99
+	if ((r = blk_init_by_path(&h, path))) {
7cdc99
+		log_dbg("Failed to initialize blkid_handle by path.");
7cdc99
+		return -EINVAL;
7cdc99
+	}
7cdc99
+
7cdc99
+	/* We don't care about details. Be fast. */
7cdc99
+	blk_set_chains_for_fast_detection(h);
7cdc99
+
7cdc99
+	/* Filter out crypto_LUKS. we don't care now */
7cdc99
+	blk_superblocks_filter_luks(h);
7cdc99
+
7cdc99
+	prb_state = blk_safeprobe(h);
7cdc99
+
7cdc99
+	switch (prb_state) {
7cdc99
+	case PRB_AMBIGUOUS:
7cdc99
+		log_dbg("Blkid probe couldn't decide device type unambiguously.");
7cdc99
+		/* fall through */
7cdc99
+	case PRB_FAIL:
7cdc99
+		log_dbg("Blkid probe failed.");
7cdc99
+		r = -EINVAL;
7cdc99
+		break;
7cdc99
+	case PRB_OK: /* crypto_LUKS type is filtered out */
7cdc99
+		r = -EINVAL;
7cdc99
+
7cdc99
+		if (blk_is_partition(h))
7cdc99
+			log_dbg("Blkid probe detected partition type '%s'", blk_get_partition_type(h));
7cdc99
+		else if (blk_is_superblock(h))
7cdc99
+			log_dbg("blkid probe detected superblock type '%s'", blk_get_superblock_type(h));
7cdc99
+		break;
7cdc99
+	case PRB_EMPTY:
7cdc99
+		log_dbg("Blkid probe detected no foreign device signature.");
7cdc99
+	}
7cdc99
+	blk_free(h);
7cdc99
+	return r;
7cdc99
+}
7cdc99
+
7cdc99
 /*
7cdc99
  * Read and convert on-disk LUKS2 header to in-memory representation..
7cdc99
  * Try to do recovery if on-disk state is not consistent.
7cdc99
  */
7cdc99
 int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
7cdc99
-			struct device *device, int do_recovery)
7cdc99
+			struct device *device, int do_recovery, int do_blkprobe)
7cdc99
 {
7cdc99
 	enum { HDR_OK, HDR_OBSOLETE, HDR_FAIL, HDR_FAIL_IO } state_hdr1, state_hdr2;
7cdc99
 	struct luks2_hdr_disk hdr_disk1, hdr_disk2;
7cdc99
@@ -616,6 +663,12 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
7cdc99
 	if (state_hdr1 == HDR_OK && state_hdr2 != HDR_OK) {
7cdc99
 		log_dbg("Secondary LUKS2 header requires recovery.");
7cdc99
 
7cdc99
+		if (do_blkprobe && (r = detect_device_signatures(device_path(device)))) {
7cdc99
+			log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
7cdc99
+				      "Please run \"cryptsetup repair\" for recovery."));
7cdc99
+			goto err;
7cdc99
+		}
7cdc99
+
7cdc99
 		if (do_recovery) {
7cdc99
 			memcpy(&hdr_disk2, &hdr_disk1, LUKS2_HDR_BIN_LEN);
7cdc99
 			r = crypt_random_get(NULL, (char*)hdr_disk2.salt, sizeof(hdr_disk2.salt), CRYPT_RND_SALT);
7cdc99
@@ -631,6 +684,12 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
7cdc99
 	} else if (state_hdr1 != HDR_OK && state_hdr2 == HDR_OK) {
7cdc99
 		log_dbg("Primary LUKS2 header requires recovery.");
7cdc99
 
7cdc99
+		if (do_blkprobe && (r = detect_device_signatures(device_path(device)))) {
7cdc99
+			log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
7cdc99
+				      "Please run \"cryptsetup repair\" for recovery."));
7cdc99
+			goto err;
7cdc99
+		}
7cdc99
+
7cdc99
 		if (do_recovery) {
7cdc99
 			memcpy(&hdr_disk1, &hdr_disk2, LUKS2_HDR_BIN_LEN);
7cdc99
 			r = crypt_random_get(NULL, (char*)hdr_disk1.salt, sizeof(hdr_disk1.salt), CRYPT_RND_SALT);
7cdc99
diff --git a/lib/luks2/luks2_internal.h b/lib/luks2/luks2_internal.h
7cdc99
index e9beab8..dcabed7 100644
7cdc99
--- a/lib/luks2/luks2_internal.h
7cdc99
+++ b/lib/luks2/luks2_internal.h
7cdc99
@@ -42,7 +42,7 @@
7cdc99
  * On-disk access function prototypes
7cdc99
  */
7cdc99
 int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
7cdc99
-			struct device *device, int do_recovery);
7cdc99
+			struct device *device, int do_recovery, int do_blkprobe);
7cdc99
 int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr,
7cdc99
 			 struct device *device);
7cdc99
 
7cdc99
diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c
7cdc99
index 362388e..125cad9 100644
7cdc99
--- a/lib/luks2/luks2_json_metadata.c
7cdc99
+++ b/lib/luks2/luks2_json_metadata.c
7cdc99
@@ -853,7 +853,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
7cdc99
 		return r;
7cdc99
 	}
7cdc99
 
7cdc99
-	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1);
7cdc99
+	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
7cdc99
 	if (r == -EAGAIN) {
7cdc99
 		/* unlikely: auto-recovery is required and failed due to read lock being held */
7cdc99
 		device_read_unlock(crypt_metadata_device(cd));
7cdc99
@@ -865,7 +865,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
7cdc99
 			return r;
7cdc99
 		}
7cdc99
 
7cdc99
-		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1);
7cdc99
+		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
7cdc99
 
7cdc99
 		device_write_unlock(crypt_metadata_device(cd));
7cdc99
 	} else
7cdc99
-- 
7cdc99
1.8.3.1
7cdc99