mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
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.
This commit is contained in:
parent
0c14c45e5c
commit
0a1d8ac77a
2
TODO
2
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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
11
src/boot/efi/part-discovery.h
Normal file
11
src/boot/efi/part-discovery.h
Normal file
|
@ -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);
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue