Update to cryptsetup 2.8.6

- Update to cryptsetup 2.8.6
- Add upstream patches for jq test fixes
- Add upstream patches for reencryption error path improvements

Resolves: RHEL-163434
This commit is contained in:
Kristina Hanicova 2026-05-10 21:51:31 +02:00
parent 98111e371e
commit c693d865ec
19 changed files with 3026 additions and 357 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/cryptsetup-2.7.5.tar.xz
/cryptsetup-2.8.1.tar.xz
/cryptsetup-2.8.6.tar.xz

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEKikYJD/eRmSNBob52bBXe9k+mPwFAmikPjAACgkQ2bBXe9k+
mPzw4hAAqew2XZt7qfeHXNrx4Qx+5fh8J6kNBByMoBBBoNV778MUeE35hZ57L+0G
fCRJTcWvZX9WUomSY3L/n1h/kGrk/G59clBNXyBo/VlqGy4TnDIyX/5RfN93Ysfr
XzdZptH7PFLnhf6R9Y6bkRTCVdutW6WSW+CTeB6LnQHR97y2Jz/L+qTpExs9ujk9
FMuMI2bO+i5QaisvAqS7/z0ba18xdgNqplj8DUFygtuJiUeshtW/RHBr21Y762Ut
ZaliJbkww/XbI0CVyjoT0OrgRIpqr1tb1AwPNCU81MgCrB5q5pYOdcGkuRGIGKSG
+BC2qrHqlbNIu8SOu6JZ7mq2gkiyzz+Gg7AuKsvV9HPFkFEd40SIE2xNMxgwZtwB
jW9d07Cg90qGcKLqESwb5bNXRFxw8aBXHaaZraC5mAoYfOXaQAL+FlBtbcsADoFy
7TJEDyqC47nRB7dC0c8Cd7rqZ7nFWenf7oPXK87wFDIRDdv7OTtwD03fQdhy7j6N
+jX1vVH/xRDpEpcUTQyuo3CO/gN5w2TWPKHYFBkAV3qvQOTLKZXQCxyYNfSBfFmJ
IyeRPYb/Euk46jX+xpCeoP540YAL6BoLTHyis5wjjM9jTXTMKFa5ZivrMlWaRKS5
pp4EIpJlxuE8kGmKvMgPO3kgS4w3akjNpfdkeRWAPKaVVMzBY1Y=
=tRD6
-----END PGP SIGNATURE-----

View File

