summaryrefslogtreecommitdiffstats
path: root/src/boot
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2022-11-18 02:49:16 +0100
committerLuca Boccassi <luca.boccassi@gmail.com>2022-11-23 00:56:45 +0100
commit0a1d8ac77a21ae0741bdf4af08f3a71354805ff1 (patch)
tree618f16fec40f4b56ae2550b930d5f3935495c9dd /src/boot
parentsd-event: reenable epoll_pwait2() (diff)
downloadsystemd-0a1d8ac77a21ae0741bdf4af08f3a71354805ff1.tar.xz
systemd-0a1d8ac77a21ae0741bdf4af08f3a71354805ff1.zip
stub: handle random seed like sd-boot does
sd-stub has an opportunity to handle the seed the same way sd-boot does, which would have benefits for UKIs when sd-boot is not in use. This commit wires that up. It refactors the XBOOTLDR partition discovery to also find the ESP partition, so that it access the random seed there.
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/bootctl.c1
-rw-r--r--src/boot/efi/boot.c4
-rw-r--r--src/boot/efi/meson.build8
-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.h11
-rw-r--r--src/boot/efi/stub.c13
-rw-r--r--src/boot/efi/xbootldr.h9
7 files changed, 42 insertions, 24 deletions
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);