Blame SOURCES/cryptsetup-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch

4bba8a
From c18dcfaa0b91eb48006232fbfadce9e6a9b4a790 Mon Sep 17 00:00:00 2001
4bba8a
From: Ondrej Kozina <okozina@redhat.com>
4bba8a
Date: Fri, 2 Dec 2022 15:39:36 +0100
4bba8a
Subject: [PATCH 2/2] Abort encryption when header and data devices are same.
4bba8a
4bba8a
If data device reduction is not requsted this led
4bba8a
to data corruption since LUKS metadata was written
4bba8a
over the data device.
4bba8a
---
4bba8a
 src/utils_reencrypt.c          | 42 ++++++++++++++++++++++++++++++----
4bba8a
 tests/luks2-reencryption-test  | 16 +++++++++++++
4bba8a
 tests/reencryption-compat-test | 20 +++++++++++++---
4bba8a
 3 files changed, 70 insertions(+), 8 deletions(-)
4bba8a
4bba8a
diff --git a/src/utils_tools.c b/src/utils_tools.c
4bba8a
--- a/src/utils_tools.c
4bba8a
+++ b/src/utils_tools.c
4bba8a
@@ -624,3 +624,23 @@ int tools_reencrypt_progress(uint64_t si
4bba8a
 
4bba8a
 	return r;
4bba8a
 }
4bba8a
+
4bba8a
+int reencrypt_is_header_detached(const char *header_device, const char *data_device)
4bba8a
+{
4bba8a
+	int r;
4bba8a
+	struct stat st;
4bba8a
+	struct crypt_device *cd;
4bba8a
+
4bba8a
+	if (!header_device)
4bba8a
+		return 0;
4bba8a
+
4bba8a
+	if (header_device && stat(header_device, &st) < 0 && errno == ENOENT)
4bba8a
+		return 1;
4bba8a
+
4bba8a
+	if ((r = crypt_init_data_device(&cd, header_device, data_device)))
4bba8a
+		return r;
4bba8a
+
4bba8a
+	r = crypt_get_metadata_device_name(cd) && crypt_get_device_name(cd) && strcmp(crypt_get_metadata_device_name(cd), crypt_get_device_name(cd));
4bba8a
+	crypt_free(cd);
4bba8a
+	return r;
4bba8a
+}
4bba8a
diff --git a/src/cryptsetup.h b/src/cryptsetup.h
4bba8a
--- a/src/cryptsetup.h
4bba8a
+++ b/src/cryptsetup.h
4bba8a
@@ -103,6 +103,7 @@ void tools_clear_line(void);
4bba8a
 
4bba8a
 int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr);
4bba8a
 int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr);
4bba8a
+int reencrypt_is_header_detached(const char *header_device, const char *data_device);
4bba8a
 
4bba8a
 int tools_read_mk(const char *file, char **key, int keysize);
4bba8a
 int tools_write_mk(const char *file, const char *key, int keysize);
4bba8a
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
4bba8a
--- a/src/cryptsetup.c
4bba8a
+++ b/src/cryptsetup.c
4bba8a
@@ -2892,6 +2892,16 @@ static int action_encrypt_luks2(struct c
4bba8a
 		return -ENOTSUP;
4bba8a
 	}
4bba8a
 
