luks2: allow masking of requirements internaly

before this patch any LUKS2 requirement defined in header
would stop a restricted operation from proceeding further.
This patch adds ability to mask requirements (internal only).
This commit is contained in:
Ondrej Kozina
2017-09-26 18:13:35 +02:00
committed by Milan Broz
parent b3feae5474
commit b4782809d4
3 changed files with 22 additions and 20 deletions

View File

@@ -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_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_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_use_keyring_for_vk(const struct crypt_device *cd);
int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk); int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk);

View File

@@ -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 */ /* 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"), log_err(cd, _("Unmet LUKS2 requirements detected in backup %s.\n"),
backup_file); backup_file);
return -ETXTBSY; return -ETXTBSY;
@@ -1733,7 +1733,7 @@ int LUKS2_activate(struct crypt_device *cd,
struct device *device = NULL; struct device *device = NULL;
/* do not allow activation when particular requirements detected */ /* 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; return r;
/* Add persistent activation flags */ /* Add persistent activation flags */
@@ -1792,21 +1792,27 @@ int LUKS2_activate(struct crypt_device *cd,
return r; 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; uint32_t reqs;
int r = LUKS2_config_get_requirements(cd, hdr, &reqs); int r = LUKS2_config_get_requirements(cd, hdr, &reqs);
if (r) { if (r) {
log_err(cd, _("Failed to read LUKS2 requierements.\n")); if (!quiet)
log_err(cd, _("Failed to read LUKS2 requierements.\n"));
return r; return r;
} }
if (reqs_unknown(reqs)) /* do not mask unknown requirements check */
r = -ETXTBSY; if (reqs_unknown(reqs)) {
if (!quiet)
log_err(cd, _("Unmet LUKS2 requirements detected.\n"));
return -ETXTBSY;
}
if (r && !quiet) /* mask out permitted requirements */
log_err(cd, _("Unmet LUKS2 requirements detected.\n")); reqs &= ~reqs_mask;
return r; /* any remaining unmasked requirement fails the check */
return reqs ? -EINVAL : 0;
} }

View File

@@ -308,14 +308,10 @@ static int _onlyLUKS(struct crypt_device *cd, uint32_t cdflags)
r = -EINVAL; r = -EINVAL;
} }
if (r || (cdflags & CRYPT_CD_UNRESTRICTED)) if (r || (cdflags & CRYPT_CD_UNRESTRICTED) || isLUKS1(cd->type))
return r; return r;
if (isLUKS2(cd->type) && return LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, cdflags & CRYPT_CD_QUIET);
LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, cdflags & CRYPT_CD_QUIET))
r = -ETXTBSY;
return r;
} }
static int onlyLUKS(struct crypt_device *cd) 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)) if (r || (cdflags & CRYPT_CD_UNRESTRICTED))
return r; 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) 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; dmd.size = new_size;
if (isTCRYPT(cd->type)) if (isTCRYPT(cd->type))
r = -ENOTSUP; r = -ENOTSUP;
else if (isLUKS2(cd->type) && LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0)) else if (isLUKS2(cd->type))
r = -ETXTBSY; r = LUKS2_unmet_requirements(cd, &cd->u.luks2.hdr, 0, 0);
else if (!r)
r = dm_create_device(cd, name, cd->type, &dmd, 1); r = dm_create_device(cd, name, cd->type, &dmd, 1);
} }
out: out: