Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi/libstub: Use TPM event typedefs from the TCG PC Client spec

Our efi_tcg2_tagged_event is not defined in the EFI spec, but it is not
a local invention either: it was taken from the TCG PC Client spec,
where it is called TCG_PCClientTaggedEvent.

Note that this spec also contains some guidance on how to populate it,
which is not being followed closely at the moment; it claims that the
event size should cover the TCG_PCClientTaggedEvent and its payload
only, but it currently covers the preceding efi_tcg2_event too.

However, this directly contradicts the TCG EFI protocol specification,
which states very clearly that the event size should cover the entire
data structure, including the leading efi_tcg2_event_t struct.

So rename the struct and document its provenance, but retain the
existing logic to populate the size field.

Link: https://lore.kernel.org/all/20240308085754.476197-8-ardb+git@google.com
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+17 -15
+11 -9
drivers/firmware/efi/libstub/efi-stub-helper.c
··· 11 11 12 12 #include <linux/efi.h> 13 13 #include <linux/kernel.h> 14 + #include <linux/overflow.h> 14 15 #include <asm/efi.h> 15 16 #include <asm/setup.h> 16 17 ··· 220 219 }, 221 220 }; 222 221 222 + struct efistub_measured_event { 223 + efi_tcg2_event_t event_data; 224 + TCG_PCClientTaggedEvent tagged_event __packed; 225 + }; 226 + 223 227 static efi_status_t efi_measure_tagged_event(unsigned long load_addr, 224 228 unsigned long load_size, 225 229 enum efistub_event event) 226 230 { 231 + struct efistub_measured_event *evt; 232 + int size = struct_size(evt, tagged_event.tagged_event_data, 233 + events[event].event_data_len); 227 234 efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; 228 235 efi_tcg2_protocol_t *tcg2 = NULL; 229 236 efi_status_t status; 230 237 231 238 efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); 232 239 if (tcg2) { 233 - struct efi_measured_event { 234 - efi_tcg2_event_t event_data; 235 - efi_tcg2_tagged_event_t tagged_event; 236 - u8 tagged_event_data[]; 237 - } *evt; 238 - int size = sizeof(*evt) + events[event].event_data_len; 239 - 240 240 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, 241 241 (void **)&evt); 242 242 if (status != EFI_SUCCESS) ··· 251 249 .event_header.event_type = EV_EVENT_TAG, 252 250 }; 253 251 254 - evt->tagged_event = (struct efi_tcg2_tagged_event){ 252 + evt->tagged_event = (TCG_PCClientTaggedEvent){ 255 253 .tagged_event_id = events[event].event_id, 256 254 .tagged_event_data_size = events[event].event_data_len, 257 255 }; 258 256 259 - memcpy(evt->tagged_event_data, events[event].event_data, 257 + memcpy(evt->tagged_event.tagged_event_data, events[event].event_data, 260 258 events[event].event_data_len); 261 259 262 260 status = efi_call_proto(tcg2, hash_log_extend_event, 0,
+6 -6
drivers/firmware/efi/libstub/efistub.h
··· 843 843 /* u8[] event follows here */ 844 844 } __packed; 845 845 846 - struct efi_tcg2_tagged_event { 847 - u32 tagged_event_id; 848 - u32 tagged_event_data_size; 849 - /* u8 tagged event data follows here */ 850 - } __packed; 846 + /* from TCG PC Client Platform Firmware Profile Specification */ 847 + typedef struct tdTCG_PCClientTaggedEvent { 848 + u32 tagged_event_id; 849 + u32 tagged_event_data_size; 850 + u8 tagged_event_data[]; 851 + } TCG_PCClientTaggedEvent; 851 852 852 853 typedef struct efi_tcg2_event efi_tcg2_event_t; 853 - typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; 854 854 typedef union efi_tcg2_protocol efi_tcg2_protocol_t; 855 855 856 856 union efi_tcg2_protocol {