cryptsetup: handle more gracefully if "keyslots" LUKS2 JSON header field is invalid

The field is not owned by us (even though is in our JSON objects) but by
the LUKS2 spec. Hence let's handle this a bit more gracefully: let's not
get confused by it, just warn and skip over it.

Fixes: #20847
This commit is contained in:
Lennart Poettering
2021-09-28 16:47:08 +02:00
parent 5918a93355
commit 1641c2b112
4 changed files with 42 additions and 17 deletions
+12 -5
View File
@@ -111,6 +111,7 @@ int find_pkcs11_auto_data(
for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
JsonVariant *w;
int ks;
r = cryptsetup_get_token_as_json(cd, token, "systemd-pkcs11", &v);
if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE))
@@ -118,10 +119,21 @@ int find_pkcs11_auto_data(
if (r < 0)
return log_error_errno(r, "Failed to read JSON token data off disk: %m");
ks = cryptsetup_get_keyslot_from_token(v);
if (ks < 0) {
/* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by
* us, but by the LUKS2 spec */
log_warning_errno(ks, "Failed to extract keyslot index from PKCS#11 JSON data token %i, skipping: %m", token);
continue;
}
if (uri)
return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
"Multiple PKCS#11 tokens enrolled, cannot automatically determine token.");
assert(keyslot < 0);
keyslot = ks;
w = json_variant_by_key(v, "pkcs11-uri");
if (!w || !json_variant_is_string(w))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@@ -145,11 +157,6 @@ int find_pkcs11_auto_data(
r = unbase64mem(json_variant_string(w), SIZE_MAX, &key, &key_size);
if (r < 0)
return log_error_errno(r, "Failed to decode base64 encoded key.");
assert(keyslot < 0);
keyslot = cryptsetup_get_keyslot_from_token(v);
if (keyslot < 0)
return log_error_errno(keyslot, "Failed to extract keyslot index from PKCS#11 JSON data: %m");
}
if (!uri)