From 66d3605896e1960583d0b2502920f33d14088801 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2024 10:49:35 +0200 Subject: [PATCH 1/5] bootctl: show new sd-boot/sd-stub feature flags --- src/boot/bootctl-status.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index 113d27410f..386f03e0dc 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -378,6 +378,7 @@ int verb_status(int argc, char *argv[], void *userdata) { { EFI_LOADER_FEATURE_SECUREBOOT_ENROLL, "Enroll SecureBoot keys" }, { EFI_LOADER_FEATURE_RETAIN_SHIM, "Retain SHIM protocols" }, { EFI_LOADER_FEATURE_MENU_DISABLE, "Menu can be disabled" }, + { EFI_LOADER_FEATURE_MULTI_PROFILE_UKI, "Multi-Profile UKIs are supported" }, }; static const struct { uint64_t flag; @@ -392,6 +393,7 @@ int verb_status(int argc, char *argv[], void *userdata) { { EFI_STUB_FEATURE_CMDLINE_ADDONS, "Pick up .cmdline from addons" }, { EFI_STUB_FEATURE_CMDLINE_SMBIOS, "Pick up .cmdline from SMBIOS Type 11" }, { EFI_STUB_FEATURE_DEVICETREE_ADDONS, "Pick up .dtb from addons" }, + { EFI_STUB_FEATURE_MULTI_PROFILE_UKI, "Stub understands profile selector" }, }; _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; From 8b5ad0ba41dee20cf039d5fd9a4a5af05be43c96 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Jul 2024 15:48:42 +0200 Subject: [PATCH 2/5] man: fix LoaderDevicePathUUID + LoaderImageIdentifier descriptions First of all, these were always set, i.e. since sd-boot was merged into our tree, i.e. v220. Let's say so explicitly. Also, let's be more accurate, regarding which partition this referes to: it's usually "the" ESP, but given that you can make firmware boot from arbitrary disks, it could be any other partition too. Hence, be explicit on this. Also, clarify tha sd-stub will set this too, if sd-boot never set it. --- man/systemd-boot.xml | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml index cc4504926c..0da919b127 100644 --- a/man/systemd-boot.xml +++ b/man/systemd-boot.xml @@ -429,13 +429,15 @@ LoaderDevicePartUUID - Contains the partition UUID of the EFI System Partition the boot loader was run from. Set by - the boot - loader. systemd-gpt-auto-generator8 - uses this information to automatically find the disk booted from, in order to discover various other partitions - on the same disk automatically. + Contains the partition UUID of the partition the boot loader has been started from on + the current boot (usually a EFI System Partition). Set by the boot loader. (Note that + systemd-stub will set this too, if not set yet, to support systems that directly + boot into a unified kernel image, bypassing any boot loader.) + systemd-gpt-auto-generator8 + uses this information to automatically find the disk booted from, in order to discover various other + partitions on the same disk automatically. - + @@ -516,12 +518,15 @@ LoaderImageIdentifier - The path of executable of the boot loader used for the current boot, relative to the EFI System - Partition's root directory. Set by the boot loader. Use - bootctl1 to view this - data. + The file system path to the EFI executable of the boot loader for the current boot, + relative to the partition's root directory (i.e. relative to the partition indicated by + LoaderDevicePartUUID, see above). Set by the boot loader. (Note that + systemd-stub will set this too, if not set yet, to support systems that directly + boot into a unified kernel image, bypassing any boot loader.) Use + bootctl1 to view + this data. - + From 8d5ff87a70d8eae868d1c3c6ba11a082717f2039 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Jul 2024 16:06:40 +0200 Subject: [PATCH 3/5] man: fix documentation for LoaderDevicePathUUID + LoaderImageIdentifier, in systemd-stub man page too Let's fix the version here too, and also clarify that this is usually not necessarily the ESP. --- man/systemd-stub.xml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/man/systemd-stub.xml b/man/systemd-stub.xml index 9f87f19f4c..d2590e509e 100644 --- a/man/systemd-stub.xml +++ b/man/systemd-stub.xml @@ -459,12 +459,16 @@ LoaderDevicePartUUID - Contains the partition UUID of the EFI System Partition the EFI image was run - from. systemd-gpt-auto-generator8 + Contains the partition UUID of the partition the boot loader has been started from on + the current boot (usually a EFI System Partition). If already set by the boot loader, this will + remain untouched by systemd-stub. If not set yet, this will be set to the + partition UUID of the partition the unified kernel is started from, in order to support systems that + directly boot into a unified kernel image, bypassing any boot loader. + systemd-gpt-auto-generator8 uses this information to automatically find the disk booted from, in order to discover various other partitions on the same disk automatically. - + @@ -481,12 +485,15 @@ LoaderImageIdentifier - The path of EFI executable, relative to the EFI System Partition's root - directory. Use + The file system path to the EFI executable of the boot loader for the current boot, + relative to the partition's root directory (i.e. relative to the partition indicated by + LoaderDevicePartUUID, see above). If not set yet, this will be set to the file + system path of the EFI executable of the booted unified kernel, in order to support systems that + directly boot into a unified kernel image, bypassing any boot loader. Use bootctl1 to view this data. - + From 77d496c083097b0cf4dca773c76f4f6625d7866f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Jul 2024 16:07:51 +0200 Subject: [PATCH 4/5] stub: tweak setting of common Loader* EFI vars Let's always check if we have data to set *first*, and only then check if an EFI var is already set. Checking for the EFI var is more expensive after all. --- src/boot/efi/export-vars.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/boot/efi/export-vars.c b/src/boot/efi/export-vars.c index 3f59922a7e..12fbd10b05 100644 --- a/src/boot/efi/export-vars.c +++ b/src/boot/efi/export-vars.c @@ -10,7 +10,8 @@ void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) { assert(loaded_image); /* Export the device path this image is started from, if it's not set yet */ - if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) { + if (loaded_image->DeviceHandle && + efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) { _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle); if (uuid) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0); @@ -22,8 +23,8 @@ void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) { * in which case there's simple nothing to set for us. (The UEFI spec doesn't really say who's wrong * here, i.e. whether FilePath may be NULL or not, hence handle this gracefully and check if FilePath * is non-NULL explicitly.) */ - if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS && - loaded_image->FilePath) { + if (loaded_image->FilePath && + efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { _cleanup_free_ char16_t *s = NULL; if (device_path_to_str(loaded_image->FilePath, &s) == EFI_SUCCESS) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", s, 0); From a482908cbcaa9f67e3c46429fb5f13a5f32f45d3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Jul 2024 16:11:31 +0200 Subject: [PATCH 5/5] stub: add StubDevicePartUUID/StubImageIdentifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These variables closely mirror the existing LoaderDevicePartUUID/LoaderImageIdentifier variables. But the Stub… variables indicate the location of the stub/UKI (i.e. of systemd-stub), while the Loader… variables indicate the location of the boot loader (i.e. of systemd-boot). (Except of course, there is no boot loader used, in which case both sets point to the stub/UKI, as a special case). This actually matters, as we support that sd-boot runs off the ESP, while a UKI then runs off XBOOTLDR, i.e. two distinct partitions. --- man/systemd-stub.xml | 12 ++++++++++++ src/boot/bootctl-status.c | 3 ++- src/boot/efi/stub.c | 13 +++++++++++++ src/fundamental/efivars-fundamental.h | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/man/systemd-stub.xml b/man/systemd-stub.xml index d2590e509e..dbc85d837a 100644 --- a/man/systemd-stub.xml +++ b/man/systemd-stub.xml @@ -496,6 +496,18 @@ + + StubDevicePartUUID + StubImageIdentifier + + Similar to LoaderDevicePartUUID and + StubImageIdentifier, but indicates the location of the unified kernel image EFI + binary rather than the location of the boot loader binary, regardless if booted via a boot loader + or not. + + + + StubInfo diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index 386f03e0dc..192fddbf5e 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -384,7 +384,7 @@ int verb_status(int argc, char *argv[], void *userdata) { uint64_t flag; const char *name; } stub_flags[] = { - { EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub sets ESP information" }, + { EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub sets loader partition information" }, { 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_PICK_UP_CONFEXTS, "Picks up configuration extension images from boot partition" }, @@ -394,6 +394,7 @@ int verb_status(int argc, char *argv[], void *userdata) { { EFI_STUB_FEATURE_CMDLINE_SMBIOS, "Pick up .cmdline from SMBIOS Type 11" }, { EFI_STUB_FEATURE_DEVICETREE_ADDONS, "Pick up .dtb from addons" }, { EFI_STUB_FEATURE_MULTI_PROFILE_UKI, "Stub understands profile selector" }, + { EFI_STUB_FEATURE_REPORT_STUB_PARTITION, "Stub sets stub partition information" }, }; _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/stub.c b/src/boot/efi/stub.c index 0ace97013f..a5b1c50acb 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -153,6 +153,7 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsig EFI_STUB_FEATURE_CMDLINE_SMBIOS | /* We support extending kernel cmdline from SMBIOS Type #11 */ EFI_STUB_FEATURE_DEVICETREE_ADDONS | /* We pick up .dtb addons */ EFI_STUB_FEATURE_MULTI_PROFILE_UKI | /* We grok the "@1" profile command line argument */ + EFI_STUB_FEATURE_REPORT_STUB_PARTITION | /* We set StubDevicePartUUID + StubImageIdentifier */ 0; assert(loaded_image); @@ -164,6 +165,18 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsig (void) efivar_set_uint64_le(MAKE_GUID_PTR(LOADER), u"StubFeatures", stub_features, 0); (void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"StubProfile", profile, 0); + + if (loaded_image->DeviceHandle) { + _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle); + if (uuid) + efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubDevicePartUUID", uuid, 0); + } + + if (loaded_image->FilePath) { + _cleanup_free_ char16_t *s = NULL; + if (device_path_to_str(loaded_image->FilePath, &s) == EFI_SUCCESS) + efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubImageIdentifier", s, 0); + } } static bool parse_profile_from_cmdline(char16_t **cmdline, unsigned *ret_profile) { diff --git a/src/fundamental/efivars-fundamental.h b/src/fundamental/efivars-fundamental.h index e18d59ff60..f002e81b53 100644 --- a/src/fundamental/efivars-fundamental.h +++ b/src/fundamental/efivars-fundamental.h @@ -36,6 +36,7 @@ #define EFI_STUB_FEATURE_DEVICETREE_ADDONS (UINT64_C(1) << 7) #define EFI_STUB_FEATURE_PICK_UP_CONFEXTS (UINT64_C(1) << 8) #define EFI_STUB_FEATURE_MULTI_PROFILE_UKI (UINT64_C(1) << 9) +#define EFI_STUB_FEATURE_REPORT_STUB_PARTITION (UINT64_C(1) << 10) typedef enum SecureBootMode { SECURE_BOOT_UNSUPPORTED,