mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
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.
This commit is contained in:
@@ -185,7 +185,7 @@
|
||||
|
||||
<row>
|
||||
<entry>Credentials (synthesized initrd from companion files)</entry>
|
||||
<entry>12 + 9</entry>
|
||||
<entry>9 + 12</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
@@ -239,6 +239,14 @@
|
||||
<citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> to view
|
||||
this data.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>StubPcrKernelParameters</varname></term>
|
||||
|
||||
<listitem><para>The PCR register index the kernel command line and credentials are measured into,
|
||||
formatted as decimal ASCII string (i.e. <literal>12</literal>). This variable is set if a measurement
|
||||
was successfully completed, and remains unset otherwise.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>Note that some of the variables above may also be set by the boot loader. The stub will only set
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
(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,
|
||||
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];
|
||||
|
||||
Reference in New Issue
Block a user