summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-07-26 18:32:21 +0200
committerLennart Poettering <lennart@poettering.net>2022-08-02 10:28:49 +0200
commit599fe002a135570406504998dbb7a42dabc963da (patch)
treec6807d3756d63630ff62b235acb23ddd999bebde /src
parent8d5e4d59f2d1c648e3cd249b55d0825c814f7ad0 (diff)
downloadsystemd-599fe002a135570406504998dbb7a42dabc963da.tar.gz
efi: tell userspace where the stub measured the kernel command line/credentials into
This is useful for userspace to know, so that policies can be put together safely, matching what the stub actually measured.
Diffstat (limited to 'src')
-rw-r--r--src/boot/efi/cpio.c24
-rw-r--r--src/boot/efi/cpio.h4
-rw-r--r--src/boot/efi/stub.c62
3 files changed, 61 insertions, 29 deletions
diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c
index 693b3816a4..0d41102d2d 100644
--- a/src/boot/efi/cpio.c
+++ b/src/boot/efi/cpio.c
@@ -315,7 +315,8 @@ EFI_STATUS pack_cpio(
UINTN n_tpm_pcr,
const char16_t *tpm_description,
void **ret_buffer,
- UINTN *ret_buffer_size) {
+ UINTN *ret_buffer_size,
+ bool *ret_measured) {
_cleanup_(file_closep) EFI_FILE *root = NULL, *extra_dir = NULL;
UINTN dirent_size = 0, buffer_size = 0, n_items = 0, n_allocated = 0;
@@ -324,6 +325,7 @@ EFI_STATUS pack_cpio(
_cleanup_(strv_freep) char16_t **items = NULL;
_cleanup_free_ void *buffer = NULL;
uint32_t inode = 1; /* inode counter, so that each item gets a new inode */
+ int measured = -1;
EFI_STATUS err;
assert(loaded_image);
@@ -432,24 +434,40 @@ EFI_STATUS pack_cpio(
return log_error_status_stall(err, L"Failed to pack cpio trailer: %r");
for (UINTN i = 0; i < n_tpm_pcr; i++) {
+ bool m;
+
+ if (tpm_pcr[i] == UINT32_MAX) /* Disabled */
+ continue;
+
err = tpm_log_event(
tpm_pcr[i],
POINTER_TO_PHYSICAL_ADDRESS(buffer),
buffer_size,
tpm_description,
- NULL);
- if (err != EFI_SUCCESS)
+ &m);
+ if (err != EFI_SUCCESS) {
log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr[i], tpm_description, err);
+ measured = false;
+ continue;
+ }
+
+ measured = measured < 0 ? m : (measured && m);
}
*ret_buffer = TAKE_PTR(buffer);
*ret_buffer_size = buffer_size;
+ if (ret_measured)
+ *ret_measured = measured;
+
return EFI_SUCCESS;
nothing:
*ret_buffer = NULL;
*ret_buffer_size = 0;
+ if (ret_measured)
+ *ret_measured = true;
+
return EFI_SUCCESS;
}
diff --git a/src/boot/efi/cpio.h b/src/boot/efi/cpio.h
index e3d206d7e8..672a751825 100644
--- a/src/boot/efi/cpio.h
+++ b/src/boot/efi/cpio.h
@@ -2,6 +2,7 @@
#pragma once
#include <efi.h>
+#include <stdbool.h>
#include <uchar.h>
EFI_STATUS pack_cpio(
@@ -15,4 +16,5 @@ EFI_STATUS pack_cpio(
UINTN n_tpm_pcr,
const char16_t *tpm_description,
void **ret_buffer,
- UINTN *ret_buffer_size);
+ UINTN *ret_buffer_size,
+ bool *ret_measured);
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index 7f43678cb1..3673d16345 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -178,7 +178,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
UINTN szs[_SECTION_MAX] = {};
char *cmdline = NULL;
_cleanup_free_ char *cmdline_owned = NULL;
+ int parameters_measured = -1;
EFI_STATUS err;
+ bool m;
InitializeLib(image, sys_table);
debug_hook(L"systemd-stub");
@@ -223,34 +225,40 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
* duplicates what we already did in the boot menu, if that was already used. However, since
* we want the boot menu to support an EFI binary, and want to this stub to be usable from
* any boot menu, let's measure things anyway. */
- (void) tpm_log_load_options(loaded_image->LoadOptions, NULL);
+ m = false;
+ (void) tpm_log_load_options(loaded_image->LoadOptions, &m);
+ parameters_measured = m;
}
export_variables(loaded_image);
- (void) pack_cpio(loaded_image,
- NULL,
- L".cred",
- ".extra/credentials",
- /* dir_mode= */ 0500,
- /* access_mode= */ 0400,
- /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
- /* n_tpm_pcr= */ 2,
- L"Credentials initrd",
- &credential_initrd,
- &credential_initrd_size);
-
- (void) pack_cpio(loaded_image,
- L"\\loader\\credentials",
- L".cred",
- ".extra/global_credentials",
- /* dir_mode= */ 0500,
- /* access_mode= */ 0400,
- /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
- /* n_tpm_pcr= */ 2,
- L"Global credentials initrd",
- &global_credential_initrd,
- &global_credential_initrd_size);
+ if (pack_cpio(loaded_image,
+ NULL,
+ L".cred",
+ ".extra/credentials",
+ /* dir_mode= */ 0500,
+ /* access_mode= */ 0400,
+ /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
+ /* n_tpm_pcr= */ 2,
+ L"Credentials initrd",
+ &credential_initrd,
+ &credential_initrd_size,
+ &m) == EFI_SUCCESS)
+ parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
+
+ if (pack_cpio(loaded_image,
+ L"\\loader\\credentials",
+ L".cred",
+ ".extra/global_credentials",
+ /* dir_mode= */ 0500,
+ /* access_mode= */ 0400,
+ /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
+ /* n_tpm_pcr= */ 2,
+ L"Global credentials initrd",
+ &global_credential_initrd,
+ &global_credential_initrd_size,
+ &m) == EFI_SUCCESS)
+ parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
(void) pack_cpio(loaded_image,
NULL,
@@ -262,7 +270,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
/* n_tpm_pcr= */ 1,
L"System extension initrd",
&sysext_initrd,
- &sysext_initrd_size);
+ &sysext_initrd_size,
+ NULL);
+
+ if (parameters_measured > 0)
+ (void) efivar_set_uint_string(LOADER_GUID, L"StubPcrKernelParameters", TPM_PCR_INDEX_KERNEL_PARAMETERS, 0);
linux_size = szs[SECTION_LINUX];
linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_LINUX];