4bba8a
+	if (!opt_data_shift) {
4bba8a
+	       r = reencrypt_is_header_detached(opt_header_device, action_argv[0]);
4bba8a
+	       if (r < 0)
4bba8a
+		       return r;
4bba8a
+	       if (!r) {
4bba8a
+		       log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
4bba8a
+		       return -ENOTSUP;
4bba8a
+	       }
4bba8a
+	}
4bba8a
+
4bba8a
 	if (!opt_header_device && opt_offset && opt_data_shift && (opt_offset > (imaxabs(opt_data_shift) / (2 * SECTOR_SIZE)))) {
4bba8a
 		log_err(_("Requested data offset must be less than or equal to half of --reduce-device-size parameter."));
4bba8a
 		return -EINVAL;
4bba8a
diff --git a/src/cryptsetup_reencrypt.c b/src/cryptsetup_reencrypt.c
4bba8a
--- a/src/cryptsetup_reencrypt.c
4bba8a
+++ b/src/cryptsetup_reencrypt.c
4bba8a
@@ -1553,6 +1553,17 @@ static int run_reencrypt(const char *dev
4bba8a
 		goto out;
4bba8a
 	}
4bba8a
4bba8a
+	if (rc.reencrypt_mode == ENCRYPT) {
4bba8a
+		r = reencrypt_is_header_detached(opt_header_device, action_argv[0]);
4bba8a
+		if (r < 0)
4bba8a
+			goto out;
4bba8a
+		if (!r && !opt_reduce_size) {
4bba8a
+			log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
4bba8a
+			r = -ENOTSUP;
4bba8a
+			goto out;
4bba8a
+		}
4bba8a
+	}
4bba8a
+
4bba8a
 	log_dbg("Running reencryption.");
4bba8a
4bba8a
 	if (!rc.in_progress) {
4bba8a
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test
4bba8a
index bab54353..a647a8c2 100755
4bba8a
--- a/tests/luks2-reencryption-test
4bba8a
+++ b/tests/luks2-reencryption-test
4bba8a
@@ -1080,6 +1080,15 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail
4bba8a
 $CRYPTSETUP close $DEV_NAME
4bba8a
 echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail
4bba8a
 
4bba8a
+# Encrypt without size reduction must not allow header device same as data device
4bba8a
+wipe_dev_head $DEV 1
4bba8a
+echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail
4bba8a
+$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail
4bba8a
+
4bba8a
+dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1
4bba8a
+echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
4bba8a
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
4bba8a
+
4bba8a
 echo "[4] Reencryption with detached header"
4bba8a
 wipe $PWD1 $IMG_HDR
4bba8a
 echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail
4bba8a
diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test
4bba8a
index f6a84137..453831d1 100755
4bba8a
--- a/tests/reencryption-compat-test
4bba8a
+++ b/tests/reencryption-compat-test
4bba8a
@@ -11,5 +11,6 @@ IMG=reenc-data
4bba8a
 IMG_HDR=$IMG.hdr
4bba8a
 ORIG_IMG=reenc-data-orig
4bba8a
+DEV_LINK="reenc-test-link"
4bba8a
 KEY1=key1
4bba8a
 PWD1="93R4P4pIqAH8"
4bba8a
 PWD2="1cND4319812f"
4bba8a
@@ -40,7 +41,7 @@ function remove_mapping()
4bba8a
 	[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2
4bba8a
 	[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
4bba8a
 	[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
4bba8a
-	rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1
4bba8a
+	rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $DEV_LINK >/dev/null 2>&1
4bba8a
 	umount $MNT_DIR > /dev/null 2>&1
4bba8a
 	rmdir $MNT_DIR > /dev/null 2>&1
4bba8a
 	LOOPDEV1=""
4bba8a
@@ -265,10 +265,16 @@ $REENC $LOOPDEV1 -d $KEY1 $FAST_PBKDF -q
4bba8a
 # FIXME echo $PWD1 | $REENC ...
4bba8a
 
4bba8a
 echo "[4] Encryption of not yet encrypted device"
4bba8a
+# Encrypt without size reduction must not allow header device same as data device
4bba8a
+wipe_dev $LOOPDEV1
4bba8a
+echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $LOOPDEV1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail
4bba8a
+$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail
4bba8a
+echo $PWD1 | $REENC $IMG --type luks1 --new --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
4bba8a
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
4bba8a
+
4bba8a
 # well, movin' zeroes :-)
4bba8a
 OFFSET=2048
4bba8a
 SIZE=$(blockdev --getsz $LOOPDEV1)
4bba8a
-wipe_dev $LOOPDEV1
4bba8a
 dmsetup create $DEV_NAME2 --table "0 $(($SIZE - $OFFSET)) linear $LOOPDEV1 0" || fail
4bba8a
 check_hash_dev /dev/mapper/$DEV_NAME2 $HASH3
4bba8a
 dmsetup remove --retry $DEV_NAME2 || fail
4bba8a
-- 
4bba8a
2.38.1
4bba8a