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