diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 8c64daa3c8..bc52a18c6a 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -39,7 +39,7 @@ static int search_policy_hash( sd_json_variant *w; r = cryptsetup_get_token_as_json(cd, token, "systemd-tpm2", &v); - if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + if (ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r)) continue; if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index 9211efef6f..6c3ee9b039 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -802,7 +802,7 @@ static int check_for_homed(struct crypt_device *cd) { for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) { r = cryptsetup_get_token_as_json(cd, token, "systemd-homed", NULL); - if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + if (ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r)) continue; if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); diff --git a/src/cryptsetup/cryptsetup-pkcs11.c b/src/cryptsetup/cryptsetup-pkcs11.c index b8534b15ef..df06b0c61d 100644 --- a/src/cryptsetup/cryptsetup-pkcs11.c +++ b/src/cryptsetup/cryptsetup-pkcs11.c @@ -110,7 +110,7 @@ int find_pkcs11_auto_data( int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-pkcs11", &v); - if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + if (ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r)) continue; if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c index 20876cc71b..9c73463deb 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c @@ -87,6 +87,8 @@ _public_ int cryptsetup_token_open_pin( params = *(systemd_tpm2_plugin_params *)usrptr; r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL); + if (r == -ENOMEM) + return r; if (r < 0) { /* Remap to -EPERM so libcryptsetup keeps iterating past a broken token. */ (void) crypt_log_debug_errno(cd, r, "Token %d: failed to parse JSON data: %m", token); diff --git a/src/shared/cryptsetup-fido2.c b/src/shared/cryptsetup-fido2.c index 8655acba3e..ffc36c697a 100644 --- a/src/shared/cryptsetup-fido2.c +++ b/src/shared/cryptsetup-fido2.c @@ -167,7 +167,7 @@ int acquire_fido2_key_auto( int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-fido2", &v); - if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + if (ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r)) continue; if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c index 7a0b9a236d..cd7a1506a1 100644 --- a/src/shared/cryptsetup-tpm2.c +++ b/src/shared/cryptsetup-tpm2.c @@ -313,7 +313,7 @@ int find_tpm2_auto_data( CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free); r = cryptsetup_get_token_as_json(cd, token, "systemd-tpm2", &v); - if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + if (ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r)) continue; if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index 35a59721f8..531d2fcbc0 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -164,6 +164,7 @@ int cryptsetup_get_token_as_json( * -EINVAL → token index out of range or "type" field missing * -ENOENT → token doesn't exist * -EMEDIUMTYPE → "verify_type" specified and doesn't match token's type + * -EUCLEAN → token JSON data cannot be parsed */ r = sym_crypt_token_json_get(cd, idx, &text); @@ -172,7 +173,7 @@ int cryptsetup_get_token_as_json( r = sd_json_parse(text, 0, &v, NULL, NULL); if (r < 0) - return r; + return r == -ENOMEM ? r : -EUCLEAN; /* Report unparseable token data in a single way for callers to skip */ if (verify_type) { sd_json_variant *w; diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h index 6e9c95aa9e..1c1e122e75 100644 --- a/src/shared/cryptsetup-util.h +++ b/src/shared/cryptsetup-util.h @@ -91,6 +91,9 @@ void cryptsetup_enable_logging(struct crypt_device *cd); int cryptsetup_set_minimal_pbkdf(struct crypt_device *cd); int cryptsetup_get_token_as_json(struct crypt_device *cd, int idx, const char *verify_type, sd_json_variant **ret); +/* Errors cryptsetup_get_token_as_json() returns for a token that is absent, of a different type, or + * unparseable, and callers should keep iterating other tokens. */ +#define ERRNO_IS_NEG_CRYPTSETUP_TOKEN_SKIP(r) IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE, -EUCLEAN) int cryptsetup_add_token_json(struct crypt_device *cd, sd_json_variant *v); int cryptsetup_get_volume_key_prefix(struct crypt_device *cd, const char *volume_name, char **ret); int cryptsetup_get_volume_key_id(struct crypt_device *cd, const char *volume_name, const void *volume_key,