From 5f28c87fb6ba11c3fa7ffdc664011565efc92ef9 Mon Sep 17 00:00:00 2001 From: Alberto Planas Date: Mon, 14 Sep 2026 10:41:05 +0200 Subject: [PATCH] tpm2-util: log transient PCR changes in tpm2_policy_super_pcr() at debug level tpm2_policy_pcr() returns -EUCLEAN when the TPM's global PCR update counter moved while the policy was being submitted, not when the recorded PCR values disagree with the current state. Logging "Either the system has been tampered with or the provided policy is incorrect" at error level is therefore wrong, and it is noisy too: the condition is transient and callers are expected to restart the policy session. Downgrade both occurrences to debug and describe what actually happened, and document the contract at the declarations. Signed-off-by: Alberto Planas (cherry picked from commit 1fc5351945cb7f389849d46b1388803b7cbcdb04) --- src/shared/tpm2-util.c | 15 +++++---------- src/shared/tpm2-util.h | 3 +++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 2499976dc2..0ed0e879c8 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -9835,15 +9835,10 @@ int tpm2_policy_super_pcr( session, &pcr_selection, ¤t_policy_digest); - if (r == -EUCLEAN) { - _cleanup_free_ char *j = NULL; - - for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) - if (single_value_pcrs & (UINT32_C(1) << pcr)) - (void) strextendf_with_separator(&j, ", ", "%" PRIu32, pcr); - - return log_error_errno(r, "Combined value for PCR(s) %s encoded in policy does not match the current TPM state. Either the system has been tampered with or the provided policy is incorrect.", strna(j)); - } + /* -EUCLEAN means some PCR got extended while we were submitting the policy. That's + * transient, so only log at debug level and let the caller restart the session. */ + if (r == -EUCLEAN) + return log_debug_errno(r, "PCR state changed while submitting the combined PolicyPCR expression, session needs to be restarted."); if (r < 0) return log_error_errno(r, "Failed to submit PCR policy to TPM: %m"); @@ -9875,7 +9870,7 @@ int tpm2_policy_super_pcr( &pcr_selection, ¤t_policy_digest); if (r == -EUCLEAN) - return log_error_errno(r, "Value for PCR %" PRIu32 " encoded in policy does not match the current TPM state. Either the system has been tampered with or the provided policy is incorrect.", pcr); + return log_debug_errno(r, "PCR state changed while submitting the PolicyPCR expression for PCR %" PRIu32 ", session needs to be restarted.", pcr); if (r < 0) return log_error_errno(r, "Failed to submit PCR policy to TPM: %m"); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 475ac54014..1d0ed81138 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -340,6 +340,9 @@ int tpm2_make_policy_session(Tpm2Context *c, const Tpm2Handle *primary, const Tp int tpm2_policy_auth_value(Tpm2Context *c, const Tpm2Handle *session, TPM2B_DIGEST **ret_policy_digest); int tpm2_policy_nv_written(Tpm2Context *c, const Tpm2Handle *session, bool written_set, TPM2B_DIGEST **ret_policy_digest); int tpm2_policy_authorize_nv(Tpm2Context *c, const Tpm2Handle *session, const Tpm2Handle *nv_handle, TPM2B_DIGEST **ret_policy_digest); +/* Note: tpm2_policy_pcr() and tpm2_policy_super_pcr() return -EUCLEAN if the TPM's global PCR update counter + * moved while the policy was submitted, i.e. if something extended a PCR in the meantime. That's transient, + * callers are supposed to restart the policy session and try again. */ int tpm2_policy_pcr(Tpm2Context *c, const Tpm2Handle *session, const TPML_PCR_SELECTION *pcr_selection, TPM2B_DIGEST **ret_policy_digest); int tpm2_policy_or(Tpm2Context *c, const Tpm2Handle *session, const TPM2B_DIGEST *branches, size_t n_branches, TPM2B_DIGEST **ret_policy_digest); int tpm2_policy_super_pcr(Tpm2Context *c, const Tpm2Handle *session, const Tpm2PCRPrediction *prediction, uint16_t algorithm);