summaryrefslogtreecommitdiff
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
parent0c14c45e5c00bbaed81566ace8f0d0c70cfe6392 (diff)
downloadsystemd-0a1d8ac77a21ae0741bdf4af08f3a71354805ff1.tar.gz
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.
-rw-r--r--TODO2
-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
-rw-r--r--src/fundamental/efivars-fundamental.h1
-rw-r--r--units/systemd-boot-system-token.service3
10 files changed, 45 insertions, 27 deletions
diff --git a/TODO b/TODO
index 6ad4778ddc..8416dbcbbb 100644
--- a/TODO
+++ b/TODO
@@ -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