Abort encryption when header and data devices are same.

If data device reduction is not requsted this led
to data corruption since LUKS metadata was written
over the data device.
This commit is contained in:
Ondrej Kozina
2022-12-02 15:39:36 +01:00
parent be088b8de8
commit c18dcfaa0b
3 changed files with 70 additions and 8 deletions

View File

@@ -467,6 +467,26 @@ static int reencrypt_check_active_device_sb_block_size(const char *active_device
return reencrypt_check_data_sb_block_size(dm_device, new_sector_size);
}
static int reencrypt_is_header_detached(const char *header_device, const char *data_device)
{
int r;
struct stat st;
struct crypt_device *cd;
if (!header_device)
return 0;
if (header_device && stat(header_device, &st) < 0 && errno == ENOENT)
return 1;
if ((r = crypt_init_data_device(&cd, header_device, data_device)))
return r;
r = crypt_header_is_detached(cd);
crypt_free(cd);
return r;
}
static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device, const char *device_name)
{
int keyslot, r, fd;
@@ -490,9 +510,14 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
_set_reencryption_flags(&params.flags);
if (!data_shift && !ARG_SET(OPT_HEADER_ID)) {
log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
return -ENOTSUP;
if (!data_shift) {
r = reencrypt_is_header_detached(ARG_STR(OPT_HEADER_ID), data_device);
if (r < 0)
return r;
if (!r) {
log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
return -ENOTSUP;
}
}
if (!ARG_SET(OPT_HEADER_ID) && ARG_UINT64(OPT_OFFSET_ID) &&
@@ -1358,9 +1383,16 @@ static int _encrypt(struct crypt_device *cd, const char *type, enum device_statu
if (!type)
type = crypt_get_default_type();
if (dev_st == DEVICE_LUKS1_UNUSABLE || isLUKS1(type))
if (dev_st == DEVICE_LUKS1_UNUSABLE || isLUKS1(type)) {
r = reencrypt_is_header_detached(ARG_STR(OPT_HEADER_ID), action_argv[0]);
if (r < 0)
return r;
if (!r && !ARG_SET(OPT_REDUCE_DEVICE_SIZE_ID)) {
log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size)."));
return -ENOTSUP;
}
return reencrypt_luks1(action_argv[0]);
else if (dev_st == DEVICE_NOT_LUKS) {
} else if (dev_st == DEVICE_NOT_LUKS) {
r = encrypt_luks2_init(&encrypt_cd, action_argv[0], action_argc > 1 ? action_argv[1] : NULL);
if (r < 0 || ARG_SET(OPT_INIT_ONLY_ID)) {
crypt_free(encrypt_cd);

View File

@@ -1080,6 +1080,22 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail
$CRYPTSETUP close $DEV_NAME
echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail
# Encrypt without size reduction must not allow header device same as data device
wipe_dev_head $DEV 1
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail
ln -s $DEV $DEV_LINK || fail
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail
rm -f $DEV_LINK || fail
dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
ln -s $IMG $DEV_LINK || fail
echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
echo "[4] Reencryption with detached header"
wipe $PWD1 $IMG_HDR
echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail

View File

@@ -15,6 +15,7 @@ IMG=reenc-data
IMG_HDR=$IMG.hdr
HEADER_LUKS2_PV=blkid-luks2-pv.img
ORIG_IMG=reenc-data-orig
DEV_LINK="reenc-test-link"
KEY1=key1
PWD1="93R4P4pIqAH8"
PWD2="1cND4319812f"
@@ -40,7 +41,7 @@ function remove_mapping()
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $HEADER_LUKS2_PV >/dev/null 2>&1
rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $HEADER_LUKS2_PV $DEV_LINK >/dev/null 2>&1
umount $MNT_DIR > /dev/null 2>&1
rmdir $MNT_DIR > /dev/null 2>&1
LOOPDEV1=""
@@ -302,12 +303,25 @@ check_slot 0 || fail "Only keyslot 0 expected to be enabled"
$REENC $LOOPDEV1 -d $KEY1 $FAST_PBKDF -q || fail
# FIXME echo $PWD1 | $REENC ...
if [ ! fips_mode ]; then
echo "[4] Encryption of not yet encrypted device"
# Encrypt without size reduction must not allow header device same as data device
wipe_dev $LOOPDEV1
echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $LOOPDEV1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail
ln -s $LOOPDEV1 $DEV_LINK || fail
echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail
rm -f $DEV_LINK || fail
echo $PWD1 | $REENC $IMG --type luks1 --new --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
ln -s $IMG $DEV_LINK || fail
echo $PWD1 | $REENC $IMG --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail
$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail
if [ ! fips_mode ]; then
# well, movin' zeroes :-)
OFFSET=2048
SIZE=$(blockdev --getsz $LOOPDEV1)
wipe_dev $LOOPDEV1
dmsetup create $DEV_NAME2 --table "0 $(($SIZE - $OFFSET)) linear $LOOPDEV1 0" || fail
check_hash_dev /dev/mapper/$DEV_NAME2 $HASH3
dmsetup remove --retry $DEV_NAME2 || fail