Skip to content

Commit

Permalink
efi/libstub: measure loaded initrd info into the TPM
Browse files Browse the repository at this point in the history
In an effort to ensure the initrd observed and used by the OS is
the same one that was meant to be loaded, which is difficult to
guarantee otherwise, let's measure the initrd if the EFI stub and
specifically the newly introduced LOAD_FILE2 protocol was used.

Modify the initrd loading sequence so that the contents of the initrd
are measured into PCR9.  Note that the patch is currently using
EV_EVENT_TAG to create the eventlog entry instead of EV_IPL.  According
to the TCP PC Client specification this is used for PCRs defined for OS
and application usage.

Co-developed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Link: https://lore.kernel.org/r/20211119114745.1560453-5-ilias.apalodimas@linaro.org
[ardb: add braces to initializer of tagged_event_data]
Link: https://github.com/ClangBuiltLinux/linux/issues/1547
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
  • Loading branch information
Ilias Apalodimas authored and Ard Biesheuvel committed Jan 6, 2022
1 parent 20287d5 commit f046fff
Showing 1 changed file with 58 additions and 14 deletions.
72 changes: 58 additions & 14 deletions drivers/firmware/efi/libstub/efi-stub-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,47 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
load_addr, load_size);
}

static const struct {
efi_tcg2_event_t event_data;
efi_tcg2_tagged_event_t tagged_event;
u8 tagged_event_data[];
} initrd_tcg2_event = {
{
sizeof(initrd_tcg2_event) + sizeof("Linux initrd"),
{
sizeof(initrd_tcg2_event.event_data.event_header),
EFI_TCG2_EVENT_HEADER_VERSION,
9,
EV_EVENT_TAG,
},
},
{
INITRD_EVENT_TAG_ID,
sizeof("Linux initrd"),
},
{ "Linux initrd" },
};

static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size)
{
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
efi_tcg2_protocol_t *tcg2 = NULL;
efi_status_t status;

efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
if (tcg2) {
status = efi_call_proto(tcg2, hash_log_extend_event,
0, load_addr, load_size,
&initrd_tcg2_event.event_data);
if (status != EFI_SUCCESS)
efi_warn("Failed to measure initrd data: 0x%lx\n",
status);
else
efi_info("Measured initrd data into PCR %d\n",
initrd_tcg2_event.event_data.event_header.pcr_index);
}
}

/**
* efi_load_initrd() - Load initial RAM disk
* @image: EFI loaded image protocol
Expand All @@ -645,22 +686,25 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,

if (efi_noinitrd) {
*load_addr = *load_size = 0;
return EFI_SUCCESS;
status = EFI_SUCCESS;
} else {
status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
if (status == EFI_SUCCESS) {
efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
if (*load_size > 0)
efi_measure_initrd(*load_addr, *load_size);
} else if (status == EFI_NOT_FOUND) {
status = efi_load_initrd_cmdline(image, load_addr, load_size,
soft_limit, hard_limit);
if (status == EFI_SUCCESS && *load_size > 0)
efi_info("Loaded initrd from command line option\n");
}
if (status != EFI_SUCCESS) {
efi_err("Failed to load initrd: 0x%lx\n", status);
*load_addr = *load_size = 0;
}
}

status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
if (status == EFI_SUCCESS) {
efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
} else if (status == EFI_NOT_FOUND) {
status = efi_load_initrd_cmdline(image, load_addr, load_size,
soft_limit, hard_limit);
if (status == EFI_SUCCESS && *load_size > 0)
efi_info("Loaded initrd from command line option\n");
}
if (status != EFI_SUCCESS) {
efi_err("Failed to load initrd: 0x%lx\n", status);
*load_addr = *load_size = 0;
}
return status;
}

Expand Down

0 comments on commit f046fff

Please sign in to comment.