diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index 45ea5fa7..9deae4af 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -337,7 +337,7 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3 int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs); int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs); -int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, int quiet); +int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet); int crypt_use_keyring_for_vk(const struct crypt_device *cd); int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk); diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index 32737755..65eb3ae2 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -1023,7 +1023,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr, } /* do not allow header restore from backup with unmet requirements */ - if (LUKS2_unmet_requirements(cd, &hdr_file, 1)) { + if (LUKS2_unmet_requirements(cd, &hdr_file, 0, 1)) { log_err(cd, _("Unmet LUKS2 requirements detected in backup %s.\n"), backup_file); return -ETXTBSY; @@ -1733,7 +1733,7 @@ int LUKS2_activate(struct crypt_device *cd, struct device *device = NULL; /* do not allow activation when particular requirements detected */ - if ((r = LUKS2_unmet_requirements(cd, hdr, 0))) + if ((r = LUKS2_unmet_requirements(cd, hdr, 0, 0))) return r; /* Add persistent activation flags */ @@ -1792,21 +1792,27 @@ int LUKS2_activate(struct crypt_device *cd, return r; } -int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, int quiet) +int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet) { uint32_t reqs; int r = LUKS2_config_get_requirements(cd, hdr, &reqs); if (r) { - log_err(cd, _("Failed to read LUKS2 requierements.\n")); + if (!quiet) + log_err(cd, _("Failed to read LUKS2 requierements.\n")); return r; } - if (reqs_unknown(reqs)) - r = -ETXTBSY; + /* do not mask unknown requirements check */ + if (reqs_unknown(reqs)) { + if (!quiet) + log_err(cd, _("Unmet LUKS2 requirements detected.\n")); + return -ETXTBSY; + } - if (r && !quiet) - log_err(cd, _("Unmet LUKS2 requirements detected.\n")); + /* mask out permitted requirements */ + reqs &= ~reqs_mask; - return r; + /* any remaining unmasked requirement fails the check */ + return reqs ? -EINVAL : 0; } diff --git a/lib/setup.c b/lib/setup.c index cbb23194..2c24bd1a 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -308,14 +308,10 @@ static int _onlyLUKS(struct crypt_device *cd, uint32_t cdflags) r = -EINVAL; } - if (r || (cdflags & CRYPT_CD_UNRESTRICTED)) + if (r || (cdflags & CRYPT_CD_UNRESTRICTED) || isLUKS1(cd->type)) return r; - if (isLUKS2(cd->type) && - LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, cdflags & CRYPT_CD_QUIET)) - r = -ETXTBSY; - - return r; + return LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, cdflags & CRYPT_CD_QUIET); } static int onlyLUKS(struct crypt_device *cd) @@ -342,7 +338,7 @@ static int _onlyLUKS2(struct crypt_device *cd, uint32_t cdflags) if (r || (cdflags & CRYPT_CD_UNRESTRICTED)) return r; - return LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, cdflags & CRYPT_CD_QUIET) ? -ETXTBSY : 0; + return LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, cdflags & CRYPT_CD_QUIET); } static int onlyLUKS2(struct crypt_device *cd) @@ -2061,9 +2057,9 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) dmd.size = new_size; if (isTCRYPT(cd->type)) r = -ENOTSUP; - else if (isLUKS2(cd->type) && LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0)) - r = -ETXTBSY; - else + else if (isLUKS2(cd->type)) + r = LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, 0); + if (!r) r = dm_create_device(cd, name, cd->type, &dmd, 1); } out: