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

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