From be36f69c90d530ea12173eaa17be87685a7f799d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Feb 2026 14:28:02 +0100 Subject: [PATCH] pcrextend: allow access to the userspace event type field when measuring something It think we should move most measurements out of the individual tools requesting them and into the pcrextend service via Varlink, so that fewer components require access to the TPM. This only works however, if we can actually write full-blown event log records via this mechanism, and for that we still were missing access to the userspace event type we insert into the event log. Add that. --- src/pcrextend/pcrextend.c | 17 +++++++++++------ src/shared/varlink-io.systemd.PCRExtend.c | 17 ++++++++++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c index d887da924fc..c80bf376fdc 100644 --- a/src/pcrextend/pcrextend.c +++ b/src/pcrextend/pcrextend.c @@ -369,6 +369,7 @@ typedef struct MethodExtendParameters { const char *nvpcr; const char *text; struct iovec data; + Tpm2UserspaceEventType event_type; } MethodExtendParameters; static void method_extend_parameters_done(MethodExtendParameters *p) { @@ -377,17 +378,21 @@ static void method_extend_parameters_done(MethodExtendParameters *p) { iovec_done(&p->data); } +static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_tpm2_userspace_event_type, Tpm2UserspaceEventType, tpm2_userspace_event_type_from_string); + static int vl_method_extend(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { static const sd_json_dispatch_field dispatch_table[] = { - { "pcr", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(MethodExtendParameters, pcr), 0 }, - { "nvpcr", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MethodExtendParameters, nvpcr), 0 }, - { "text", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MethodExtendParameters, text), 0 }, - { "data", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MethodExtendParameters, data), 0 }, + { "pcr", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(MethodExtendParameters, pcr), 0 }, + { "nvpcr", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MethodExtendParameters, nvpcr), 0 }, + { "text", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MethodExtendParameters, text), 0 }, + { "data", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MethodExtendParameters, data), 0 }, + { "eventType", SD_JSON_VARIANT_STRING, json_dispatch_tpm2_userspace_event_type, offsetof(MethodExtendParameters, event_type), 0 }, {} }; _cleanup_(method_extend_parameters_done) MethodExtendParameters p = { .pcr = UINT_MAX, + .event_type = _TPM2_USERSPACE_EVENT_TYPE_INVALID, }; int r; @@ -424,11 +429,11 @@ static int vl_method_extend(sd_varlink *link, sd_json_variant *parameters, sd_va return sd_varlink_error_invalid_parameter_name(link, "text"); if (p.nvpcr) { - r = extend_nvpcr_now(p.nvpcr, extend_iovec->iov_base, extend_iovec->iov_len, _TPM2_USERSPACE_EVENT_TYPE_INVALID); + r = extend_nvpcr_now(p.nvpcr, extend_iovec->iov_base, extend_iovec->iov_len, p.event_type); if (r == -ENOENT) return sd_varlink_error(link, "io.systemd.PCRExtend.NoSuchNvPCR", NULL); } else - r = extend_pcr_now(p.pcr, extend_iovec->iov_base, extend_iovec->iov_len, _TPM2_USERSPACE_EVENT_TYPE_INVALID); + r = extend_pcr_now(p.pcr, extend_iovec->iov_base, extend_iovec->iov_len, p.event_type); if (r < 0) return r; diff --git a/src/shared/varlink-io.systemd.PCRExtend.c b/src/shared/varlink-io.systemd.PCRExtend.c index 87783f1ee9f..9179668d7dc 100644 --- a/src/shared/varlink-io.systemd.PCRExtend.c +++ b/src/shared/varlink-io.systemd.PCRExtend.c @@ -2,6 +2,17 @@ #include "varlink-io.systemd.PCRExtend.h" +static SD_VARLINK_DEFINE_ENUM_TYPE( + EventType, + SD_VARLINK_DEFINE_ENUM_VALUE(phase), + SD_VARLINK_DEFINE_ENUM_VALUE(filesystem), + SD_VARLINK_DEFINE_ENUM_VALUE(volume_key), + SD_VARLINK_DEFINE_ENUM_VALUE(machine_id), + SD_VARLINK_DEFINE_ENUM_VALUE(product_id), + SD_VARLINK_DEFINE_ENUM_VALUE(keyslot), + SD_VARLINK_DEFINE_ENUM_VALUE(nvpcr_init), + SD_VARLINK_DEFINE_ENUM_VALUE(nvpcr_separator)); + static SD_VARLINK_DEFINE_METHOD( Extend, SD_VARLINK_FIELD_COMMENT("PCR number to extend, in range of 0…23. Either this or 'nvpcr' must be specified, not both, not neither."), @@ -11,7 +22,9 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_FIELD_COMMENT("Text string to measure. (Specify either this, or the 'data' field below, not both)"), SD_VARLINK_DEFINE_INPUT(text, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Binary data to measure, encoded in Base64. (Specify either this, or the 'text' field above, not both)"), - SD_VARLINK_DEFINE_INPUT(data, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(data, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Event type to include in the (userspace) event log). This is optional, and mostly for debugging."), + SD_VARLINK_DEFINE_INPUT_BY_TYPE(eventType, EventType, SD_VARLINK_NULLABLE)); static SD_VARLINK_DEFINE_ERROR(NoSuchNvPCR); @@ -21,4 +34,6 @@ SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_INTERFACE_COMMENT("TPM PCR Extension APIs"), SD_VARLINK_SYMBOL_COMMENT("Measure some text or binary data into a PCR"), &vl_method_Extend, + SD_VARLINK_SYMBOL_COMMENT("Event type to store in event log"), + &vl_type_EventType, &vl_error_NoSuchNvPCR); -- 2.47.3