@ -1,31 +0,0 @@
From 55e0209a4e751e4edb3662827a57cd5d330f30c2 Mon Sep 17 00:00:00 2001
Message-ID: <55e0209a4e751e4edb3662827a57cd5d330f30c2.1766066332.git.khanicov@redhat.com>
From: Milan Broz <gmazyland@gmail.com>
Date: Thu, 11 Dec 2025 23:40:14 +0100
Subject: [PATCH] Fix LUKS2 device status in inline HW mode and detached header
Internal type is not set if detached header is not specified,
but inline tag check should be done anyway.
---
lib/setup.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/setup.c b/lib/setup.c
index 3a411733..1ee02db5 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -5838,8 +5838,12 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
if (r < 0)
return r;
- /* For LUKS2 with integrity we need flags from underlying dm-integrity */
- if (isLUKS2(cd->type) && crypt_get_integrity_tag_size(cd) &&
+ /*
+ * For integrity and LUKS2 (and detached header where context is NULL)
+ * we need flags from underlying dm-integrity device.
+ * This check must be skipped for non-LUKS2 integrity device.
+ */
+ if ((isLUKS2(cd->type) || !cd->type) && crypt_get_integrity_tag_size(cd) &&
(iname = dm_get_active_iname(cd, name))) {
if (dm_query_device(cd, iname, 0, &dmdi) >= 0)
dmd.flags |= dmdi.flags;

View File

@ -1,29 +0,0 @@
From a8e8e39007f9a3ab91267ff2b4f0aee45cc48752 Mon Sep 17 00:00:00 2001
Message-ID: <a8e8e39007f9a3ab91267ff2b4f0aee45cc48752.1766065101.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Thu, 30 Oct 2025 13:59:52 +0100
Subject: [PATCH] Fix possible use of uninitialized variable.
device_tag_size variable was not initialized and used
when device_is_nop_dif returned negative error code.
---
lib/setup.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/setup.c b/lib/setup.c
index 37e6f7d9..48b67ce6 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -3045,7 +3045,11 @@ int crypt_format_inline(struct crypt_device *cd,
iparams->journal_integrity_key_size))
return -EINVAL;
- if (!device_is_nop_dif(idevice, &device_tag_size)) {
+ r = device_is_nop_dif(idevice, &device_tag_size);
+ if (r < 0)
+ return r;
+
+ if (!r) {
log_err(cd, _("Device %s does not provide inline integrity data fields."), mdata_device_path(cd));
return -EINVAL;
}

View File

@ -1,49 +0,0 @@
From 9810c6fb2f24073796aa1482680151ddbc668790 Mon Sep 17 00:00:00 2001
Message-ID: <9810c6fb2f24073796aa1482680151ddbc668790.1766065092.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Fri, 17 Oct 2025 15:13:41 +0200
Subject: [PATCH] Read integrity profile info from top level device.
When formating device with --integrity-inline option
there's a check if underlying device properly advertise
integrity profile support. The check did not work
properly for partition device nodes. We have to read
integrity profile info from top level block device.
Fixes: #964.
---
lib/utils_device.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/lib/utils_device.c b/lib/utils_device.c
index 90ec9de4..1cdbcc65 100644
--- a/lib/utils_device.c
+++ b/lib/utils_device.c
@@ -1004,12 +1004,26 @@ int device_is_zoned(struct device *device)
int device_is_nop_dif(struct device *device, uint32_t *tag_size)
{
+ char *base_device_path;
+ int r;
struct stat st;
if (!device)
return -EINVAL;
- if (stat(device_path(device), &st) < 0)
+ /*
+ * For partition devices, check integrity profile on the base device.
+ * Partition device nodes don't advertise integrity profile directly
+ * via sysfs attributes.
+ */
+ base_device_path = crypt_get_base_device(device_path(device));
+ if (base_device_path) {
+ r = stat(base_device_path, &st);
+ free(base_device_path);
+ } else
+ r = stat(device_path(device), &st);
+
+ if (r < 0)
return -EINVAL;
if (!S_ISBLK(st.st_mode))

View File

@ -1,41 +0,0 @@
From 5d69c34f59dbe7fce07d76057fc39198666ab44e Mon Sep 17 00:00:00 2001
Message-ID: <5d69c34f59dbe7fce07d76057fc39198666ab44e.1766065109.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Thu, 27 Nov 2025 10:49:24 +0100
Subject: [PATCH] Reinstate pbkdf serialization flag in device activation.
crypt_activate_by_keyslot_context never respected pbkdf serialation
flag (CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF).
In fact it worked only when device was activated via passphrase or via
passphrase file. It was never respected when device was activated
by a token for example.
When the internal code was fully switched to activation via keyslot
context the legacy code for passphrase based activation was dropped
and we lost track of serialization flag completely.
This fixes all of the issues so now the serialization flag will be
respected also with tokens (and all other activation methods unlocking
LUKS2 keyslot with memory hard pbkdf).
Fixes: 58385d68d8f4 (Allow activation via keyslot context)
Fixes: #968.
---
lib/setup.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/setup.c b/lib/setup.c
index f1b2033b..367d2d11 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -5450,6 +5450,9 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd,
return _activate_loopaes(cd, name, passphrase, passphrase_size, flags);
}
+ if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF)
+ cd->memory_hard_pbkdf_lock_enabled = true;
+
/* acquire the volume key(s) */
r = -EINVAL;
if (isLUKS1(cd->type)) {

View File

@ -1,38 +0,0 @@
From cdb6a5626089a56a7a135042be7c157acda70506 Mon Sep 17 00:00:00 2001
Message-ID: <cdb6a5626089a56a7a135042be7c157acda70506.1766065116.git.khanicov@redhat.com>
From: Kristina Hanicova <khanicov@redhat.com>
Date: Wed, 10 Dec 2025 17:58:36 +0100
Subject: [PATCH] Set inline integrity flag if no underlying dm-integrity
device
Cryptsetup status does not report when the hw inline integrity is
set without the underlying dm-integrity device.
Fixes: #965
---
lib/setup.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/lib/setup.c b/lib/setup.c
index 1ee02db5..93c7ef5f 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -5843,11 +5843,13 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
* we need flags from underlying dm-integrity device.
* This check must be skipped for non-LUKS2 integrity device.
*/
- if ((isLUKS2(cd->type) || !cd->type) && crypt_get_integrity_tag_size(cd) &&
- (iname = dm_get_active_iname(cd, name))) {
- if (dm_query_device(cd, iname, 0, &dmdi) >= 0)
- dmd.flags |= dmdi.flags;
- free(iname);
+ if ((isLUKS2(cd->type) || !cd->type) && crypt_get_integrity_tag_size(cd)) {
+ if ((iname = dm_get_active_iname(cd, name))) {
+ if (dm_query_device(cd, iname, 0, &dmdi) >= 0)
+ dmd.flags |= dmdi.flags;
+ free(iname);
+ } else
+ dmd.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
}
if (cd && isTCRYPT(cd->type)) {

View File

@ -1,143 +0,0 @@
From 7fa4cd930814073cb8abe997d8fac19a849daecd Mon Sep 17 00:00:00 2001
Message-ID: <7fa4cd930814073cb8abe997d8fac19a849daecd.1767967753.git.khanicov@redhat.com>
From: Milan Broz <gmazyland@gmail.com>
Date: Fri, 2 Jan 2026 20:58:26 +0100
Subject: [PATCH] Fix wrong device size status reports in cryptsetup and
integritysetup
In version 2.8.0 the status output was modified to strictly use
units and also bytes device size was added.
Unfortunately, the size was wrongly calculated if sector size was
different than 512-byte default.
Fixes: #972
---
src/cryptsetup.c | 8 +++-----
src/integritysetup.c | 6 ++----
src/veritysetup.c | 2 +-
tests/compat-test2 | 2 ++
tests/integrity-compat-test | 6 ++++++
tests/verity-compat-test | 4 ++++
6 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
index d8b9e508..b9966f84 100644
--- a/src/cryptsetup.c
+++ b/src/cryptsetup.c
@@ -936,7 +936,6 @@ static int action_status(void)
char *backing_file;
const char *device;
int path = 0, r = 0, hw_enc;
- uint64_t sector_size;
/* perhaps a path, not a dm device name */
if (strchr(action_argv[0], '/'))
@@ -1019,10 +1018,9 @@ static int action_status(void)
log_std(" loop: %s\n", backing_file);
free(backing_file);
}
- sector_size = (uint64_t)crypt_get_sector_size(cd) ?: SECTOR_SIZE;
- log_std(" sector size: %" PRIu64 " [bytes]\n", sector_size);
- log_std(" offset: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.offset, cad.offset * sector_size);
- log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * sector_size);
+ log_std(" sector size: %" PRIu64 " [bytes]\n", (uint64_t)crypt_get_sector_size(cd) ?: SECTOR_SIZE);
+ log_std(" offset: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.offset, cad.offset * SECTOR_SIZE);
+ log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * SECTOR_SIZE);
if (cad.iv_offset)
log_std(" skipped: %" PRIu64 " [512-byte units]\n", cad.iv_offset);
log_std(" mode: %s%s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
diff --git a/src/integritysetup.c b/src/integritysetup.c
index a1d77855..89c3edd3 100644
--- a/src/integritysetup.c
+++ b/src/integritysetup.c
@@ -424,7 +424,6 @@ static int action_status(void)
char *backing_file;
const char *device, *metadata_device;
int path = 0, r = 0;
- uint64_t sector_size;
/* perhaps a path, not a dm device name */
if (strchr(action_argv[0], '/'))
@@ -482,10 +481,9 @@ static int action_status(void)
free(backing_file);
}
}
- sector_size = (uint64_t)crypt_get_sector_size(cd) ?: SECTOR_SIZE;
- log_std(" sector size: %" PRIu64 " [bytes]\n", sector_size);
+ log_std(" sector size: %" PRIu64 " [bytes]\n", (uint64_t)crypt_get_sector_size(cd) ?: SECTOR_SIZE);
log_std(" interleave sectors: %u\n", ip.interleave_sectors);
- log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * sector_size);
+ log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * SECTOR_SIZE);
log_std(" mode: %s%s\n",
cad.flags & CRYPT_ACTIVATE_READONLY ? "readonly" : "read/write",
cad.flags & CRYPT_ACTIVATE_RECOVERY ? " recovery" : "");
diff --git a/src/veritysetup.c b/src/veritysetup.c
index 8e666e3f..d95db09b 100644
--- a/src/veritysetup.c
+++ b/src/veritysetup.c
@@ -395,7 +395,7 @@ static int action_status(void)
log_std(" data loop: %s\n", backing_file);
free(backing_file);
}
- log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * (uint64_t)SECTOR_SIZE);
+ log_std(" size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", cad.size, cad.size * SECTOR_SIZE);
log_std(" mode: %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
"readonly" : "read/write");
diff --git a/tests/compat-test2 b/tests/compat-test2
index 373461eb..7350455b 100755
--- a/tests/compat-test2
+++ b/tests/compat-test2
@@ -816,9 +816,11 @@ if dm_crypt_sector_size_support; then
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP -q resize --device-size 1M $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "1048576 \[bytes\]" || fail
echo $PWD1 | $CRYPTSETUP -q resize --device-size 2049s $DEV_NAME > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP -q resize --size 2049 $DEV_NAME > /dev/null 2>&1 && fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "1048576 \[bytes\]" || fail
fi
$CRYPTSETUP close $DEV_NAME || fail
# Resize not aligned to logical block size
diff --git a/tests/integrity-compat-test b/tests/integrity-compat-test
index c40218cd..5aeea5c0 100755
--- a/tests/integrity-compat-test
+++ b/tests/integrity-compat-test
@@ -230,7 +230,13 @@ intformat() # alg alg_out tagsize outtagsize sector_size csum [keyfile keysize]
status_check "tag size" "$4 [bytes]"
status_check "integrity" $2
status_check "sector size" "$5 [bytes]"
+
+ SIZE_BYTES=$(blockdev --getsize64 /dev/mapper/$DEV_NAME)
+ SIZE_512S=$(( $SIZE_BYTES / 512 ))
+ status_check " size" "$SIZE_512S [512-byte units] ($SIZE_BYTES [bytes])"
+
int_check_sum $1 $6 $7 $8
+
echo -n "[REMOVE]"
$INTSETUP close $DEV_NAME || fail "Cannot deactivate device."
echo "[OK]"
diff --git a/tests/verity-compat-test b/tests/verity-compat-test
index 93ac405e..02b3d390 100755
--- a/tests/verity-compat-test
+++ b/tests/verity-compat-test
@@ -188,6 +188,9 @@ check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset]
$VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || fail
check_exists
+ SIZE_BYTES=$(blockdev --getsize64 /dev/mapper/$DEV_NAME)
+ SIZE_512S=$(( $SIZE_BYTES / 512 ))
+ $VERITYSETUP status $DEV_NAME 2>/dev/null | grep " size:" | grep -q -F "$SIZE_512S [512-byte units] ($SIZE_BYTES [bytes])" || fail
echo -n "[activate]"
dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
@@ -474,6 +477,7 @@ export LANG=C
[ -n "$VALG" ] && valgrind_setup && VERITYSETUP=valgrind_run
modprobe dm-verity >/dev/null 2>&1
dmsetup targets | grep verity >/dev/null 2>&1 || skip "Cannot find dm-verity target, test skipped."
+command -v blockdev >/dev/null || skip "Cannot find blockdev utility, test skipped."
# VERITYSETUP tests

