Properly block opal devices from deferred deactivation.

The check did not work properly for stacked dm_crypt over
hw opal devices.

Also it did not work at all for active dm mappings with
missing (or detached) LUKS2 metadata.
This commit is contained in:
Ondrej Kozina
2024-10-08 13:55:20 +02:00
committed by Milan Broz
parent 7c83d4e639
commit e4bf1f91b9
2 changed files with 27 additions and 16 deletions

View File

@@ -5957,13 +5957,10 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
} }
if (flags & (CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) { if (flags & (CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) {
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); r = crypt_get_hw_encryption_type(cd);
if (hdr) { if (r == CRYPT_SW_AND_OPAL_HW || r == CRYPT_OPAL_HW_ONLY) {
json_object *jobj = json_segments_get_segment(LUKS2_get_segments_jobj(hdr), 0); log_err(cd, _("OPAL does not support deferred deactivation."));
if (jobj && !strcmp(json_segment_type(jobj), "hw-opal")) { return -EINVAL;
log_err(cd, _("OPAL does not support deferred deactivation."));
return -EINVAL;
}
} }
} }
@@ -5974,13 +5971,6 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
switch (crypt_status(cd, name)) { switch (crypt_status(cd, name)) {
case CRYPT_ACTIVE: case CRYPT_ACTIVE:
case CRYPT_BUSY: case CRYPT_BUSY:
if (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL) {
r = dm_cancel_deferred_removal(name);
if (r < 0)
log_err(cd, _("Could not cancel deferred remove from device %s."), name);
break;
}
r = dm_query_device(cd, name, get_flags, &dmd); r = dm_query_device(cd, name, get_flags, &dmd);
if (r >= 0) { if (r >= 0) {
if (dmd.holders) { if (dmd.holders) {
@@ -5990,8 +5980,23 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
} }
} }
if (isLUKS2(cd->type)) /* For detached header case or missing metadata we need to check for OPAL2 devices
hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2); * from DM UUID */
if (dmd.uuid && (flags & (CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) &&
!strncmp(CRYPT_LUKS2_HW_OPAL, dmd.uuid, sizeof(CRYPT_LUKS2_HW_OPAL)-1)) {
log_err(cd, _("OPAL does not support deferred deactivation."));
r = -EINVAL;
break;
}
if (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL) {
r = dm_cancel_deferred_removal(name);
if (r < 0)
log_err(cd, _("Could not cancel deferred remove from device %s."), name);
break;
}
hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2);
if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2) if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2)
r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags); r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags);

View File

@@ -391,6 +391,8 @@ function test_device() #opal_mode, #format_params, #--integrity-no-wipe
dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail
dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail
$CRYPTSETUP close --cancel-deferred $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP close --deferred $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP close $DEV_NAME || fail $CRYPTSETUP close $DEV_NAME || fail
dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
@@ -406,9 +408,13 @@ function test_device_detached_header() #hdr, #opal_mode, #format_params, #--inte
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $1 || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $1 || fail
dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail
$CRYPTSETUP close --cancel-deferred $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP close --deferred $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP close $DEV_NAME || fail $CRYPTSETUP close $DEV_NAME || fail
dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail
$CRYPTSETUP close $DEV_NAME --header $1 --cancel-deferred 2>/dev/null && fail
$CRYPTSETUP close $DEV_NAME --header $1 --deferred 2>/dev/null && fail
$CRYPTSETUP close $DEV_NAME --header $1 || fail $CRYPTSETUP close $DEV_NAME --header $1 || fail
dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail
echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q --header $1 || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q --header $1 || fail