diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 99061a1339..9dbf96f169 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -7,6 +7,7 @@ #include "devicetree.h" #include "drivers.h" #include "efivars-fundamental.h" +#include "export-vars.h" #include "graphics.h" #include "initrd.h" #include "linux.h" @@ -2538,9 +2539,8 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) return EFI_SUCCESS; } -static void export_variables( +static void export_loader_variables( EFI_LOADED_IMAGE_PROTOCOL *loaded_image, - const char16_t *loaded_image_path, uint64_t init_usec) { static const uint64_t loader_features = @@ -2560,28 +2560,11 @@ static void export_variables( EFI_LOADER_FEATURE_MENU_DISABLE | 0; - _cleanup_free_ char16_t *infostr = NULL, *typestr = NULL; - assert(loaded_image); - efivar_set_time_usec(MAKE_GUID_PTR(LOADER), u"LoaderTimeInitUSec", init_usec); - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderInfo", u"systemd-boot " GIT_VERSION, 0); - - infostr = xasprintf("%ls %u.%02u", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", infostr, 0); - - typestr = xasprintf("UEFI %u.%02u", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", typestr, 0); - + (void) efivar_set_time_usec(MAKE_GUID_PTR(LOADER), u"LoaderTimeInitUSec", init_usec); + (void) efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderInfo", u"systemd-boot " GIT_VERSION, 0); (void) efivar_set_uint64_le(MAKE_GUID_PTR(LOADER), u"LoaderFeatures", loader_features, 0); - - /* the filesystem path to this image, to prevent adding ourselves to the menu */ - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", loaded_image_path, 0); - - /* export the device path this image is started from */ - _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle); - if (uuid) - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0); } static void config_load_all_entries( @@ -2681,7 +2664,6 @@ static EFI_STATUS run(EFI_HANDLE image) { EFI_LOADED_IMAGE_PROTOCOL *loaded_image; _cleanup_(file_closep) EFI_FILE *root_dir = NULL; _cleanup_(config_free) Config config = {}; - _cleanup_free_ char16_t *loaded_image_path = NULL; EFI_STATUS err; uint64_t init_usec; bool menu = false; @@ -2696,9 +2678,8 @@ static EFI_STATUS run(EFI_HANDLE image) { if (err != EFI_SUCCESS) return log_error_status(err, "Error getting a LoadedImageProtocol handle: %m"); - (void) device_path_to_str(loaded_image->FilePath, &loaded_image_path); - - export_variables(loaded_image, loaded_image_path, init_usec); + export_common_variables(loaded_image); + export_loader_variables(loaded_image, init_usec); err = discover_root_dir(loaded_image, &root_dir); if (err != EFI_SUCCESS) @@ -2706,6 +2687,8 @@ static EFI_STATUS run(EFI_HANDLE image) { (void) load_drivers(image, loaded_image, root_dir); + _cleanup_free_ char16_t *loaded_image_path = NULL; + (void) device_path_to_str(loaded_image->FilePath, &loaded_image_path); config_load_all_entries(&config, loaded_image, loaded_image_path, root_dir); if (config.n_entries == 0) diff --git a/src/boot/efi/export-vars.c b/src/boot/efi/export-vars.c new file mode 100644 index 0000000000..3926747bba --- /dev/null +++ b/src/boot/efi/export-vars.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "device-path-util.h" +#include "export-vars.h" +#include "part-discovery.h" +#include "util.h" + +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) { + _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle); + if (uuid) + efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0); + } + + /* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the + * UEFI firmware without any boot loader, and hence set the LoaderImageIdentifier ourselves. Note + * that some boot chain loaders neither set LoaderImageIdentifier nor make FilePath available to us, + * 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) { + _cleanup_free_ char16_t *s = NULL; + if (device_path_to_str(loaded_image->FilePath, &s) == EFI_SUCCESS) + efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", s, 0); + } + + /* if LoaderFirmwareInfo is not set, let's set it */ + if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { + _cleanup_free_ char16_t *s = NULL; + s = xasprintf("%ls %u.%02u", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); + efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", s, 0); + } + + /* ditto for LoaderFirmwareType */ + if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { + _cleanup_free_ char16_t *s = NULL; + s = xasprintf("UEFI %u.%02u", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); + efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", s, 0); + } +} diff --git a/src/boot/efi/export-vars.h b/src/boot/efi/export-vars.h new file mode 100644 index 0000000000..a925d09827 --- /dev/null +++ b/src/boot/efi/export-vars.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "proto/loaded-image.h" + +void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image); diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 7a60b0ec7e..42a7914bf6 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -258,6 +258,7 @@ libefi_sources = files( 'devicetree.c', 'drivers.c', 'efi-string.c', + 'export-vars.c', 'graphics.c', 'initrd.c', 'log.c', diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 3e95eb1785..db4f473410 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -3,6 +3,7 @@ #include "cpio.h" #include "device-path-util.h" #include "devicetree.h" +#include "export-vars.h" #include "graphics.h" #include "iovec-util-fundamental.h" #include "linux.h" @@ -138,7 +139,7 @@ static EFI_STATUS combine_initrds( return EFI_SUCCESS; } -static void export_general_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) { +static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) { static const uint64_t stub_features = EFI_STUB_FEATURE_REPORT_BOOT_PARTITION | /* We set LoaderDevicePartUUID */ EFI_STUB_FEATURE_PICK_UP_CREDENTIALS | /* We pick up credentials from the boot partition */ @@ -153,40 +154,6 @@ static void export_general_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) { - _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle); - if (uuid) - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0); - } - - /* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the - * UEFI firmware without any boot loader, and hence set the LoaderImageIdentifier ourselves. Note - * that some boot chain loaders neither set LoaderImageIdentifier nor make FilePath available to us, - * 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) { - _cleanup_free_ char16_t *s = NULL; - if (device_path_to_str(loaded_image->FilePath, &s) == EFI_SUCCESS) - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", s, 0); - } - - /* if LoaderFirmwareInfo is not set, let's set it */ - if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { - _cleanup_free_ char16_t *s = NULL; - s = xasprintf("%ls %u.%02u", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", s, 0); - } - - /* ditto for LoaderFirmwareType */ - if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { - _cleanup_free_ char16_t *s = NULL; - s = xasprintf("UEFI %u.%02u", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", s, 0); - } - /* add StubInfo (this is one is owned by the stub, hence we unconditionally override this with our * own data) */ (void) efivar_set(MAKE_GUID_PTR(LOADER), u"StubInfo", u"systemd-stub " GIT_VERSION, 0); @@ -939,7 +906,8 @@ static EFI_STATUS run(EFI_HANDLE image) { cmdline_append_and_measure_addons(cmdline_addons, &cmdline, ¶meters_measured); cmdline_append_and_measure_smbios(&cmdline, ¶meters_measured); - export_general_variables(loaded_image); + export_common_variables(loaded_image); + export_stub_variables(loaded_image); /* First load the base device tree, then fix it up using addons - global first, then per-UKI. */ install_embedded_devicetree(loaded_image, sections, &dt_state);