diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index a887f4b2..420de700 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -600,7 +600,8 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd, crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd, struct crypt_params_reencrypt *params); -int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock); +int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock); +int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock); void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock); int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic); diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index a143b3b3..51b18346 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -2205,26 +2205,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr struct dm_target *tgt; crypt_status_info ci; struct crypt_dm_active_device dmdc; - char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 }; + char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 }; const char *namei = NULL; struct crypt_lock_handle *reencrypt_lock = NULL; - if (!dmd || !dmd->uuid) + if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1)) + return -EINVAL; + + /* uuid mismatch with metadata (if available) */ + if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid)) return -EINVAL; r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6); if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1)) return -EINVAL; - r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s", - dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26); - if (r < 0 || (size_t)r != (sizeof(uuid) - 1)) - return -EINVAL; - - /* uuid mismatch with metadata (if available) */ - if (hdr && strcmp(hdr->uuid, uuid)) - return -EINVAL; - tgt = &dmd->segment; /* TODO: We have LUKS2 dependencies now */ @@ -2236,7 +2231,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr goto out; if (contains_reencryption_helper(deps)) { - r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock); + r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock); if (r) { if (r == -EBUSY) log_err(cd, _("Reencryption in-progress. Cannot deactivate device.")); diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index 718f3477..5edc266c 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -2546,21 +2546,10 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr, return 0; } -/* internal only */ -int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock) +static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock) { int r; char *lock_resource; - const char *tmp = crypt_get_uuid(cd); - - if (!tmp && !uuid) - return -EINVAL; - if (!uuid) - uuid = tmp; - if (!tmp) - tmp = uuid; - if (strcmp(uuid, tmp)) - return -EINVAL; if (!crypt_metadata_locking_enabled()) { *reencrypt_lock = NULL; @@ -2582,6 +2571,36 @@ out: return r; } +/* internal only */ +int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock) +{ + int r; + char hdr_uuid[37]; + const char *uuid = crypt_get_uuid(cd); + + if (!dm_uuid) + return -EINVAL; + + if (!uuid) { + r = snprintf(hdr_uuid, sizeof(hdr_uuid), "%.8s-%.4s-%.4s-%.4s-%.12s", + dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26); + if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1)) + return -EINVAL; + } else if (crypt_uuid_cmp(dm_uuid, uuid)) + return -EINVAL; + + return reencrypt_lock_internal(cd, uuid, reencrypt_lock); +} + +/* internal only */ +int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock) +{ + if (!cd || !crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2)) + return -EINVAL; + + return reencrypt_lock_internal(cd, crypt_get_uuid(cd), reencrypt_lock); +} + /* internal only */ void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock) { @@ -2605,7 +2624,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr * return -EINVAL; } - r = crypt_reencrypt_lock(cd, NULL, &h); + r = crypt_reencrypt_lock(cd, &h); if (r < 0) { if (r == -EBUSY) log_err(cd, _("Reencryption process is already running.")); @@ -2809,7 +2828,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd, crypt_reencrypt_info ri; struct crypt_lock_handle *reencrypt_lock; - r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock); + r = crypt_reencrypt_lock(cd, &reencrypt_lock); if (r) { if (r == -EBUSY) log_err(cd, _("Reencryption in-progress. Cannot perform recovery.")); diff --git a/lib/setup.c b/lib/setup.c index be57864c..0d6ca7e4 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -3888,7 +3888,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd, if (crypt_use_keyring_for_vk(cd)) flags |= CRYPT_ACTIVATE_KEYRING_KEY; - r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock); + r = crypt_reencrypt_lock(cd, &reencrypt_lock); if (r) { if (r == -EBUSY) log_err(cd, _("Reencryption in-progress. Cannot activate device.")); @@ -4354,7 +4354,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t if (isLUKS2(cd->type)) hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2); - if (!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); else if (isTCRYPT(cd->type)) r = TCRYPT_deactivate(cd, name, flags);