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

623667
From c18dcfaa0b91eb48006232fbfadce9e6a9b4a790 Mon Sep 17 00:00:00 2001
623667
From: Ondrej Kozina <okozina@redhat.com>
623667
Date: Fri, 2 Dec 2022 15:39:36 +0100
623667
Subject: [PATCH 2/2] Abort encryption when header and data devices are same.
623667
623667
If data device reduction is not requsted this led
623667
to data corruption since LUKS metadata was written
623667
over the data device.
623667
---
623667
 src/utils_reencrypt.c          | 42 ++++++++++++++++++++++++++++++----
623667
 tests/luks2-reencryption-test  | 16 +++++++++++++
623667
 tests/reencryption-compat-test | 20 +++++++++++++---
623667
 3 files changed, 70 insertions(+), 8 deletions(-)
623667
623667
diff --git a/src/utils_reencrypt.c b/src/utils_reencrypt.c
623667
index 87ead680..73e0bca8 100644
623667
--- a/src/utils_reencrypt.c
623667
+++ b/src/utils_reencrypt.c
623667
@@ -467,6 +467,26 @@ static int reencrypt_check_active_device_sb_block_size(const char *active_device
623667
 	return reencrypt_check_data_sb_block_size(dm_device, new_sector_size);
623667
 }
623667
 
623667
+static int reencrypt_is_header_detached(const char *header_device, const char *data_device)
623667
+{
623667
+	int r;
623667
+	struct stat st;
623667
+	struct crypt_device *cd;
623667
+
623667
+	if (!header_device)
623667
+		return 0;
623667
+
623667
+	if (header_device && stat(header_device, &st) < 0 && errno == ENOENT)
623667
+		return 1;
623667
+
623667
+	if ((r = crypt_init_data_device(&cd, header_device, data_device)))
623667
+		return r;
623667
+
623667
+	r = crypt_header_is_detached(cd);
623667
+	crypt_free(cd);
623667
+	return r;
623667
+}
623667
+
623667
 static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device, const char *device_name)
623667
 {
623667
 	int keyslot, r, fd;
623667
@@ -490,9 +510,14 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
623667
 
623667
 	_set_reencryption_flags(&params.flags);
623667
 
623667
-	if (!data_shift && !ARG_SET(OPT_HEADER_ID)) {
623667
-		log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
623667
-		return -ENOTSUP;
623667
+	if (!data_shift) {
623667
+		r = reencrypt_is_header_detached(ARG_STR(OPT_HEADER_ID), data_device);
623667
+		if (r < 0)
623667
+			return r;
623667
+		if (!r) {
623667
+			log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
623667
+			return -ENOTSUP;
623667
+		}
623667
 	}
623667
 
623667
 	if (!ARG_SET(OPT_HEADER_ID) && ARG_UINT64(OPT_OFFSET_ID) &&
623667
@@ -1358,9 +1383,16 @@ static int _encrypt(struct crypt_device *cd, const char *type, enum device_statu
623667
 	if (!type)
623667
 		type = crypt_get_default_type();
623667
 
623667
-	if (dev_st == DEVICE_LUKS1_UNUSABLE || isLUKS1(type))
623667
+	if (dev_st == DEVICE_LUKS1_UNUSABLE || isLUKS1(type)) {
623667
+		r = reencrypt_is_header_detached(ARG_STR(OPT_HEADER_ID), action_argv[0]);
623667
+		if (r < 0)
623667
+			return r;
623667
+		if (!r && !ARG_SET(OPT_REDUCE_DEVICE_SIZE_ID)) {
623667
+			log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
623667
+			return -ENOTSUP;
623667
+		}
623667
 		return reencrypt_luks1(action_argv[0]);
623667
-	else if (dev_st == DEVICE_NOT_LUKS) {
623667
+	} else if (dev_st == DEVICE_NOT_LUKS) {
623667
 		r = encrypt_luks2_init(&encrypt_cd, action_argv[0], action_argc > 1 ? action_argv[1] : NULL);
623667
 		if (r < 0 || ARG_SET(OPT_INIT_ONLY_ID)) {
623667
 			crypt_free(encrypt_cd);
623667
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test
623667
index bab54353..a647a8c2 100755
623667
--- a/tests/luks2-reencryption-test
623667
+++ b/tests/luks2-reencryption-test
623667
@@ -1080,6 +1080,22 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail
623667
 $CRYPTSETUP close $DEV_NAME
623667
 echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail
623667
 
623667
+# Encrypt without size reduction must not allow header device same as data device
623667
+wipe_dev_head $DEV 1
623667
+echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail
623667
+ln -s $DEV $DEV_LINK || fail
623667
+echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail
623667
+rm -f $DEV_LINK || fail
623667
+
623667
+dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1
623667
+echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
623667
+ln -s $IMG $DEV_LINK || fail
623667
+echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
623667
+
623667
 echo "[4] Reencryption with detached header"
623667
 wipe $PWD1 $IMG_HDR
623667
 echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail
623667
diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test
623667
index f6a84137..453831d1 100755
623667
--- a/tests/reencryption-compat-test
623667
+++ b/tests/reencryption-compat-test
623667
@@ -15,6 +15,7 @@ IMG=reenc-data
623667
 IMG_HDR=$IMG.hdr
623667
 HEADER_LUKS2_PV=blkid-luks2-pv.img
623667
 ORIG_IMG=reenc-data-orig
623667
+DEV_LINK="reenc-test-link"
623667
 KEY1=key1
623667
 PWD1="93R4P4pIqAH8"
623667
 PWD2="1cND4319812f"
623667
@@ -40,7 +41,7 @@ function remove_mapping()
623667
 	[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2
623667
 	[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
623667
 	[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
623667
-	rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $HEADER_LUKS2_PV >/dev/null 2>&1
623667
+	rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $HEADER_LUKS2_PV $DEV_LINK >/dev/null 2>&1
623667
 	umount $MNT_DIR > /dev/null 2>&1
623667
 	rmdir $MNT_DIR > /dev/null 2>&1
623667
 	LOOPDEV1=""
623667
@@ -302,12 +303,25 @@ check_slot 0 || fail "Only keyslot 0 expected to be enabled"
623667
 $REENC $LOOPDEV1 -d $KEY1 $FAST_PBKDF -q || fail
623667
 # FIXME echo $PWD1 | $REENC ...
623667
 
623667
-if [ ! fips_mode ]; then
623667
 echo "[4] Encryption of not yet encrypted device"
623667
+# Encrypt without size reduction must not allow header device same as data device
623667
+wipe_dev $LOOPDEV1
623667
+echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $LOOPDEV1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail
623667
+ln -s $LOOPDEV1 $DEV_LINK || fail
623667
+echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail
623667
+rm -f $DEV_LINK || fail
623667
+echo $PWD1 | $REENC $IMG --type luks1 --new --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
623667
+ln -s $IMG $DEV_LINK || fail
623667
+echo $PWD1 | $REENC $IMG --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
623667
+$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
623667
+
623667
+if [ ! fips_mode ]; then
623667
 # well, movin' zeroes :-)
623667
 OFFSET=2048
623667
 SIZE=$(blockdev --getsz $LOOPDEV1)
623667
-wipe_dev $LOOPDEV1
623667
 dmsetup create $DEV_NAME2 --table "0 $(($SIZE - $OFFSET)) linear $LOOPDEV1 0" || fail
623667
 check_hash_dev /dev/mapper/$DEV_NAME2 $HASH3
623667
 dmsetup remove --retry $DEV_NAME2 || fail
623667
-- 
623667
2.38.1
623667