diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/boot/bootctl.c | 1 | ||||
-rw-r--r-- | src/boot/efi/boot.c | 4 | ||||
-rw-r--r-- | src/boot/efi/meson.build | 8 | ||||
-rw-r--r-- | src/boot/efi/part-discovery.c (renamed from src/boot/efi/xbootldr.c) | 20 | ||||
-rw-r--r-- | src/boot/efi/part-discovery.h | 11 | ||||
-rw-r--r-- | src/boot/efi/stub.c | 13 | ||||
-rw-r--r-- | src/boot/efi/xbootldr.h | 9 | ||||
-rw-r--r-- | src/fundamental/efivars-fundamental.h | 1 | ||||
-rw-r--r-- | units/systemd-boot-system-token.service | 3 |
10 files changed, 45 insertions, 27 deletions
@@ -146,8 +146,6 @@ Features: * bootctl: warn if ESP is mounted world-readable (and in particular the seed). -* sd-stub: call process_random_seed() the same way sd-boot does. - * maybe: systemd-loop-generator that sets up loopback devices if requested via kernel cmdline. usecase: include encrypted/verity root fs in UKI. diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 1e862018d4..0df456827c 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -1808,6 +1808,7 @@ static int verb_status(int argc, char *argv[], void *userdata) { { EFI_STUB_FEATURE_PICK_UP_CREDENTIALS, "Picks up credentials from boot partition" }, { EFI_STUB_FEATURE_PICK_UP_SYSEXTS, "Picks up system extension images from boot partition" }, { EFI_STUB_FEATURE_THREE_PCRS, "Measures kernel+command line+sysexts" }, + { EFI_STUB_FEATURE_RANDOM_SEED, "Support for passing random seed to OS" }, }; _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL; sd_id128_t loader_part_uuid = SD_ID128_NULL; diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index caa2a69a6f..85e936b866 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -15,6 +15,7 @@ #include "initrd.h" #include "linux.h" #include "measure.h" +#include "part-discovery.h" #include "pe.h" #include "vmm.h" #include "random-seed.h" @@ -22,7 +23,6 @@ #include "shim.h" #include "ticks.h" #include "util.h" -#include "xbootldr.h" #ifndef GNU_EFI_USE_MS_ABI /* We do not use uefi_call_wrapper() in systemd-boot. As such, we rely on the @@ -2241,7 +2241,7 @@ static void config_load_xbootldr( assert(config); assert(device); - err = xbootldr_open(device, &new_device, &root_dir); + err = partition_open(XBOOTLDR_GUID, device, &new_device, &root_dir); if (err != EFI_SUCCESS) return; diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 0de43993a4..2a7e457df3 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -360,6 +360,7 @@ efi_headers = files( 'linux.h', 'measure.h', 'missing_efi.h', + 'part-discovery.h', 'pe.h', 'random-seed.h', 'secure-boot.h', @@ -367,7 +368,6 @@ efi_headers = files( 'splash.h', 'ticks.h', 'util.h', - 'xbootldr.h', ) common_sources = files( @@ -379,7 +379,9 @@ common_sources = files( 'graphics.c', 'initrd.c', 'measure.c', + 'part-discovery.c', 'pe.c', + 'random-seed.c', 'secure-boot.c', 'ticks.c', 'util.c', @@ -388,10 +390,8 @@ common_sources = files( systemd_boot_sources = files( 'boot.c', 'drivers.c', - 'random-seed.c', - 'vmm.c', 'shim.c', - 'xbootldr.c', + 'vmm.c', ) stub_sources = files( diff --git a/src/boot/efi/xbootldr.c b/src/boot/efi/part-discovery.c index e5b9ca7268..de6d6112a1 100644 --- a/src/boot/efi/xbootldr.c +++ b/src/boot/efi/part-discovery.c @@ -4,8 +4,8 @@ #include <efigpt.h> #include <efilib.h> +#include "part-discovery.h" #include "util.h" -#include "xbootldr.h" union GptHeaderBuffer { EFI_PARTITION_TABLE_HEADER gpt_header; @@ -81,6 +81,7 @@ static bool verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_exp } static EFI_STATUS try_gpt( + const EFI_GUID *type, EFI_BLOCK_IO_PROTOCOL *block_io, EFI_LBA lba, EFI_LBA *ret_backup_lba, /* May be changed even on error! */ @@ -133,7 +134,7 @@ static EFI_STATUS try_gpt( EFI_PARTITION_ENTRY *entry = (EFI_PARTITION_ENTRY *) ((uint8_t *) entries + gpt.gpt_header.SizeOfPartitionEntry * i); - if (memcmp(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0) + if (memcmp(&entry->PartitionTypeGUID, type, sizeof(entry->PartitionTypeGUID)) != 0) continue; if (entry->EndingLBA < entry->StartingLBA) /* Bogus? */ @@ -165,7 +166,7 @@ static EFI_STATUS try_gpt( return EFI_NOT_FOUND; } -static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_path) { +static EFI_STATUS find_device(const EFI_GUID *type, EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_path) { EFI_STATUS err; assert(device); @@ -231,8 +232,7 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p continue; HARDDRIVE_DEVICE_PATH hd; - err = try_gpt( - block_io, lba, + err = try_gpt(type, block_io, lba, nr == 0 ? &backup_lba : NULL, /* Only get backup LBA location from first GPT header. */ &hd); if (err != EFI_SUCCESS) { @@ -252,17 +252,18 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p return EFI_NOT_FOUND; } -EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir) { +EFI_STATUS partition_open(const EFI_GUID *type, EFI_HANDLE *device, EFI_HANDLE *ret_device, + EFI_FILE **ret_root_dir) { _cleanup_free_ EFI_DEVICE_PATH *partition_path = NULL; EFI_HANDLE new_device; EFI_FILE *root_dir; EFI_STATUS err; + assert(type); assert(device); - assert(ret_device); assert(ret_root_dir); - err = find_device(device, &partition_path); + err = find_device(type, device, &partition_path); if (err != EFI_SUCCESS) return err; @@ -275,7 +276,8 @@ EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE ** if (err != EFI_SUCCESS) return err; - *ret_device = new_device; + if (ret_device) + *ret_device = new_device; *ret_root_dir = root_dir; return EFI_SUCCESS; } diff --git a/src/boot/efi/part-discovery.h b/src/boot/efi/part-discovery.h new file mode 100644 index 0000000000..5cc17f6b3b --- /dev/null +++ b/src/boot/efi/part-discovery.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <efi.h> + +#define XBOOTLDR_GUID \ + &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } } +#define ESP_GUID \ + &(const EFI_GUID) { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } } + +EFI_STATUS partition_open(const EFI_GUID *type, EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir); diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index a842c5c679..6ece3cf733 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -9,7 +9,9 @@ #include "graphics.h" #include "linux.h" #include "measure.h" +#include "part-discovery.h" #include "pe.h" +#include "random-seed.h" #include "secure-boot.h" #include "splash.h" #include "tpm-pcr.h" @@ -84,6 +86,7 @@ static void export_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) { EFI_STUB_FEATURE_PICK_UP_CREDENTIALS | /* We pick up credentials from the boot partition */ EFI_STUB_FEATURE_PICK_UP_SYSEXTS | /* We pick up system extensions from the boot partition */ EFI_STUB_FEATURE_THREE_PCRS | /* We can measure kernel image, parameters and sysext */ + EFI_STUB_FEATURE_RANDOM_SEED | /* We pass a random seed to the kernel */ 0; char16_t uuid[37]; @@ -142,6 +145,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { _cleanup_free_ char *cmdline_owned = NULL; int sections_measured = -1, parameters_measured = -1; bool sysext_measured = false, m; + uint64_t loader_features = 0; EFI_STATUS err; InitializeLib(image, sys_table); @@ -159,6 +163,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { if (err != EFI_SUCCESS) return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err); + if (efivar_get_uint64_le(LOADER_GUID, L"LoaderFeatures", &loader_features) != EFI_SUCCESS || + !FLAGS_SET(loader_features, EFI_LOADER_FEATURE_RANDOM_SEED)) { + _cleanup_(file_closep) EFI_FILE *esp_dir = NULL; + + err = partition_open(ESP_GUID, loaded_image->DeviceHandle, NULL, &esp_dir); + if (err == EFI_SUCCESS) /* Non-fatal on failure, so that we still boot without it. */ + (void) process_random_seed(esp_dir); + } + err = pe_memory_locate_sections(loaded_image->ImageBase, unified_sections, addrs, szs); if (err != EFI_SUCCESS || szs[UNIFIED_SECTION_LINUX] == 0) { if (err == EFI_SUCCESS) diff --git a/src/boot/efi/xbootldr.h b/src/boot/efi/xbootldr.h deleted file mode 100644 index 205ce71edf..0000000000 --- a/src/boot/efi/xbootldr.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include <efi.h> - -#define XBOOTLDR_GUID \ - &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } } - -EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir); diff --git a/src/fundamental/efivars-fundamental.h b/src/fundamental/efivars-fundamental.h index fe34e6c714..cf785f8b7d 100644 --- a/src/fundamental/efivars-fundamental.h +++ b/src/fundamental/efivars-fundamental.h @@ -22,6 +22,7 @@ #define EFI_STUB_FEATURE_PICK_UP_CREDENTIALS (UINT64_C(1) << 1) #define EFI_STUB_FEATURE_PICK_UP_SYSEXTS (UINT64_C(1) << 2) #define EFI_STUB_FEATURE_THREE_PCRS (UINT64_C(1) << 3) +#define EFI_STUB_FEATURE_RANDOM_SEED (UINT64_C(1) << 4) typedef enum SecureBootMode { SECURE_BOOT_UNSUPPORTED, diff --git a/units/systemd-boot-system-token.service b/units/systemd-boot-system-token.service index 689b902000..63e523bb3e 100644 --- a/units/systemd-boot-system-token.service +++ b/units/systemd-boot-system-token.service @@ -17,7 +17,8 @@ Conflicts=shutdown.target initrd-switch-root.target Before=shutdown.target initrd-switch-root.target # Only run this if the boot loader can support random seed initialization. -ConditionPathExists=/sys/firmware/efi/efivars/LoaderFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionPathExists|=/sys/firmware/efi/efivars/LoaderFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionPathExists|=/sys/firmware/efi/efivars/StubFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f # Only run this if there is no system token defined yet ConditionPathExists=!/sys/firmware/efi/efivars/LoaderSystemToken-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f |