Skip to content

Commit 70ef654

Browse files
committed
Merge tag 'efi-next-for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel: - Measure initrd and command line using the CC protocol if the ordinary TCG2 protocol is not implemented, typically on TDX confidential VMs - Avoid creating mappings that are both writable and executable while running in the EFI boot services. This is a prerequisite for getting the x86 shim loader signed by MicroSoft again, which allows the distros to install on x86 PCs that ship with EFI secure boot enabled. - API update for struct platform_driver::remove() * tag 'efi-next-for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: virt: efi_secret: Convert to platform remove callback returning void x86/efistub: Remap kernel text read-only before dropping NX attribute efi/libstub: Add get_event_log() support for CC platforms efi/libstub: Measure into CC protocol if TCG2 protocol is absent efi/libstub: Add Confidential Computing (CC) measurement typedefs efi/tpm: Use symbolic GUID name from spec for final events table efi/libstub: Use TPM event typedefs from the TCG PC Client spec
2 parents 27b984a + 021bc4b commit 70ef654

File tree

11 files changed

+234
-72
lines changed

11 files changed

+234
-72
lines changed

arch/x86/boot/compressed/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ LDFLAGS_vmlinux += -T
8484
hostprogs := mkpiggy
8585
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
8686

87-
sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
87+
sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__start_rodata\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
8888

8989
quiet_cmd_voffset = VOFFSET $@
9090
cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@

arch/x86/boot/compressed/misc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ static size_t parse_elf(void *output)
344344
return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
345345
}
346346

347+
const unsigned long kernel_text_size = VO___start_rodata - VO__text;
347348
const unsigned long kernel_total_size = VO__end - VO__text;
348349

349350
static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);

arch/x86/include/asm/boot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181

8282
#ifndef __ASSEMBLY__
8383
extern unsigned int output_len;
84+
extern const unsigned long kernel_text_size;
8485
extern const unsigned long kernel_total_size;
8586

8687
unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,

