Skip to content

Commit

Permalink
Suspend and resume also dm-integrity device with AEAD.
Browse files Browse the repository at this point in the history
Currently we suspend top-level device only.

With OPAL, the underlying device will start to return errors
once OPAL LR is locked.

If the dm-integrity device is not suspended, regular journal
flush corrupts the device (journal write failure),
corrupting data above it.

Suspending the whole stack should fix the issue.
  • Loading branch information
mbroz committed Nov 17, 2023
1 parent d54c927 commit 630703b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
12 changes: 12 additions & 0 deletions lib/libdevmapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -3041,6 +3041,18 @@ const char *dm_get_dir(void)
return dm_dir();
}

int dm_get_iname(const char *name, char **iname, bool with_path)
{
int r;

if (with_path)
r = asprintf(iname, "%s/%s_dif", dm_get_dir(), name);
else
r = asprintf(iname, "%s_dif", name);

return r < 0 ? -ENOMEM : 0;
}

int dm_is_dm_device(int major)
{
return dm_is_dm_major((uint32_t)major);
Expand Down
39 changes: 33 additions & 6 deletions lib/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -3894,7 +3894,7 @@ int crypt_suspend(struct crypt_device *cd,
struct crypt_dm_active_device dmd;
uint32_t opal_segment_number = 1, dmflags = DM_SUSPEND_WIPE_KEY;
struct dm_target *tgt = &dmd.segment;
char *key_desc = NULL;
char *key_desc = NULL, *iname = NULL;

if (!cd || !name)
return -EINVAL;
Expand Down Expand Up @@ -3989,12 +3989,23 @@ int crypt_suspend(struct crypt_device *cd,
goto out;
}

if (crypt_get_integrity_tag_size(cd)) {
r = dm_get_iname(name, &iname, false);
if (r)
goto out;

r = dm_suspend_device(cd, iname, 0);
if (r)
log_err(cd, _("Error during suspending device %s."), iname);
}

crypt_drop_keyring_key_by_description(cd, key_desc, cd->keyring_key_type);

if (dm_opal_uuid && (!crypt_data_device(cd) || opal_lock(cd, crypt_data_device(cd), opal_segment_number)))
log_err(cd, _("Device %s was suspended but hardware OPAL device cannot be locked."), name);
out:
free(key_desc);
free(iname);
dm_targets_free(cd, &dmd);
free(CONST_CAST(void*)dmd.uuid);
return r;
Expand Down Expand Up @@ -4077,6 +4088,7 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd,
uint32_t opal_segment_number;
key_serial_t user_vk_kid = 0;
struct volume_key *p_crypt = vk, *p_opal = NULL, *zerokey = NULL, *crypt_key = NULL, *opal_key = NULL;
char *iname = NULL;

assert(digest >= 0);
assert(vk && crypt_volume_key_get_id(vk) == digest);
Expand Down Expand Up @@ -4140,6 +4152,16 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd,
}
}

if (crypt_get_integrity_tag_size(cd)) {
r = dm_get_iname(name, &iname, false);
if (r)
goto out;

r = dm_resume_device(cd, iname, 0);
if (r)
log_err(cd, _("Error during resuming device %s."), iname);
}

if (enc_type == CRYPT_OPAL_HW_ONLY)
r = dm_resume_device(cd, name, 0);
else
Expand All @@ -4163,6 +4185,7 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd,
crypt_free_volume_key(zerokey);
crypt_free_volume_key(opal_key);
crypt_free_volume_key(crypt_key);
free(iname);

return r;
}
Expand Down Expand Up @@ -4743,15 +4766,18 @@ int create_or_reload_device_with_integrity(struct crypt_device *cd, const char *
struct crypt_dm_active_device *dmdi)
{
int r;
const char *iname = NULL;
char *ipath = NULL;
char *iname = NULL, *ipath = NULL;

if (!type || !name || !dmd || !dmdi)
return -EINVAL;

if (asprintf(&ipath, "%s/%s_dif", dm_get_dir(), name) < 0)
return -ENOMEM;
iname = ipath + strlen(dm_get_dir()) + 1;
r = dm_get_iname(name, &iname, false);
if (r)
goto out;

r = dm_get_iname(name, &ipath, true);
if (r)
goto out;

/* drop CRYPT_ACTIVATE_REFRESH flag if any device is inactive */
r = check_devices(cd, name, iname, &dmd->flags);
Expand All @@ -4764,6 +4790,7 @@ int create_or_reload_device_with_integrity(struct crypt_device *cd, const char *
r = _create_device_with_integrity(cd, type, name, iname, ipath, dmd, dmdi);
out:
free(ipath);
free(iname);

return r;
}
Expand Down
1 change: 1 addition & 0 deletions lib/utils_dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ int dm_clear_device(struct crypt_device *cd, const char *name);
int dm_cancel_deferred_removal(const char *name);

const char *dm_get_dir(void);
int dm_get_iname(const char *name, char **iname, bool with_path);

int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type);

Expand Down

0 comments on commit 630703b

Please sign in to comment.