mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
sd-stub: if we are http booted, query source URL and write to EFI variable
This way userspace can read the field, and use it to retrieve more resources from the same place.
This commit is contained in:
@@ -97,6 +97,9 @@ variables. All EFI variables use the vendor UUID
|
||||
generally only written once, by the OS installer, and is usually not touched
|
||||
after that.
|
||||
|
||||
* The EFI variable `LoaderDeviceURL` contains the URL the boot loader was
|
||||
downloaded from, in UTF-16 format. Only set in case of network boots.
|
||||
|
||||
If `LoaderTimeInitUSec` and `LoaderTimeExecUSec` are set, `systemd-analyze`
|
||||
will include them in its boot-time analysis. If `LoaderDevicePartUUID` is set,
|
||||
systemd will mount the ESP that was used for the boot to `/boot`, but only if
|
||||
|
||||
@@ -440,6 +440,16 @@
|
||||
<xi:include href="version-info.xml" xpointer="v220"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LoaderDeviceURL</varname></term>
|
||||
|
||||
<listitem><para>If the boot loader has been invoked via network booting this variable contains the
|
||||
originating URL. This may be used to automatically acquire additional resources from the same
|
||||
source.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LoaderEntries</varname></term>
|
||||
|
||||
|
||||
@@ -550,6 +550,16 @@
|
||||
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>StubDeviceURL</varname></term>
|
||||
|
||||
<listitem><para>If the kernel image has been invoked via network booting this variable contains the
|
||||
originating URL. This may be used to automatically acquire additional resources from the same
|
||||
source.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>StubInfo</varname></term>
|
||||
|
||||
|
||||
@@ -2764,6 +2764,7 @@ static void export_loader_variables(
|
||||
EFI_LOADER_FEATURE_RETAIN_SHIM |
|
||||
EFI_LOADER_FEATURE_MENU_DISABLE |
|
||||
EFI_LOADER_FEATURE_MULTI_PROFILE_UKI |
|
||||
EFI_LOADER_FEATURE_REPORT_URL |
|
||||
0;
|
||||
|
||||
assert(loaded_image);
|
||||
|
||||
@@ -4,17 +4,25 @@
|
||||
#include "efivars.h"
|
||||
#include "export-vars.h"
|
||||
#include "part-discovery.h"
|
||||
#include "url-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 (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);
|
||||
if (loaded_image->DeviceHandle) {
|
||||
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", /* ret_data= */ NULL, /* ret_size= */ 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);
|
||||
}
|
||||
|
||||
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDeviceURL", /* ret_data= */ NULL, /* ret_size= */ NULL) != EFI_SUCCESS) {
|
||||
_cleanup_free_ char16_t *url = disk_get_url(loaded_image->DeviceHandle);
|
||||
if (url)
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderDeviceURL", url, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the
|
||||
|
||||
@@ -300,6 +300,7 @@ libefi_sources = files(
|
||||
'shim.c',
|
||||
'smbios.c',
|
||||
'ticks.c',
|
||||
'url-discovery.c',
|
||||
'util.c',
|
||||
'vmm.c',
|
||||
)
|
||||
|
||||
@@ -30,6 +30,8 @@ enum {
|
||||
MEDIA_FILEPATH_DP = 0x04,
|
||||
MEDIA_PIWG_FW_FILE_DP = 0x06,
|
||||
MEDIA_PIWG_FW_VOL_DP = 0x07,
|
||||
|
||||
MSG_URI_DP = 24,
|
||||
};
|
||||
|
||||
struct _packed_ EFI_DEVICE_PATH_PROTOCOL {
|
||||
@@ -67,6 +69,11 @@ typedef struct {
|
||||
char16_t PathName[];
|
||||
} _packed_ FILEPATH_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
EFI_DEVICE_PATH Header;
|
||||
char Uri[];
|
||||
} _packed_ URI_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
char16_t* (EFIAPI *ConvertDeviceNodeToText)(
|
||||
const EFI_DEVICE_PATH *DeviceNode,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "splash.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "uki.h"
|
||||
#include "url-discovery.h"
|
||||
#include "util.h"
|
||||
#include "version.h"
|
||||
#include "vmm.h"
|
||||
@@ -151,6 +152,7 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsig
|
||||
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 */
|
||||
EFI_STUB_FEATURE_REPORT_URL | /* We set StubDeviceURL + LoaderDeviceURL */
|
||||
0;
|
||||
|
||||
assert(loaded_image);
|
||||
@@ -167,6 +169,10 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsig
|
||||
_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);
|
||||
|
||||
_cleanup_free_ char16_t *url = disk_get_url(loaded_image->DeviceHandle);
|
||||
if (url)
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubDeviceURL", url, 0);
|
||||
}
|
||||
|
||||
if (loaded_image->FilePath) {
|
||||
|
||||
30
src/boot/url-discovery.c
Normal file
30
src/boot/url-discovery.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "device-path-util.h"
|
||||
#include "efi-string.h"
|
||||
#include "proto/device-path.h"
|
||||
#include "url-discovery.h"
|
||||
|
||||
char16_t *disk_get_url(EFI_HANDLE *handle) {
|
||||
EFI_STATUS err;
|
||||
EFI_DEVICE_PATH *dp;
|
||||
|
||||
/* export the device path this image is started from */
|
||||
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
err = BS->HandleProtocol(handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
|
||||
if (err != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
for (; !device_path_is_end(dp); dp = device_path_next_node(dp)) {
|
||||
if (dp->Type != MESSAGING_DEVICE_PATH || dp->SubType != MSG_URI_DP)
|
||||
continue;
|
||||
|
||||
URI_DEVICE_PATH *udp = (URI_DEVICE_PATH*) dp;
|
||||
return xstrn8_to_16(udp->Uri, dp->Length);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
4
src/boot/url-discovery.h
Normal file
4
src/boot/url-discovery.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
char16_t *disk_get_url(EFI_HANDLE *handle);
|
||||
@@ -390,12 +390,15 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
{ 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" },
|
||||
{ EFI_LOADER_FEATURE_REPORT_URL, "Loader reports network boot URL" },
|
||||
};
|
||||
static const struct {
|
||||
uint64_t flag;
|
||||
const char *name;
|
||||
} stub_flags[] = {
|
||||
{ EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub sets loader partition information" },
|
||||
{ EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub reports loader partition information" },
|
||||
{ EFI_STUB_FEATURE_REPORT_STUB_PARTITION, "Stub reports stub partition information" },
|
||||
{ EFI_STUB_FEATURE_REPORT_URL, "Stub reports network boot URL" },
|
||||
{ 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" },
|
||||
@@ -405,7 +408,6 @@ 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, *stub_path = NULL,
|
||||
*current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL;
|
||||
@@ -480,6 +482,10 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
(void) efi_loader_get_device_part_uuid(&loader_partition_uuid);
|
||||
print_yes_no_line(/* first= */ false, !sd_id128_is_null(loader_partition_uuid), "Boot loader set partition information");
|
||||
|
||||
_cleanup_free_ char *loader_url = NULL;
|
||||
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderDeviceURL"), &loader_url);
|
||||
print_yes_no_line(/* first= */ false, !!loader_url, "Boot loader set network boot URL information");
|
||||
|
||||
if (!sd_id128_is_null(loader_partition_uuid)) {
|
||||
if (!sd_id128_is_null(esp_uuid) && !sd_id128_equal(esp_uuid, loader_partition_uuid))
|
||||
printf("WARNING: The boot loader reports a different partition UUID than the detected ESP ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
|
||||
@@ -493,6 +499,9 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
if (loader_path)
|
||||
printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
|
||||
|
||||
if (loader_url)
|
||||
printf(" Net Boot URL: %s\n", loader_url);
|
||||
|
||||
if (current_entry)
|
||||
printf("Current Entry: %s\n", current_entry);
|
||||
if (default_entry)
|
||||
@@ -513,6 +522,10 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
(void) efi_stub_get_device_part_uuid(&stub_partition_uuid);
|
||||
print_yes_no_line(/* first= */ false, !sd_id128_is_null(stub_partition_uuid), "Stub loader set partition information");
|
||||
|
||||
_cleanup_free_ char *stub_url = NULL;
|
||||
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("StubDeviceURL"), &stub_url);
|
||||
print_yes_no_line(/* first= */ false, !!stub_url, "Stub set network boot URL information");
|
||||
|
||||
if (!sd_id128_is_null(stub_partition_uuid)) {
|
||||
if (!(!sd_id128_is_null(esp_uuid) && sd_id128_equal(esp_uuid, stub_partition_uuid)) &&
|
||||
!(!sd_id128_is_null(xbootldr_uuid) && sd_id128_equal(xbootldr_uuid, stub_partition_uuid)))
|
||||
@@ -526,6 +539,10 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
|
||||
if (stub_path)
|
||||
printf(" Stub: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(stub_path));
|
||||
|
||||
if (stub_url)
|
||||
printf(" Net Boot URL: %s\n", stub_url);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define EFI_LOADER_FEATURE_RETAIN_SHIM (UINT64_C(1) << 12)
|
||||
#define EFI_LOADER_FEATURE_MENU_DISABLE (UINT64_C(1) << 13)
|
||||
#define EFI_LOADER_FEATURE_MULTI_PROFILE_UKI (UINT64_C(1) << 14)
|
||||
#define EFI_LOADER_FEATURE_REPORT_URL (UINT64_C(1) << 15)
|
||||
|
||||
/* Features of the stub, i.e. systemd-stub */
|
||||
#define EFI_STUB_FEATURE_REPORT_BOOT_PARTITION (UINT64_C(1) << 0)
|
||||
@@ -37,6 +38,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)
|
||||
#define EFI_STUB_FEATURE_REPORT_URL (UINT64_C(1) << 11)
|
||||
|
||||
typedef enum SecureBootMode {
|
||||
SECURE_BOOT_UNSUPPORTED,
|
||||
|
||||
Reference in New Issue
Block a user