drivers/firmware/efi/efi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,8 @@ static const efi_config_table_type_t common_tables[] __initconst = {
597597
{EFI_MEMORY_ATTRIBUTES_TABLE_GUID, &efi_mem_attr_table, "MEMATTR" },
598598
{LINUX_EFI_RANDOM_SEED_TABLE_GUID, &efi_rng_seed, "RNG" },
599599
{LINUX_EFI_TPM_EVENT_LOG_GUID, &efi.tpm_log, "TPMEventLog" },
600-
{LINUX_EFI_TPM_FINAL_LOG_GUID, &efi.tpm_final_log, "TPMFinalLog" },
600+
{EFI_TCG2_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "TPMFinalLog" },
601+
{EFI_CC_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "CCFinalLog" },
601602
{LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" },
602603
{LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD" },
603604
{EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" },

drivers/firmware/efi/libstub/efi-stub-helper.c

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/efi.h>
1313
#include <linux/kernel.h>
14+
#include <linux/overflow.h>
1415
#include <asm/efi.h>
1516
#include <asm/setup.h>
1617

@@ -201,7 +202,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
201202
*load_options_size = load_option_unpacked.optional_data_size;
202203
}
203204

204-
enum efistub_event {
205+
enum efistub_event_type {
205206
EFISTUB_EVT_INITRD,
206207
EFISTUB_EVT_LOAD_OPTIONS,
207208
EFISTUB_EVT_COUNT,
@@ -227,54 +228,95 @@ static const struct {
227228
},
228229
};
229230

231+
static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t));
232+
233+
union efistub_event {
234+
efi_tcg2_event_t tcg2_data;
235+
efi_cc_event_t cc_data;
236+
};
237+
238+
struct efistub_measured_event {
239+
union efistub_event event_data;
240+
TCG_PCClientTaggedEvent tagged_event __packed;
241+
};
242+
230243
static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
231244
unsigned long load_size,
232-
enum efistub_event event)
245+
enum efistub_event_type event)
233246
{
247+
union {
248+
efi_status_t
249+
(__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t,
250+
u64, const union efistub_event *);
251+
struct { u32 hash_log_extend_event; } mixed_mode;
252+
} method;
253+
struct efistub_measured_event *evt;
254+
int size = struct_size(evt, tagged_event.tagged_event_data,
255+
events[event].event_data_len);
234256
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
235257
efi_tcg2_protocol_t *tcg2 = NULL;
258+
union efistub_event ev;
236259
efi_status_t status;
260+
void *protocol;
237261

238262
efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
239263
if (tcg2) {
240-
struct efi_measured_event {
241-
efi_tcg2_event_t event_data;
242-
efi_tcg2_tagged_event_t tagged_event;
243-
u8 tagged_event_data[];
244-
} *evt;
245-
int size = sizeof(*evt) + events[event].event_data_len;
246-
247-
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
248-
(void **)&evt);
249-
if (status != EFI_SUCCESS)
250-
goto fail;
251-
252-
evt->event_data = (struct efi_tcg2_event){
264+
ev.tcg2_data = (struct efi_tcg2_event){
253265
.event_size = size,
254-
.event_header.header_size = sizeof(evt->event_data.event_header),
266+
.event_header.header_size = sizeof(ev.tcg2_data.event_header),
255267
.event_header.header_version = EFI_TCG2_EVENT_HEADER_VERSION,
256268
.event_header.pcr_index = events[event].pcr_index,
257269
.event_header.event_type = EV_EVENT_TAG,
258270
};
271+
protocol = tcg2;
272+
method.hash_log_extend_event =
273+
(void *)efi_table_attr(tcg2, hash_log_extend_event);
274+
} else {
275+
efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
276+
efi_cc_protocol_t *cc = NULL;
259277

260-
evt->tagged_event = (struct efi_tcg2_tagged_event){
261-
.tagged_event_id = events[event].event_id,
262-
.tagged_event_data_size = events[event].event_data_len,
263-
};
264-
265-
memcpy(evt->tagged_event_data, events[event].event_data,
266-
events[event].event_data_len);
278+
efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
279+
if (!cc)
280+
return EFI_UNSUPPORTED;
267281

268-
status = efi_call_proto(tcg2, hash_log_extend_event, 0,
269-
load_addr, load_size, &evt->event_data);
270-
efi_bs_call(free_pool, evt);
282+
ev.cc_data = (struct efi_cc_event){
283+
.event_size = size,
284+
.event_header.header_size = sizeof(ev.cc_data.event_header),
285+
.event_header.header_version = EFI_CC_EVENT_HEADER_VERSION,
286+
.event_header.event_type = EV_EVENT_TAG,
287+
};
271288

289+
status = efi_call_proto(cc, map_pcr_to_mr_index,
290+
events[event].pcr_index,
291+
&ev.cc_data.event_header.mr_index);
272292
if (status != EFI_SUCCESS)
273293
goto fail;
274-
return EFI_SUCCESS;
294+
295+
protocol = cc;
296+
method.hash_log_extend_event =
297+
(void *)efi_table_attr(cc, hash_log_extend_event);
275298
}
276299

277-
return EFI_UNSUPPORTED;
300+
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt);
301+
if (status != EFI_SUCCESS)
302+
goto fail;
303+
304+
*evt = (struct efistub_measured_event) {
305+
.event_data = ev,
306+
.tagged_event.tagged_event_id = events[event].event_id,
307+
.tagged_event.tagged_event_data_size = events[event].event_data_len,
308+
};
309+
310+
memcpy(evt->tagged_event.tagged_event_data, events[event].event_data,
311+
events[event].event_data_len);
312+
313+
status = efi_fn_call(&method, hash_log_extend_event, protocol, 0,
314+
load_addr, load_size, &evt->event_data);
315+
efi_bs_call(free_pool, evt);
316+
317+
if (status == EFI_SUCCESS)
318+
return EFI_SUCCESS;
319+
278320
fail:
279321
efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
280322
return status;