16
cryptsetup-2.8.6.tar.sign Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEKikYJD/eRmSNBob52bBXe9k+mPwFAmnOnzMACgkQ2bBXe9k+
mPzd/g//bN3k3M4j/AuO4SE1IF+J0g1gBi3ljhmbXc/4rjqce3exO+u0MeuWfPgW
1AyXqLsaETa0L3iF7iw0rnQ+Esxyoorz29590gxRCGls3mFRxytwRcPEvCmTc0qA
zephE2vUdycw09kzi7Ors0jxw/EyUU3bIQounTRH7avDmNTU5AoehIZwMk/u0fQU
Th4c1PPiWdgkimvXmJpea/hAB7VO88VP9B3fcO2FxO+zy1UzhwCUvcJv+/LAlB4e
AmsvBBQ0CAM4p1GFJ1GjIwldgjmovxD7x/xAQQA14raLWGIJODXLMWaAq/bzUGHh
jZg5vGycYqCE+WpvyR9mR41bchzC0BDZX5puZucKvvuWPb39A+vtAgzHHwBTHAkm
GSjmObJhI4QQZmkm0/NWdddj2h1aZY8T1B7jwI+6Bdw88s/OI28CAM+bLzJkOTaJ
V4mu/JxX/qsq1rdOtlAfbVD6CQnu6s1O+zvtsUeKCuWnCzesD1yiD5RUjMzWlW+E
WqiX1VhOXKP9HL6iD4Krgm2GtkbMqL5cTY57sKAnX3GVJsNj4/wXKREWRf1ZQnFP
OTvm7t4x8yoHRnVC7emM3WH40Yi9BWo7OCqVhaOvzemmtbkYj4V2XY1Hs9Q85lQI
muEZDfK1TRTvj6H9ng44I1yj+HgbNOr2YYBLmX9E6rBn60XWNr8=
=dDcU
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,36 @@
From 6298269486354834d4037ba294c91452dec4c2f5 Mon Sep 17 00:00:00 2001
Message-ID: <6298269486354834d4037ba294c91452dec4c2f5.1778441448.git.khanicov@redhat.com>
From: Milan Broz <gmazyland@gmail.com>
Date: Fri, 17 Apr 2026 18:02:12 +0200
Subject: [PATCH] ci: Fix jq no longer handling 0x00 characters
Due to jq fix for CVE-2026-33948, we cannot use json with trailing 0x00.
Just remove them and parse through jq.
Fixes: #989
---
tests/generators/lib.sh | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tests/generators/lib.sh b/tests/generators/lib.sh
index 51d38700..440dff7c 100644
--- a/tests/generators/lib.sh
+++ b/tests/generators/lib.sh
@@ -175,9 +175,12 @@ _dd()
dd $@ status=none
}
+# Remove all trailing 0x00 characters
+# Last parameter must be an input file
_jq()
{
- jq -c "$@"
+ local last="${!#}"
+ sed 's/\x00*$//' "$last" | jq -c "${@:1:$#-1}"
}
write_bin_hdr_size() {
--
2.53.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
From 303b319488b652efc68472e1580f5ec0df3e8eba Mon Sep 17 00:00:00 2001
Message-ID: <303b319488b652efc68472e1580f5ec0df3e8eba.1778441857.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Wed, 10 Dec 2025 16:37:20 +0100
Subject: [PATCH] reencrypt: add more gracefull reencryption error path.
This adds proper reencryption error path for non critical
failures not requiring full LUKS2 reencryption recovery.
While non-critical reencryption failures were properly identified
in former code the graceful recovery was never implemented.
This affected the state of live device mappings after failed
reencription. For example, read error on data device did not trigger
LUKS2 recovery scenario (correctly), but the overlay reencryption
device stack for online reencryption remained stuck with hotzone layer
suspended.
This patch addresses the issue.
---
lib/luks2/luks2_reencrypt.c | 86 +++++++++++++++++++++++++++++++++----
1 file changed, 78 insertions(+), 8 deletions(-)
diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c
index 21bd6674..1845a782 100644
--- a/lib/luks2/luks2_reencrypt.c
+++ b/lib/luks2/luks2_reencrypt.c
@@ -2374,11 +2374,6 @@ err:
return r;
}
-/* TODO:
- * 1) audit error path. any error in this routine is fatal and should be unlikely.
- * usually it would hint some collision with another userspace process touching
- * dm devices directly.
- */
static reenc_status_t reenc_refresh_helper_devices(struct crypt_device *cd, const char *overlay,
const char *hotzone)
{
@@ -4125,14 +4120,24 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
/* metadata commit point */
r = reencrypt_hotzone_protect_final(cd, hdr, rh->reenc_keyslot, rp, rh->reenc_buffer, rh->read);
if (r < 0) {
- /* severity normal */
+ /*
+ * Nothing was written in hotzone area yet. Even if metadata write failed the previous
+ * state is still valid. If the metadata write passed and there was another
+ * error it's harmless to do recovery. Recovery may be run several times with no
+ * negative side effect.
+ */
log_err(cd, _("Failed to write reencryption resilience metadata."));
return REENC_ERR_ROLLBACK_MEMORY;
}
r = crypt_storage_wrapper_decrypt(rh->cw1, rh->offset, rh->reenc_buffer, rh->read);
if (r) {
- /* severity normal */
+ /*
+ * Ideally, this would be specific error (REENC_ERR_ROLLBACK_METADATA) case where
+ * it would rollback on-disk metadata to the last valid state (still no write in
+ * hotzone area). But it's not worth the effort. This will trigger full LUKS2
+ * reencryption recovery despite not being necessary.
+ */
log_err(cd, _("Decryption failed."));
return REENC_ERR_ROLLBACK_MEMORY;
}
@@ -4156,7 +4161,6 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
}
if (online) {
- /* severity normal */
log_dbg(cd, "Resuming device %s", rh->hotzone_name);
r = dm_resume_device(cd, rh->hotzone_name, DM_RESUME_PRIVATE);
if (r) {
@@ -4246,6 +4250,7 @@ static int replace_hotzone_device_with_error(struct crypt_device *cd, struct luk
static int teardown_overlay_devices(struct crypt_device *cd, struct luks2_reencrypt *rh)
{
+ bool overlay_suspended, hotzone_suspended;
int r;
/* Reload device with current LUKS2 segments */
@@ -4255,6 +4260,44 @@ static int teardown_overlay_devices(struct crypt_device *cd, struct luks2_reencr
return r;
}
+ overlay_suspended = dm_status_suspended(cd, rh->overlay_name) > 0;
+ hotzone_suspended = dm_status_suspended(cd, rh->hotzone_name) > 0;
+
+ /*
+ * The overlay (if suspended) may hold already queued I/Os.
+ * Reload the overlay device with the table identical to the one
+ * loaded to the top level device. The overlay device will dropped
+ * shortly after successful top level device resume.
+ */
+ if (overlay_suspended) {
+ log_dbg(cd, "Reverting suspended device %s to previous metadata segments", rh->overlay_name);
+ r = LUKS2_reload(cd, rh->overlay_name, rh->vks, rh->device_size, rh->flags);
+ if (r) {
+ log_err(cd, _("Failed to reload device %s."), rh->overlay_name);
+ return r;
+ }
+ }
+
+ /*
+ * if the hotzone is suspended we must error all pending I/O waiting in the device. The
+ * reencryption step was not completed and the pending I/O would corrupt the data on data
+ * device.
+ *
+ * If the hotzone table replacement fails we must abort!
+ */
+ if (hotzone_suspended && (r = replace_hotzone_device_with_error(cd, rh)))
+ return r;
+
+ if (overlay_suspended) {
+ /* Resume will pass since the hotzone (if previously suspended) is now
+ * replaced with live dm-error table */
+ r = dm_resume_device(cd, rh->overlay_name, DM_RESUME_PRIVATE);
+ if (r) {
+ log_err(cd, _("Failed to resume device %s."), rh->overlay_name);
+ return r;
+ }
+ }
+
/* Now we can switch original top level device away from overlay device */
r = dm_resume_device(cd, rh->device_name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r) {
@@ -4322,6 +4365,29 @@ static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
+static void reencrypt_teardown_rollback(struct crypt_device *cd, struct luks2_hdr *hdr,
+ struct luks2_reencrypt *rh)
+{
+ /*
+ * We cannot rollback for REENC_PROTECTION_NONE. It does not commit metadata as
+ * it progresses. In this case, the device stack is intentionally left as-is.
+ */
+ if (rh->rp.type <= REENC_PROTECTION_NONE)
+ return;
+
+ /*
+ * If metadata rollback fails, we cannot proceed with device teardown
+ * as we do not have proper metadata snapshot for LUKS2_reload().
+ */
+ if (LUKS2_hdr_rollback(cd, hdr))
+ return;
+
+ if (!rh->online)
+ return;
+
+ teardown_overlay_devices(cd, rh);
+}
+
static void reencrypt_teardown_fatal(struct crypt_device *cd, struct luks2_reencrypt *rh)
{
log_err(cd, _("Fatal error while reencrypting chunk starting at %" PRIu64 ", %" PRIu64 " sectors long."),
@@ -4347,6 +4413,10 @@ static int reencrypt_teardown(struct crypt_device *cd, struct luks2_hdr *hdr,
progress(rh->device_size, rh->progress, usrptr);
r = reencrypt_teardown_ok(cd, hdr, rh);
break;
+ case REENC_ERR_ROLLBACK_MEMORY:
+ reencrypt_teardown_rollback(cd, hdr, rh);
+ r = -EINVAL;
+ break;
case REENC_ERR_FATAL:
reencrypt_teardown_fatal(cd, rh);
/* fall-through */
--
2.53.0

View File

@ -0,0 +1,173 @@
From 3d49f68bfb6c14c88db260d498d63c306fa6173a Mon Sep 17 00:00:00 2001
Message-ID: <3d49f68bfb6c14c88db260d498d63c306fa6173a.1778441842.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Wed, 10 Dec 2025 16:18:54 +0100
Subject: [PATCH] reencrypt: better name error values to match the description.
---
lib/luks2/luks2_reencrypt.c | 38 ++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c
index 5977a6e9..544e78b8 100644
--- a/lib/luks2/luks2_reencrypt.c
+++ b/lib/luks2/luks2_reencrypt.c
@@ -847,12 +847,12 @@ typedef enum { REENC_OK = 0,
* and teardown reencryption device stack (if used).
* The reencryption fails but does not require recovery
*/
- REENC_ROLLBACK,
+ REENC_ERR_ROLLBACK_MEMORY,
/*
* Error while writing hotzone (short write or sync fail) or failed metadata
* update post hotzone write.
*/
- REENC_FATAL
+ REENC_ERR_FATAL
} reenc_status_t;
void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp)
@@ -2394,21 +2394,21 @@ static reenc_status_t reenc_refresh_helper_devices(struct crypt_device *cd, cons
r = dm_suspend_device(cd, overlay, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r) {
log_err(cd, _("Failed to suspend device %s."), overlay);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
/* suspend HZ device */
r = dm_suspend_device(cd, hotzone, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r) {
log_err(cd, _("Failed to suspend device %s."), hotzone);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
/* resume overlay device: inactive table (with hotozne) -> live */
r = dm_resume_device(cd, overlay, DM_RESUME_PRIVATE);
if (r) {
log_err(cd, _("Failed to resume device %s."), overlay);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
return REENC_OK;
@@ -2426,7 +2426,7 @@ static reenc_status_t reencrypt_refresh_overlay_devices(struct crypt_device *cd,
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone_device, vks, device_size, flags);
if (r) {
log_err(cd, _("Failed to reload device %s."), overlay);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
r = reenc_refresh_helper_devices(cd, overlay, hotzone);
@@ -4069,12 +4069,12 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
/* in memory only */
r = reencrypt_make_segments(cd, hdr, rh, device_size);
if (r)
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
r = reencrypt_assign_segments(cd, hdr, rh, 1, 0);
if (r) {
log_err(cd, _("Failed to set device segments for next reencryption hotzone."));
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
log_dbg(cd, "Reencrypting chunk starting at offset: %" PRIu64 ", size :%" PRIu64 ".", rh->offset, rh->length);
@@ -4092,7 +4092,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
rh->wflags1);
if (r) {
log_err(cd, _("Failed to initialize old segment storage wrapper."));
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
if (rh->rp_moved_segment.type != REENC_PROTECTION_NOT_SET) {
@@ -4104,7 +4104,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
r = reencrypt_hotzone_protect_ready(cd, rp);
if (r) {
log_err(cd, _("Failed to initialize hotzone protection."));
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
if (online) {
@@ -4119,7 +4119,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
if (rh->read < 0) {
/* severity normal */
log_err(cd, _("Failed to read hotzone area starting at %" PRIu64 "."), rh->offset);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
/* metadata commit point */
@@ -4127,24 +4127,24 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
if (r < 0) {
/* severity normal */
log_err(cd, _("Failed to write reencryption resilience metadata."));
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
r = crypt_storage_wrapper_decrypt(rh->cw1, rh->offset, rh->reenc_buffer, rh->read);
if (r) {
/* severity normal */
log_err(cd, _("Decryption failed."));
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
if (rh->read != crypt_storage_wrapper_encrypt_write(rh->cw2, rh->offset, rh->reenc_buffer, rh->read)) {
/* severity fatal */
log_err(cd, _("Failed to write hotzone area starting at %" PRIu64 "."), rh->offset);
- return REENC_FATAL;
+ return REENC_ERR_FATAL;
}
if (rp->type != REENC_PROTECTION_NONE && crypt_storage_wrapper_datasync(rh->cw2)) {
log_err(cd, _("Failed to sync data."));
- return REENC_FATAL;
+ return REENC_ERR_FATAL;
}
/* metadata commit safe point */
@@ -4152,7 +4152,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
if (r) {
/* severity fatal */
log_err(cd, _("Failed to update metadata after current reencryption hotzone completed."));
- return REENC_FATAL;
+ return REENC_ERR_FATAL;
}
if (online) {
@@ -4161,7 +4161,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
r = dm_resume_device(cd, rh->hotzone_name, DM_RESUME_PRIVATE);
if (r) {
log_err(cd, _("Failed to resume device %s."), rh->hotzone_name);
- return REENC_ROLLBACK;
+ return REENC_ERR_ROLLBACK_MEMORY;
}
}
@@ -4317,7 +4317,7 @@ static int reencrypt_teardown(struct crypt_device *cd, struct luks2_hdr *hdr,
progress(rh->device_size, rh->progress, usrptr);
r = reencrypt_teardown_ok(cd, hdr, rh);
break;
- case REENC_FATAL:
+ case REENC_ERR_FATAL:
reencrypt_teardown_fatal(cd, rh);
/* fall-through */
default:
@@ -4391,7 +4391,7 @@ int crypt_reencrypt_run(
r = reencrypt_context_update(cd, rh);
if (r) {
log_err(cd, _("Failed to update reencryption context."));
- rs = REENC_ROLLBACK;
+ rs = REENC_ERR_ROLLBACK_MEMORY;
break;
}
--
2.53.0

View File

@ -0,0 +1,125 @@
From f26218bfc08d7882a6bc814235d1f0f7c3f4997f Mon Sep 17 00:00:00 2001
Message-ID: <f26218bfc08d7882a6bc814235d1f0f7c3f4997f.1778441834.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Wed, 10 Dec 2025 16:14:36 +0100
Subject: [PATCH] reencrypt: merge REENC_ERR and REENC_ROLLBACK errors in one.
The REENC_ERR was unused for anything meaningful and also
the error recovery from non-fatal reencryption failures
will be managed by same code in future commits.
---
lib/luks2/luks2_reencrypt.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c
index dcf349fe..5977a6e9 100644
--- a/lib/luks2/luks2_reencrypt.c
+++ b/lib/luks2/luks2_reencrypt.c
@@ -841,8 +841,6 @@ static crypt_reencrypt_direction_info reencrypt_direction(struct luks2_hdr *hdr)
}
typedef enum { REENC_OK = 0,
- /* to be removed in next commit */
- REENC_ERR,
/*
* The state not requiring LUKS2 reencryption recovery. We can rollback
* to last known safe state (hold in memory since last metadata write)
@@ -2381,7 +2379,8 @@ err:
* usually it would hint some collision with another userspace process touching
* dm devices directly.
*/
-static int reenc_refresh_helper_devices(struct crypt_device *cd, const char *overlay, const char *hotzone)
+static reenc_status_t reenc_refresh_helper_devices(struct crypt_device *cd, const char *overlay,
+ const char *hotzone)
{
int r;
@@ -2395,25 +2394,27 @@ static int reenc_refresh_helper_devices(struct crypt_device *cd, const char *ove
r = dm_suspend_device(cd, overlay, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r) {
log_err(cd, _("Failed to suspend device %s."), overlay);
- return r;
+ return REENC_ROLLBACK;
}
/* suspend HZ device */
r = dm_suspend_device(cd, hotzone, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r) {
log_err(cd, _("Failed to suspend device %s."), hotzone);
- return r;
+ return REENC_ROLLBACK;
}
/* resume overlay device: inactive table (with hotozne) -> live */
r = dm_resume_device(cd, overlay, DM_RESUME_PRIVATE);
- if (r)
+ if (r) {
log_err(cd, _("Failed to resume device %s."), overlay);
+ return REENC_ROLLBACK;
+ }
- return r;
+ return REENC_OK;
}
-static int reencrypt_refresh_overlay_devices(struct crypt_device *cd,
+static reenc_status_t reencrypt_refresh_overlay_devices(struct crypt_device *cd,
struct luks2_hdr *hdr,
const char *overlay,
const char *hotzone,
@@ -2425,16 +2426,14 @@ static int reencrypt_refresh_overlay_devices(struct crypt_device *cd,
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone_device, vks, device_size, flags);
if (r) {
log_err(cd, _("Failed to reload device %s."), overlay);
- return REENC_ERR;
+ return REENC_ROLLBACK;
}
r = reenc_refresh_helper_devices(cd, overlay, hotzone);
- if (r) {
+ if (r != REENC_OK)
log_err(cd, _("Failed to refresh reencryption devices stack."));
- return REENC_ROLLBACK;
- }
- return REENC_OK;
+ return r;
}
static int reencrypt_move_data(struct crypt_device *cd,
@@ -4070,12 +4069,12 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
/* in memory only */
r = reencrypt_make_segments(cd, hdr, rh, device_size);
if (r)
- return REENC_ERR;
+ return REENC_ROLLBACK;
r = reencrypt_assign_segments(cd, hdr, rh, 1, 0);
if (r) {
log_err(cd, _("Failed to set device segments for next reencryption hotzone."));
- return REENC_ERR;
+ return REENC_ROLLBACK;
}
log_dbg(cd, "Reencrypting chunk starting at offset: %" PRIu64 ", size :%" PRIu64 ".", rh->offset, rh->length);
@@ -4162,7 +4161,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
r = dm_resume_device(cd, rh->hotzone_name, DM_RESUME_PRIVATE);
if (r) {
log_err(cd, _("Failed to resume device %s."), rh->hotzone_name);
- return REENC_ERR;
+ return REENC_ROLLBACK;
}
}
@@ -4392,7 +4391,7 @@ int crypt_reencrypt_run(
r = reencrypt_context_update(cd, rh);
if (r) {
log_err(cd, _("Failed to update reencryption context."));
- rs = REENC_ERR;
+ rs = REENC_ROLLBACK;
break;
}
--
2.53.0

View File

@ -0,0 +1,104 @@
From ab4753756a2084928174b97b5b6a6abe970712d9 Mon Sep 17 00:00:00 2001
Message-ID: <ab4753756a2084928174b97b5b6a6abe970712d9.1778441850.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Wed, 10 Dec 2025 17:12:28 +0100
Subject: [PATCH] reencrypt: refactor overlay devices teardown.
---
lib/luks2/luks2_reencrypt.c | 64 +++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 17 deletions(-)
diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c
index 544e78b8..21bd6674 100644
--- a/lib/luks2/luks2_reencrypt.c
+++ b/lib/luks2/luks2_reencrypt.c
@@ -4232,6 +4232,48 @@ static int reencrypt_wipe_unused_device_area(struct crypt_device *cd, struct luk
return r;
}
+static int replace_hotzone_device_with_error(struct crypt_device *cd, struct luks2_reencrypt *rh)
+{
+ log_dbg(cd, "Replacing device %s with dm-error.", rh->hotzone_name);
+ if (dm_error_device(cd, rh->hotzone_name)) {
+ log_err(cd, _("Failed to replace suspended device %s with dm-error target."), rh->hotzone_name);
+ log_err(cd, _("Do not resume the device unless replaced with error target manually."));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int teardown_overlay_devices(struct crypt_device *cd, struct luks2_reencrypt *rh)
+{
+ int r;
+
+ /* Reload device with current LUKS2 segments */
+ r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, rh->flags);
+ if (r) {
+ log_err(cd, _("Failed to reload device %s."), rh->device_name);
+ return r;
+ }
+
+ /* Now we can switch original top level device away from overlay device */
+ r = dm_resume_device(cd, rh->device_name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
+ if (r) {
+ log_err(cd, _("Failed to resume device %s."), rh->device_name);
+ return r;
+ }
+
+ /*
+ * This should not affect teardown return value. There may be other processes
+ * touching those devices despite being private.
+ */
+ if (dm_remove_device(cd, rh->overlay_name, 0))
+ log_dbg(cd, "Failed to remove unused device %s", rh->overlay_name);
+ if (dm_remove_device(cd, rh->hotzone_name, 0))
+ log_dbg(cd, "Failed to remove unused device %s", rh->hotzone_name);
+
+ return 0;
+}
+
static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr, struct luks2_reencrypt *rh)
{
int i, r;
@@ -4245,18 +4287,11 @@ static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr,
}
if (rh->online) {
- r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, rh->flags);
+ r = teardown_overlay_devices(cd, rh);
if (r)
- log_err(cd, _("Failed to reload device %s."), rh->device_name);
- if (!r) {
- r = dm_resume_device(cd, rh->device_name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
- if (r)
- log_err(cd, _("Failed to resume device %s."), rh->device_name);
- }
- dm_remove_device(cd, rh->overlay_name, 0);
- dm_remove_device(cd, rh->hotzone_name, 0);
+ return r;
- if (!r && finished && rh->mode == CRYPT_REENCRYPT_DECRYPT &&
+ if (finished && rh->mode == CRYPT_REENCRYPT_DECRYPT &&
!dm_flags(cd, DM_LINEAR, &dmt_flags) && (dmt_flags & DM_DEFERRED_SUPPORTED))
dm_remove_device(cd, rh->device_name, CRYPT_DEACTIVATE_DEFERRED);
}
@@ -4294,13 +4329,8 @@ static void reencrypt_teardown_fatal(struct crypt_device *cd, struct luks2_reenc
if (rh->online) {
log_err(cd, _("Online reencryption failed."));
- if (dm_status_suspended(cd, rh->hotzone_name) > 0) {
- log_dbg(cd, "Hotzone device %s suspended, replacing with dm-error.", rh->hotzone_name);
- if (dm_error_device(cd, rh->hotzone_name)) {
- log_err(cd, _("Failed to replace suspended device %s with dm-error target."), rh->hotzone_name);
- log_err(cd, _("Do not resume the device unless replaced with error target manually."));
- }
- }
+ if (dm_status_suspended(cd, rh->hotzone_name) > 0)
+ replace_hotzone_device_with_error(cd, rh);
}
}
--
2.53.0

View File

@ -0,0 +1,42 @@
From bccf4da7e5a3e7da40bf7bb8fedbe13147583d85 Mon Sep 17 00:00:00 2001
Message-ID: <bccf4da7e5a3e7da40bf7bb8fedbe13147583d85.1778441820.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Wed, 10 Dec 2025 15:44:14 +0100
Subject: [PATCH] reencrypt: update internal reencryption error state
descriptions.
---
lib/luks2/luks2_reencrypt.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c
index 96749f7d..dcf349fe 100644
--- a/lib/luks2/luks2_reencrypt.c
+++ b/lib/luks2/luks2_reencrypt.c
@@ -840,7 +840,22 @@ static crypt_reencrypt_direction_info reencrypt_direction(struct luks2_hdr *hdr)
return di;
}
-typedef enum { REENC_OK = 0, REENC_ERR, REENC_ROLLBACK, REENC_FATAL } reenc_status_t;
+typedef enum { REENC_OK = 0,
+ /* to be removed in next commit */
+ REENC_ERR,
+ /*
+ * The state not requiring LUKS2 reencryption recovery. We can rollback
+ * to last known safe state (hold in memory since last metadata write)
+ * and teardown reencryption device stack (if used).
+ * The reencryption fails but does not require recovery
+ */
+ REENC_ROLLBACK,
+ /*
+ * Error while writing hotzone (short write or sync fail) or failed metadata
+ * update post hotzone write.
+ */
+ REENC_FATAL
+} reenc_status_t;
void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp)
{
--
2.53.0

View File

@ -0,0 +1,607 @@
From 667bc74b83afd158c8d6a92316f20cdad98f694c Mon Sep 17 00:00:00 2001
Message-ID: <667bc74b83afd158c8d6a92316f20cdad98f694c.1778441875.git.khanicov@redhat.com>
From: Ondrej Kozina <okozina@redhat.com>
Date: Mon, 1 Dec 2025 16:59:08 +0100
Subject: [PATCH] tests: Add reencryption error path tests.
---
tests/luks2-reencryption-test | 289 ++++++++++++++++++++++++++++++++--
1 file changed, 274 insertions(+), 15 deletions(-)
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test
index d1d30c33..f277483e 100755
--- a/tests/luks2-reencryption-test
+++ b/tests/luks2-reencryption-test
@@ -20,6 +20,9 @@ OVRDEV="123reenc321"
DEVBIG="reenc2134"
DEV_NAME=reenc9768
DEV_NAME2=reenc97682
+DEV_HOTZONE_FORWARD="$DEV_NAME-hotzone-forward"
+DEV_HOTZONE_BACKWARD="$DEV_NAME-hotzone-backward"
+DEV_OVERLAY=$DEV_NAME-overlay
IMG=reenc-data
IMG_HDR=$IMG.hdr
HEADER_LUKS2_PV=blkid-luks2-pv.img
@@ -317,6 +320,30 @@ error_io() { # $1 dmdev, $2 data dev, $3 offset, $4 size
blockdev --setra 0 /dev/mapper/$1
}
+error_reads() { # $1 dmdev, $2 data dev, $3 offset, $4 size
+ local _dev_size=$(blockdev --getsz /dev/mapper/$1)
+ local _offset=$(($3+$4))
+ local _size=$((_dev_size-_offset))
+ local _err=$1-err
+ local _table=
+ dmsetup create $_err --table "0 $_dev_size error" || fail
+
+ if [ $3 -ne 0 ]; then
+ _table="0 $3 linear $2 0\n"
+ fi
+
+ _table=$_table"$3 $4 delay /dev/mapper/$_err $3 0 $2 $3 0"
+
+ if [ $_size -ne 0 ]; then
+ _table="$_table\n$_offset $_size linear $2 $_offset"
+ fi
+
+ echo -e "$_table" | dmsetup load $1 || fail
+ dmsetup resume $1 || fail
+ blockdev --setra 0 /dev/mapper/$1
+ blockdev --setra 0 /dev/mapper/$_err
+}
+
error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size
local _dev_size=$(blockdev --getsz /dev/mapper/$1)
local _offset=$(($3+$4))
@@ -341,7 +368,7 @@ error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size
blockdev --setra 0 /dev/mapper/$_err
}
-fix_writes() { # $1 dmdev, $2 data dev
+fix_ios() { # $1 dmdev, $2 data dev
local _dev_size=$(blockdev --getsz /dev/mapper/$1)
dmsetup load $1 --table "0 $_dev_size linear $2 0" || fail
dmsetup resume $1 || fail
@@ -379,6 +406,23 @@ get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if omit
ERROFFSET=$(($ERROFFSET-($ERROFFSET%$_sector_size)))
}
+reencrypt_recover_read_error() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
+ echo -n "resilience mode: $2 ..."
+ local _hdr=""
+ test -z "$4" || _hdr="--header $4"
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 --force-offline-reencrypt -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
+ fix_ios $OVRDEV $OLD_DEV
+
+ check_hash $PWD1 $3 $4
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON || fail
+ check_hash $PWD1 $3 $4
+
+ echo "[OK]"
+}
+
reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
echo -n "resilience mode: $2 ..."
local _hdr=""
@@ -386,7 +430,7 @@ reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 --force-offline-reencrypt -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP -q repair $DEV $_hdr || fail
@@ -409,7 +453,7 @@ reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest, [$4 hea
echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
$CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery during activation
echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail
@@ -426,6 +470,61 @@ reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest, [$4 hea
echo "[OK]"
}
+check_device_removed() { # $1 dm device name
+ # ignore racy udev or udev-like hacks in some distributions
+ dmsetup status $1 >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ local msg="Device $1 is still active"
+
+ local ret=$(dmsetup info -C --nohead $1 | cut -d ':' -f 4)
+
+ [ ${#ret} -eq 4 ] || fail
+ [ ${ret:2:1} = "s" ] && msg="$msg and suspended."
+
+ fail "$msg"
+ fi
+}
+
+reencrypt_recover_read_error_online() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
+ echo -n "resilience mode: $2 ..."
+ local _hdr=""
+ test -z "$4" || _hdr="--header $4"
+
+ echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
+
+ # less severe reencryption errors should not leave helper devices behind
+ check_device_removed $DEV_HOTZONE_FORWARD
+ check_device_removed $DEV_OVERLAY
+
+ # The read error may have failed the reencryption initialization (blkid scans are mandatory).
+ # Check if device is in reencryption state
+ $CRYPTSETUP luksDump ${4:-$DEV} | grep -q "in-reencryption"
+ if [ $? -eq 0 ]; then
+ # the device is expected in interrupted reencryption
+ $CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail
+
+ fix_ios $OVRDEV $OLD_DEV
+
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ # verify it does correct segment mappings (LUKS2 contains correct state description)
+ echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+
+ echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --resilience $2 --resume-only -q || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+ else
+ fix_ios $OVRDEV $OLD_DEV
+ fi
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ echo "[OK]"
+}
+
reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
echo -n "resilience mode: $2 ..."
local _hdr=""
@@ -441,7 +540,7 @@ reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 digest, [$4
echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
$CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery during activation
$CRYPTSETUP open --volume-key-keyring $KEY_NAME1 --volume-key-keyring $KEY_NAME2 $DEV $_hdr $DEV_NAME || fail
@@ -468,7 +567,7 @@ encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size
error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q >/dev/null 2>&1 && fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP -q repair $DEV || fail
@@ -483,6 +582,26 @@ encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size
echo "[OK]"
}
+encrypt_recover_read_error() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest
+ wipe_dev $DEV
+ check_hash_dev $DEV $5
+
+ echo -n "resilience mode: datashift ..."
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only >/dev/null 2>&1 || fail
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q >/dev/null 2>&1 && fail
+ fix_ios $OVRDEV $OLD_DEV
+ check_hash $PWD1 $3
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only --sector-size $1 -q $FAST_PBKDF_ARGON || fail
+
+ check_hash_head $PWD1 $4 $3
+
+ echo "[OK]"
+}
+
encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest
wipe_dev $DEV
check_hash_dev $DEV $5
@@ -496,7 +615,7 @@ encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 devic
echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q >/dev/null 2>&1 && fail
$CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery in activation
echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
@@ -514,6 +633,41 @@ encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 devic
echo "[OK]"
}
+encrypt_recover_read_error_online() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest
+ wipe_dev $DEV
+ check_hash_dev $DEV $5
+
+ echo -n "resilience mode: datashift ..."
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only > /dev/null || fail
+ echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt --resume-only --active-name $DEV_NAME -q >/dev/null 2>&1 && fail
+
+ # less severe reencryption errors should not leave helper devices behind
+ check_device_removed $DEV_HOTZONE_BACKWARD
+ check_device_removed $DEV_OVERLAY
+
+ $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" || fail
+ $CRYPTSETUP luksDump $DEV | grep -q "in-reencryption" && fail
+ fix_ios $OVRDEV $OLD_DEV
+
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ # recovery in activation
+ echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+
+ echo $PWD1 | $CRYPTSETUP reencrypt --resume-only --active-name $DEV_NAME -q || fail
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ check_hash_head $PWD1 $4 $3
+
+ echo "[OK]"
+}
+
encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
wipe_dev $DEV
check_hash_dev $DEV $3
@@ -522,7 +676,7 @@ encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --hotzone-size 1M --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP repair $DEV --header $4 || fail
@@ -549,7 +703,7 @@ encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest,
echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $4 --hotzone-size 1M 2>/dev/null && fail
$CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail
check_hash_dev /dev/mapper/$DEV_NAME $3
@@ -577,7 +731,7 @@ decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP repair $DEV --header $4 || fail
@@ -594,6 +748,29 @@ decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
echo "[OK]"
}
+decrypt_recover_read_error_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1 $4
+ check_hash $PWD1 $3 $4
+
+ echo -n "resilience mode: $2 ..."
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail
+ fix_ios $OVRDEV $OLD_DEV
+ $CRYPTSETUP luksDump $4 | grep -q "in-reencryption" && fail
+
+ check_hash $PWD1 $3 $4
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only --header $4 --resilience $2 -q || fail
+
+ check_hash_dev $DEV $3
+
+ [ -f $4 ] && rm -f $4
+
+ echo "[OK]"
+}
+
decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail
echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail
@@ -606,7 +783,7 @@ decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest,
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail
$CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery during activation
echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail
@@ -626,6 +803,35 @@ decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest,
echo "[OK]"
}
+decrypt_recover_read_error_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail
+ echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail
+ wipe_dev /dev/mapper/$DEV_NAME
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+
+ echo -n "resilience mode: $2 ..."
+
+ error_reads $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail
+ $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail
+ fix_ios $OVRDEV $OLD_DEV
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail
+
+ $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only --header $4 --resilience $2 -q || fail
+
+ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail
+ check_hash_dev $DEV $3
+
+ [ -f $4 ] && rm -f $4
+
+ echo "[OK]"
+}
+
decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone size
local _res=""
local _maxhz=""
@@ -637,7 +843,7 @@ decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone si
error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
echo $PWD1 | $CRYPTSETUP -q repair $DEV --header $2 || fail
@@ -667,7 +873,7 @@ decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail
$CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery during activation
echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME || fail
@@ -696,7 +902,7 @@ decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail
$CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail
$CRYPTSETUP close $DEV_NAME || fail
- fix_writes $OVRDEV $OLD_DEV
+ fix_ios $OVRDEV $OLD_DEV
# recovery but activation fails due to last segment recovery makes it plaintext device
echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME 2>/dev/null && fail
@@ -1258,7 +1464,7 @@ ERROFFSET=34816
ERRLENGTH=65536
error_io $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 1M --reduce-device-size 32M -q $FAST_PBKDF_ARGON || fail
-fix_writes $OVRDEV $OLD_DEV
+fix_ios $OVRDEV $OLD_DEV
check_hash_head $PWD1 2048 $HASH2
wipe_dev_head $DEV 43
@@ -1268,7 +1474,7 @@ ERRLENGTH=12288
# data device: [ reduce-device-size / 2 ] [ device-size ] [ error minefield ] [ reduce-device-size / 2]
error_io $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 43M --reduce-device-size 16M -q $FAST_PBKDF_ARGON || fail
-fix_writes $OVRDEV $OLD_DEV
+fix_ios $OVRDEV $OLD_DEV
check_hash_head $PWD1 88064 $HASH6
echo "[3] Encryption with detached header"
@@ -1431,6 +1637,9 @@ echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover 512 checksum $HASH1
reencrypt_recover 512 journal $HASH1
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+reencrypt_recover_read_error 512 checksum $HASH1
+
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 512->4096"
@@ -1443,6 +1652,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
wipe $PWD1
reencrypt_recover 4096 journal $HASH1
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1
+
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error 4096 checksum $HASH1
echo "sector size 4096->4096"
@@ -1453,6 +1667,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover 4096 checksum $HASH1
reencrypt_recover 4096 journal $HASH1
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error 4096 checksum $HASH1
fi
echo "[7] Reencryption recovery (online i/o error)"
@@ -1466,6 +1682,8 @@ wipe $PWD1
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover_online 512 checksum $HASH1
reencrypt_recover_online 512 journal $HASH1
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+reencrypt_recover_read_error_online 512 checksum $HASH1
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 512->4096"
@@ -1479,6 +1697,10 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
wipe $PWD1
reencrypt_recover_online 4096 journal $HASH1
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error_online 4096 checksum $HASH1
echo "sector size 4096->4096"
@@ -1489,6 +1711,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover_online 4096 checksum $HASH1
reencrypt_recover_online 4096 journal $HASH1
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error_online 4096 checksum $HASH1
fi
if [ $HAVE_KEYRING -eq 1 ]; then
@@ -1540,6 +1764,8 @@ check_hash $PWD1 $HASH7 $IMG_HDR
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover 512 checksum $HASH7 $IMG_HDR
reencrypt_recover 512 journal $HASH7 $IMG_HDR
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+reencrypt_recover_read_error 512 checksum $HASH7 $IMG_HDR
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 512->4096"
@@ -1553,6 +1779,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail
wipe $PWD1 $IMG_HDR
reencrypt_recover 4096 journal $HASH7 $IMG_HDR
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1 $IMG_HDR
+
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error 4096 checksum $HASH7 $IMG_HDR
echo "sector size 4096->4096"
@@ -1563,6 +1794,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover 4096 checksum $HASH7 $IMG_HDR
reencrypt_recover 4096 journal $HASH7 $IMG_HDR
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error 4096 checksum $HASH7 $IMG_HDR
fi
echo "[9] Reencryption with detached header recovery (online i/o error)"
@@ -1576,6 +1809,8 @@ wipe $PWD1 $IMG_HDR
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover_online 512 checksum $HASH7 $IMG_HDR
reencrypt_recover_online 512 journal $HASH7 $IMG_HDR
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+reencrypt_recover_read_error_online 512 checksum $HASH7 $IMG_HDR
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 512->4096"
@@ -1590,6 +1825,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
wipe $PWD1 $IMG_HDR
reencrypt_recover_online 4096 journal $HASH7 $IMG_HDR
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1 $IMG_HDR
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error_online 4096 checksum $HASH7 $IMG_HDR
+
echo "sector size 4096->4096"
get_error_offsets 31 0 4096
@@ -1599,6 +1839,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
reencrypt_recover_online 4096 checksum $HASH7 $IMG_HDR
reencrypt_recover_online 4096 journal $HASH7 $IMG_HDR
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_read_error_online 4096 checksum $HASH7 $IMG_HDR
fi
echo "[10] Encryption recovery"
@@ -1611,6 +1853,8 @@ get_error_offsets 64 $OFFSET 512 $((62*1024*2))
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
encrypt_recover 512 4M $HASH8 $((60*1024*2)) $HASH4
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+encrypt_recover_read_error 512 4M $HASH8 $((60*1024*2)) $HASH4
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 4096"
@@ -1619,6 +1863,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
encrypt_recover 4096 4M $HASH8 $((60*1024*2)) $HASH4
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ encrypt_recover_read_error 4096 4M $HASH8 $((60*1024*2)) $HASH4
fi
echo "[11] Encryption recovery (online i/o error)"
@@ -1629,6 +1875,8 @@ get_error_offsets 64 $OFFSET 512 $((62*1024*2))
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
encrypt_recover_online 512 4M $HASH8 $((60*1024*2)) $HASH4
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+encrypt_recover_read_error_online 512 4M $HASH8 $((60*1024*2)) $HASH4
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 4096"
@@ -1637,6 +1885,9 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
encrypt_recover_online 4096 4M $HASH8 $((60*1024*2)) $HASH4
+
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ encrypt_recover_read_error_online 4096 4M $HASH8 $((60*1024*2)) $HASH4
fi
echo "[12] Encryption with detached header recovery"
@@ -1690,6 +1941,8 @@ get_error_offsets 31 2049
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
decrypt_recover_detached 512 journal $HASH7 $IMG_HDR
decrypt_recover_detached 512 checksum $HASH7 $IMG_HDR
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+decrypt_recover_read_error_detached 512 checksum $HASH7 $IMG_HDR
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 4096"
@@ -1700,6 +1953,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
decrypt_recover_detached 4096 checksum $HASH7 $IMG_HDR
decrypt_recover_detached 4096 journal $HASH7 $IMG_HDR
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ decrypt_recover_read_error_detached 4096 checksum $HASH7 $IMG_HDR
fi
echo "[15] Decryption with detached header recovery (online i/o error)"
@@ -1712,6 +1967,8 @@ get_error_offsets 31 2049
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
decrypt_recover_detached_online 512 journal $HASH7 $IMG_HDR
decrypt_recover_detached_online 512 checksum $HASH7 $IMG_HDR
+echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+decrypt_recover_read_error_detached_online 512 checksum $HASH7 $IMG_HDR
if [ -n "$DM_SECTOR_SIZE" ]; then
echo "sector size 4096"
@@ -1722,6 +1979,8 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
decrypt_recover_detached_online 4096 checksum $HASH7 $IMG_HDR
decrypt_recover_detached_online 4096 journal $HASH7 $IMG_HDR
+ echo "ERR reads to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ decrypt_recover_read_error_detached_online 4096 checksum $HASH7 $IMG_HDR
fi
echo "[16] Offline reencryption with fixed device size."
--
2.53.0

View File

@ -1,7 +1,7 @@
Summary: Utility for setting up encrypted disks
Name: cryptsetup
Version: 2.8.1
Release: 2%{?dist}
Version: 2.8.6
Release: 1%{?dist}
License: GPL-2.0-or-later WITH cryptsetup-OpenSSL-exception AND LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception
URL: https://gitlab.com/cryptsetup/cryptsetup
BuildRequires: autoconf, automake, libtool, gettext-devel,
@ -22,13 +22,14 @@ Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-%{ups
Patch0001: %{name}-Add-FIPS-related-error-message-in-keyslot-add-code.patch
Patch0002: %{name}-Enable-to-use-Argon2-in-FIPS-with-openssl-backend.patch
Patch0003: %{name}-Warn-if-Argon2-keyslot-is-unlocked-in-FIPS-mode.patch
Patch0004: %{name}-2.8.2-opal-Submit-PSID-reset-command-to-R-W-file-descripto.patch
Patch0005: %{name}-2.8.2-Read-integrity-profile-info-from-top-level-device.patch
Patch0006: %{name}-2.8.2-Fix-possible-use-of-uninitialized-variable.patch
Patch0007: %{name}-2.8.2-Reinstate-pbkdf-serialization-flag-in-device-activat.patch
Patch0008: %{name}-2.8.2-Fix-LUKS2-device-status-in-inline-HW-mode-and-detach.patch
Patch0009: %{name}-2.8.2-Set-inline-integrity-flag-if-no-underlying-dm-integr.patch
Patch0010: %{name}-2.8.4-Fix-wrong-device-size-status-reports-in-cryptsetup.patch
Patch0004: %{name}-2.8.7-ci-Replace-jq-with-bash-wrapper.patch
Patch0005: %{name}-2.8.7-ci-Fix-jq-no-longer-handling-0x00-characters.patch
Patch0006: %{name}-2.8.7-reencrypt-update-internal-reencryption-error-state-d.patch
Patch0007: %{name}-2.8.7-reencrypt-merge-REENC_ERR-and-REENC_ROLLBACK-errors-.patch
Patch0008: %{name}-2.8.7-reencrypt-better-name-error-values-to-match-the-desc.patch
Patch0009: %{name}-2.8.7-reencrypt-refactor-overlay-devices-teardown.patch
Patch0010: %{name}-2.8.7-reencrypt-add-more-gracefull-reencryption-error-path.patch
Patch0011: %{name}-2.8.7-tests-Add-reencryption-error-path-tests.patch
%description
The cryptsetup package contains a utility for setting up
@ -116,6 +117,18 @@ rm -rf %{buildroot}%{_libdir}/%{name}/*.la
%ghost %attr(700, -, -) %dir /run/cryptsetup
%changelog
* Fri May 08 2026 Kristina Hanicova <khanicov@redhat.com> - 2.8.6-1
- Update to cryptsetup 2.8.6.
- patch: ci: Replace jq with bash wrapper.
- patch: ci: Fix jq no longer handling 0x00 characters.
- patch: reencrypt: update internal reencryption error state descriptions.
- patch: reencrypt: merge REENC_ERR and REENC_ROLLBACK errors in one.
- patch: reencrypt: better name error values to match the description.
- patch: reencrypt: refactor overlay devices teardown.
- patch: reencrypt: add more gracefull reencryption error path.
- patch: tests: Add reencryption error path tests.
- Resolves: 163434
* Fri Jan 09 2026 Kristina Hanicova <khanicov@redhat.com> - 2.8.1-2
- patch: opal: Submit PSID reset command to R/W file descriptor.
- patch: Read integrity profile info from top level device.

View File

@ -1 +1 @@
SHA512 (cryptsetup-2.8.1.tar.xz) = a5171e18c55bfbc57330f2d46ab06b5ac6957392a77aef74c3d1c5295eb39962d1db19ddd3420ea1154d730b361d09e72bf5315c7a3d56eb36cee9c2531bca5d
SHA512 (cryptsetup-2.8.6.tar.xz) = b580e0b384a590447cf21a9d50142e7f799c3dae0fc13999886db45716f95523fa47c795335a27a7282ff1ee67eedd69989c56e6a429016aa957171fe2646d5e