From: Lennart Poettering Date: Wed, 21 Feb 2024 13:43:42 +0000 (+0100) Subject: pcrlock: handle measurement logs where hash algs in header are announced in different... X-Git-Tag: v256-rc1~777^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F31429%2Fhead;p=thirdparty%2Fsystemd.git pcrlock: handle measurement logs where hash algs in header are announced in different order than in records Apparently on HyperV the measurement logs announce the hash algs in a different order in the header than the records have them. Let's handle this gracefully --- diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index e70c44c675c..1fb9d692a27 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -936,23 +936,30 @@ static int event_log_load_firmware(EventLog *el) { assert(event->digests.count == n_algorithms); for (size_t i = 0; i < n_algorithms; i++, ha = ha_next) { - ha_next = (const uint8_t*) ha + offsetof(TPMT_HA, digest) + algorithms[i].digestSize; - /* The TPMT_HA is not aligned in the record, hence read the hashAlg field via an unaligned read */ assert_cc(__builtin_types_compatible_p(uint16_t, typeof(TPMI_ALG_HASH))); uint16_t hash_alg = unaligned_read_ne16((const uint8_t*) ha + offsetof(TPMT_HA, hashAlg)); - if (hash_alg != algorithms[i].algorithmId) - return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Hash algorithms in event log record don't match log."); + /* On some systems (some HyperV?) the order of hash algorithms announced in the + * header does not match the order in the records. Let's hence search for the right + * mapping */ + size_t j; + for (j = 0; j < n_algorithms; j++) + if (hash_alg == algorithms[j].algorithmId) + break; + if (j >= n_algorithms) + return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Hash algorithms in event log record not among those advertised by log header."); + + ha_next = (const uint8_t*) ha + offsetof(TPMT_HA, digest) + algorithms[j].digestSize; - if (!tpm2_hash_alg_to_string(algorithms[i].algorithmId)) + if (!tpm2_hash_alg_to_string(hash_alg)) continue; r = event_log_record_add_bank( record, - algorithms[i].algorithmId, + hash_alg, (const uint8_t*) ha + offsetof(TPMT_HA, digest), - algorithms[i].digestSize, + algorithms[j].digestSize, /* ret= */ NULL); if (r < 0) return log_error_errno(r, "Failed to add bank to event log record: %m");