drivers/firmware/efi/libstub/efi-stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ efi_status_t efi_stub_common(efi_handle_t handle,
167167

168168
si = setup_graphics();
169169

170-
efi_retrieve_tpm2_eventlog();
170+
efi_retrieve_eventlog();
171171

172172
/* Ask the firmware to clear memory on unclean shutdown */
173173
efi_enable_reset_attack_mitigation();

drivers/firmware/efi/libstub/efistub.h

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -843,14 +843,14 @@ struct efi_tcg2_event {
843843
/* u8[] event follows here */
844844
} __packed;
845845

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;
851852

852853
typedef struct efi_tcg2_event efi_tcg2_event_t;
853-
typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t;
854854
typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
855855

856856
union efi_tcg2_protocol {
@@ -882,6 +882,87 @@ union efi_tcg2_protocol {
882882
} mixed_mode;
883883
};
884884

885+
typedef struct {
886+
u8 major;
887+
u8 minor;
888+
} efi_cc_version_t;
889+
890+
typedef struct {
891+
u8 type;
892+
u8 sub_type;
893+
} efi_cc_type_t;
894+
895+
/* EFI CC type/subtype defines */
896+
#define EFI_CC_TYPE_NONE 0
897+
#define EFI_CC_TYPE_AMD_SEV 1
898+
#define EFI_CC_TYPE_INTEL_TDX 2
899+
900+
typedef u32 efi_cc_mr_index_t;
901+
902+
struct efi_cc_event {
903+
u32 event_size;
904+
struct {
905+
u32 header_size;
906+
u16 header_version;
907+
u32 mr_index;
908+
u32 event_type;
909+
} __packed event_header;
910+
/* u8[] event follows here */
911+
} __packed;
912+
913+
typedef struct efi_cc_event efi_cc_event_t;
914+
915+
typedef u32 efi_cc_event_log_bitmap_t;
916+
typedef u32 efi_cc_event_log_format_t;
917+
typedef u32 efi_cc_event_algorithm_bitmap_t;
918+
919+
typedef struct {
920+
u8 size;
921+
efi_cc_version_t structure_version;
922+
efi_cc_version_t protocol_version;
923+
efi_cc_event_algorithm_bitmap_t hash_algorithm_bitmap;
924+
efi_cc_event_log_bitmap_t supported_event_logs;
925+
efi_cc_type_t cc_type;
926+
} efi_cc_boot_service_cap_t;
927+
928+
#define EFI_CC_EVENT_HEADER_VERSION 1
929+
930+
#define EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004
931+
932+
#define EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002
933+
934+
typedef union efi_cc_protocol efi_cc_protocol_t;
935+
936+
union efi_cc_protocol {
937+
struct {
938+
efi_status_t
939+
(__efiapi *get_capability)(efi_cc_protocol_t *,
940+
efi_cc_boot_service_cap_t *);
941+
942+
efi_status_t
943+
(__efiapi *get_event_log)(efi_cc_protocol_t *,
944+
efi_cc_event_log_format_t,
945+
efi_physical_addr_t *,
946+
efi_physical_addr_t *,
947+
efi_bool_t *);
948+
949+
efi_status_t
950+
(__efiapi *hash_log_extend_event)(efi_cc_protocol_t *, u64,
951+
efi_physical_addr_t, u64,
952+
const efi_cc_event_t *);
953+
954+
efi_status_t
955+
(__efiapi *map_pcr_to_mr_index)(efi_cc_protocol_t *, u32,
956+
efi_cc_mr_index_t *);
957+
};
958+
struct {
959+
u32 get_capability;
960+
u32 get_event_log;
961+
u32 hash_log_extend_event;
962+
u32 map_pcr_to_mr_index;
963+
} mixed_mode;
964+
};
965+
885966
struct riscv_efi_boot_protocol {
886967
u64 revision;
887968

@@ -1061,7 +1142,7 @@ static inline void
10611142
efi_enable_reset_attack_mitigation(void) { }
10621143
#endif
10631144

1064-
void efi_retrieve_tpm2_eventlog(void);
1145+
void efi_retrieve_eventlog(void);
10651146

10661147
struct screen_info *alloc_screen_info(void);
10671148
struct screen_info *__alloc_screen_info(void);

0 commit comments

Comments
 (0)