Merge pull request #27358 from bluca/pe_mule
stub: allow loading and verifying kernel command line addons
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "efi.h"
|
||||
#include "version.h"
|
||||
|
||||
/* Magic string for recognizing our own binaries */
|
||||
_used_ _section_(".sdmagic") static const char magic[] =
|
||||
"#### LoaderInfo: systemd-addon " GIT_VERSION " ####";
|
||||
|
||||
/* This is intended to carry data, not to be executed */
|
||||
|
||||
EFIAPI EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table);
|
||||
EFIAPI EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@@ -2641,6 +2641,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
|
||||
init_usec = time_usec();
|
||||
|
||||
/* Ask Shim to leave its protocol around, so that the stub can use it to validate PEs.
|
||||
* By default, Shim uninstalls its protocol when calling StartImage(). */
|
||||
shim_retain_protocol();
|
||||
|
||||
err = BS->OpenProtocol(
|
||||
image,
|
||||
MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL),
|
||||
|
||||
+1
-24
@@ -301,29 +301,6 @@ static EFI_STATUS pack_cpio_trailer(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static char16_t *get_dropin_dir(const EFI_DEVICE_PATH *file_path) {
|
||||
if (!file_path)
|
||||
return NULL;
|
||||
|
||||
/* A device path is allowed to have more than one file path node. If that is the case they are
|
||||
* supposed to be concatenated. Unfortunately, the device path to text protocol simply converts the
|
||||
* nodes individually and then combines those with the usual '/' for device path nodes. But this does
|
||||
* not create a legal EFI file path that the file protocol can use. */
|
||||
|
||||
/* Make sure we really only got file paths. */
|
||||
for (const EFI_DEVICE_PATH *node = file_path; !device_path_is_end(node);
|
||||
node = device_path_next_node(node))
|
||||
if (node->Type != MEDIA_DEVICE_PATH || node->SubType != MEDIA_FILEPATH_DP)
|
||||
return NULL;
|
||||
|
||||
_cleanup_free_ char16_t *file_path_str = NULL;
|
||||
if (device_path_to_str(file_path, &file_path_str) != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
convert_efi_path(file_path_str);
|
||||
return xasprintf("%ls.extra.d", file_path_str);
|
||||
}
|
||||
|
||||
EFI_STATUS pack_cpio(
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||
const char16_t *dropin_dir,
|
||||
@@ -363,7 +340,7 @@ EFI_STATUS pack_cpio(
|
||||
return log_error_status(err, "Unable to open root directory: %m");
|
||||
|
||||
if (!dropin_dir)
|
||||
dropin_dir = rel_dropin_dir = get_dropin_dir(loaded_image->FilePath);
|
||||
dropin_dir = rel_dropin_dir = get_extra_dir(loaded_image->FilePath);
|
||||
|
||||
err = open_directory(root, dropin_dir, &extra_dir);
|
||||
if (err == EFI_NOT_FOUND)
|
||||
|
||||
@@ -242,6 +242,7 @@ libefi_sources = files(
|
||||
'pe.c',
|
||||
'random-seed.c',
|
||||
'secure-boot.c',
|
||||
'shim.c',
|
||||
'ticks.c',
|
||||
'util.c',
|
||||
'vmm.c',
|
||||
@@ -249,7 +250,6 @@ libefi_sources = files(
|
||||
|
||||
systemd_boot_sources = files(
|
||||
'boot.c',
|
||||
'shim.c',
|
||||
)
|
||||
|
||||
stub_sources = files(
|
||||
@@ -259,6 +259,10 @@ stub_sources = files(
|
||||
'stub.c',
|
||||
)
|
||||
|
||||
addon_sources = files(
|
||||
'addon.c',
|
||||
)
|
||||
|
||||
if get_option('b_sanitize') == 'undefined'
|
||||
libefi_sources += files('ubsan.c')
|
||||
endif
|
||||
@@ -328,12 +332,28 @@ foreach archspec : efi_archspecs
|
||||
override_options : efi_override_options,
|
||||
name_suffix : 'elf.stub',
|
||||
pie : true)
|
||||
|
||||
efi_elf_binaries += executable(
|
||||
'addon' + archspec['arch'],
|
||||
addon_sources,
|
||||
include_directories : efi_includes,
|
||||
c_args : archspec['c_args'],
|
||||
link_args : archspec['link_args'],
|
||||
link_depends : elf2efi_lds,
|
||||
dependencies : versiondep,
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
override_options : efi_override_options,
|
||||
name_suffix : 'elf.stub',
|
||||
pie : true)
|
||||
endforeach
|
||||
|
||||
foreach efi_elf_binary : efi_elf_binaries
|
||||
# FIXME: Use build_tgt.name() with meson >= 0.54.0
|
||||
name = fs.name(efi_elf_binary.full_path()).split('.')[0]
|
||||
name += name.startswith('linux') ? '.efi.stub' : '.efi'
|
||||
name += name.startswith('systemd-boot') ? '.efi' : '.efi.stub'
|
||||
# For the addon, given it's empty, we need to explicitly reserve space in the header to account for
|
||||
# the sections that ukify will add.
|
||||
minimum_sections = name.startswith('addon') ? '7' : '0'
|
||||
exe = custom_target(
|
||||
name,
|
||||
output : name,
|
||||
@@ -348,6 +368,7 @@ foreach efi_elf_binary : efi_elf_binaries
|
||||
'--efi-major=1',
|
||||
'--efi-minor=1',
|
||||
'--subsystem=10',
|
||||
'--minimum-sections=' + minimum_sections,
|
||||
'@INPUT@',
|
||||
'@OUTPUT@',
|
||||
])
|
||||
|
||||
@@ -97,3 +97,12 @@ EFI_STATUS shim_load_image(EFI_HANDLE parent, const EFI_DEVICE_PATH *device_path
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void shim_retain_protocol(void) {
|
||||
uint8_t value = 1;
|
||||
|
||||
/* Ask Shim to avoid uninstalling its security protocol, so that we can use it from sd-stub to
|
||||
* validate PE addons. By default, Shim uninstalls its protocol when calling StartImage().
|
||||
* Requires Shim 15.8. */
|
||||
(void) efivar_set_raw(MAKE_GUID_PTR(SHIM_LOCK), u"ShimRetainProtocol", &value, sizeof(value), 0);
|
||||
}
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
|
||||
bool shim_loaded(void);
|
||||
EFI_STATUS shim_load_image(EFI_HANDLE parent, const EFI_DEVICE_PATH *device_path, EFI_HANDLE *ret_image);
|
||||
void shim_retain_protocol(void);
|
||||
|
||||
+223
-1
@@ -11,6 +11,7 @@
|
||||
#include "proto/shell-parameters.h"
|
||||
#include "random-seed.h"
|
||||
#include "secure-boot.h"
|
||||
#include "shim.h"
|
||||
#include "splash.h"
|
||||
#include "tpm-pcr.h"
|
||||
#include "util.h"
|
||||
@@ -180,6 +181,189 @@ static bool use_load_options(
|
||||
return true;
|
||||
}
|
||||
|
||||
static EFI_STATUS load_addons_from_dir(
|
||||
EFI_FILE *root,
|
||||
const char16_t *prefix,
|
||||
char16_t ***items,
|
||||
size_t *n_items,
|
||||
size_t *n_allocated) {
|
||||
|
||||
_cleanup_(file_closep) EFI_FILE *extra_dir = NULL;
|
||||
_cleanup_free_ EFI_FILE_INFO *dirent = NULL;
|
||||
size_t dirent_size = 0;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(root);
|
||||
assert(prefix);
|
||||
assert(items);
|
||||
assert(n_items);
|
||||
assert(n_allocated);
|
||||
|
||||
err = open_directory(root, prefix, &extra_dir);
|
||||
if (err == EFI_NOT_FOUND)
|
||||
/* No extra subdir, that's totally OK */
|
||||
return EFI_SUCCESS;
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Failed to open addons directory '%ls': %m", prefix);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char16_t *d = NULL;
|
||||
|
||||
err = readdir(extra_dir, &dirent, &dirent_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Failed to read addons directory of loaded image: %m");
|
||||
if (!dirent) /* End of directory */
|
||||
break;
|
||||
|
||||
if (dirent->FileName[0] == '.')
|
||||
continue;
|
||||
if (FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY))
|
||||
continue;
|
||||
if (!is_ascii(dirent->FileName))
|
||||
continue;
|
||||
if (strlen16(dirent->FileName) > 255) /* Max filename size on Linux */
|
||||
continue;
|
||||
if (!endswith_no_case(dirent->FileName, u".addon.efi"))
|
||||
continue;
|
||||
|
||||
d = xstrdup16(dirent->FileName);
|
||||
|
||||
if (*n_items + 2 > *n_allocated) {
|
||||
/* We allocate 16 entries at a time, as a matter of optimization */
|
||||
if (*n_items > (SIZE_MAX / sizeof(uint16_t)) - 16) /* Overflow check, just in case */
|
||||
return log_oom();
|
||||
|
||||
size_t m = *n_items + 16;
|
||||
*items = xrealloc(*items, *n_allocated * sizeof(uint16_t *), m * sizeof(uint16_t *));
|
||||
*n_allocated = m;
|
||||
}
|
||||
|
||||
(*items)[(*n_items)++] = TAKE_PTR(d);
|
||||
(*items)[*n_items] = NULL; /* Let's always NUL terminate, to make freeing via strv_free() easy */
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static EFI_STATUS cmdline_append_and_measure_addons(
|
||||
EFI_HANDLE stub_image,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||
const char16_t *prefix,
|
||||
const char *uname,
|
||||
bool *ret_parameters_measured,
|
||||
char16_t **cmdline_append) {
|
||||
|
||||
_cleanup_(strv_freep) char16_t **items = NULL;
|
||||
_cleanup_(file_closep) EFI_FILE *root = NULL;
|
||||
_cleanup_free_ char16_t *buffer = NULL;
|
||||
size_t n_items = 0, n_allocated = 0;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(stub_image);
|
||||
assert(loaded_image);
|
||||
assert(prefix);
|
||||
assert(ret_parameters_measured);
|
||||
assert(cmdline_append);
|
||||
|
||||
if (!loaded_image->DeviceHandle)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
err = open_volume(loaded_image->DeviceHandle, &root);
|
||||
if (err == EFI_UNSUPPORTED)
|
||||
/* Error will be unsupported if the bootloader doesn't implement the file system protocol on
|
||||
* its file handles. */
|
||||
return EFI_SUCCESS;
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Unable to open root directory: %m");
|
||||
|
||||
err = load_addons_from_dir(root, prefix, &items, &n_items, &n_allocated);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (n_items == 0)
|
||||
return EFI_SUCCESS; /* Empty directory */
|
||||
|
||||
/* Now, sort the files we found, to make this uniform and stable (and to ensure the TPM measurements
|
||||
* are not dependent on read order) */
|
||||
sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) strcmp16);
|
||||
|
||||
for (size_t i = 0; i < n_items; i++) {
|
||||
size_t addrs[_UNIFIED_SECTION_MAX] = {}, szs[_UNIFIED_SECTION_MAX] = {};
|
||||
_cleanup_free_ EFI_DEVICE_PATH *addon_path = NULL;
|
||||
_cleanup_(unload_imagep) EFI_HANDLE addon = NULL;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_addon = NULL;
|
||||
_cleanup_free_ char16_t *addon_spath = NULL;
|
||||
|
||||
addon_spath = xasprintf("%ls\\%ls", prefix, items[i]);
|
||||
err = make_file_device_path(loaded_image->DeviceHandle, addon_spath, &addon_path);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Error making device path for %ls: %m", addon_spath);
|
||||
|
||||
/* By using shim_load_image, we cover both the case where the PE files are signed with MoK
|
||||
* and with DB, and running with or without shim. */
|
||||
err = shim_load_image(stub_image, addon_path, &addon);
|
||||
if (err != EFI_SUCCESS) {
|
||||
log_error_status(err,
|
||||
"Failed to read '%ls' from '%ls', ignoring: %m",
|
||||
items[i],
|
||||
addon_spath);
|
||||
continue;
|
||||
}
|
||||
|
||||
err = BS->HandleProtocol(addon,
|
||||
MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL),
|
||||
(void **) &loaded_addon);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Failed to find protocol in %ls: %m", items[i]);
|
||||
|
||||
err = pe_memory_locate_sections(loaded_addon->ImageBase, unified_sections, addrs, szs);
|
||||
if (err != EFI_SUCCESS || szs[UNIFIED_SECTION_CMDLINE] == 0) {
|
||||
if (err == EFI_SUCCESS)
|
||||
err = EFI_NOT_FOUND;
|
||||
log_error_status(err,
|
||||
"Unable to locate embedded .cmdline section in %ls, ignoring: %m",
|
||||
items[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We want to enforce that addons are not UKIs, i.e.: they must not embed a kernel. */
|
||||
if (szs[UNIFIED_SECTION_LINUX] > 0) {
|
||||
log_error_status(EFI_INVALID_PARAMETER, "%ls is a UKI, not an addon, ignoring: %m", items[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Also enforce that, in case it is specified, .uname matches as a quick way to allow
|
||||
* enforcing compatibility with a specific UKI only */
|
||||
if (uname && szs[UNIFIED_SECTION_UNAME] > 0 &&
|
||||
!strneq8(uname,
|
||||
(char *)loaded_addon->ImageBase + addrs[UNIFIED_SECTION_UNAME],
|
||||
szs[UNIFIED_SECTION_UNAME])) {
|
||||
log_error(".uname mismatch between %ls and UKI, ignoring", items[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
_cleanup_free_ char16_t *tmp = TAKE_PTR(buffer),
|
||||
*extra16 = xstrn8_to_16((char *)loaded_addon->ImageBase + addrs[UNIFIED_SECTION_CMDLINE],
|
||||
szs[UNIFIED_SECTION_CMDLINE]);
|
||||
buffer = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", extra16);
|
||||
}
|
||||
|
||||
mangle_stub_cmdline(buffer);
|
||||
|
||||
if (!isempty(buffer)) {
|
||||
_cleanup_free_ char16_t *tmp = TAKE_PTR(*cmdline_append);
|
||||
bool m = false;
|
||||
|
||||
(void) tpm_log_load_options(buffer, &m);
|
||||
*ret_parameters_measured = m;
|
||||
|
||||
*cmdline_append = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", buffer);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS run(EFI_HANDLE image) {
|
||||
_cleanup_free_ void *credential_initrd = NULL, *global_credential_initrd = NULL, *sysext_initrd = NULL, *pcrsig_initrd = NULL, *pcrpkey_initrd = NULL;
|
||||
size_t credential_initrd_size = 0, global_credential_initrd_size = 0, sysext_initrd_size = 0, pcrsig_initrd_size = 0, pcrpkey_initrd_size = 0;
|
||||
@@ -190,6 +374,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
size_t addrs[_UNIFIED_SECTION_MAX] = {}, szs[_UNIFIED_SECTION_MAX] = {};
|
||||
_cleanup_free_ char16_t *cmdline = NULL;
|
||||
int sections_measured = -1, parameters_measured = -1;
|
||||
_cleanup_free_ char *uname = NULL;
|
||||
bool sysext_measured = false, m;
|
||||
uint64_t loader_features = 0;
|
||||
EFI_STATUS err;
|
||||
@@ -262,6 +447,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
/* Show splash screen as early as possible */
|
||||
graphics_splash((const uint8_t*) loaded_image->ImageBase + addrs[UNIFIED_SECTION_SPLASH], szs[UNIFIED_SECTION_SPLASH]);
|
||||
|
||||
if (szs[UNIFIED_SECTION_UNAME] > 0)
|
||||
uname = xstrndup8((char *)loaded_image->ImageBase + addrs[UNIFIED_SECTION_UNAME],
|
||||
szs[UNIFIED_SECTION_UNAME]);
|
||||
|
||||
if (use_load_options(image, loaded_image, szs[UNIFIED_SECTION_CMDLINE] > 0, &cmdline)) {
|
||||
/* Let's measure the passed kernel command line into the TPM. Note that this possibly
|
||||
* duplicates what we already did in the boot menu, if that was already used. However, since
|
||||
@@ -277,11 +466,44 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
mangle_stub_cmdline(cmdline);
|
||||
}
|
||||
|
||||
/* SMBIOS strings are measured in PCR1, so we do not re-measure these command line extensions. */
|
||||
/* If we have any extra command line to add via PE addons, load them now and append, and
|
||||
* measure the additions separately, after the embedded options, but before the smbios ones,
|
||||
* so that the order is reversed from "most hardcoded" to "most dynamic". The global addons are
|
||||
* loaded first, and the image-specific ones later, for the same reason. */
|
||||
err = cmdline_append_and_measure_addons(
|
||||
image,
|
||||
loaded_image,
|
||||
u"\\loader\\addons",
|
||||
uname,
|
||||
&m,
|
||||
&cmdline);
|
||||
if (err != EFI_SUCCESS)
|
||||
log_error_status(err, "Error loading global addons, ignoring: %m");
|
||||
parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
|
||||
|
||||
_cleanup_free_ char16_t *dropin_dir = get_extra_dir(loaded_image->FilePath);
|
||||
err = cmdline_append_and_measure_addons(
|
||||
image,
|
||||
loaded_image,
|
||||
dropin_dir,
|
||||
uname,
|
||||
&m,
|
||||
&cmdline);
|
||||
if (err != EFI_SUCCESS)
|
||||
log_error_status(err, "Error loading UKI-specific addons, ignoring: %m");
|
||||
parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
|
||||
|
||||
const char *extra = smbios_find_oem_string("io.systemd.stub.kernel-cmdline-extra");
|
||||
if (extra) {
|
||||
_cleanup_free_ char16_t *tmp = TAKE_PTR(cmdline), *extra16 = xstr8_to_16(extra);
|
||||
cmdline = xasprintf("%ls %ls", tmp, extra16);
|
||||
|
||||
/* SMBIOS strings are measured in PCR1, but we also want to measure them in our specific
|
||||
* PCR12, as firmware-owned PCRs are very difficult to use as they'll contain unpredictable
|
||||
* measurements that are not under control of the machine owner. */
|
||||
m = false;
|
||||
(void) tpm_log_load_options(extra16, &m);
|
||||
parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
|
||||
}
|
||||
|
||||
export_variables(loaded_image);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "device-path-util.h"
|
||||
#include "proto/device-path.h"
|
||||
#include "proto/simple-text-io.h"
|
||||
#include "ticks.h"
|
||||
@@ -267,6 +268,9 @@ char16_t *xstr8_to_path(const char *str8) {
|
||||
void mangle_stub_cmdline(char16_t *cmdline) {
|
||||
char16_t *p = cmdline;
|
||||
|
||||
if (!cmdline)
|
||||
return;
|
||||
|
||||
for (; *cmdline != '\0'; cmdline++)
|
||||
/* Convert ASCII control characters to spaces. */
|
||||
if (*cmdline <= 0x1F)
|
||||
@@ -665,3 +669,26 @@ void *find_configuration_table(const EFI_GUID *guid) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path) {
|
||||
if (!file_path)
|
||||
return NULL;
|
||||
|
||||
/* A device path is allowed to have more than one file path node. If that is the case they are
|
||||
* supposed to be concatenated. Unfortunately, the device path to text protocol simply converts the
|
||||
* nodes individually and then combines those with the usual '/' for device path nodes. But this does
|
||||
* not create a legal EFI file path that the file protocol can use. */
|
||||
|
||||
/* Make sure we really only got file paths. */
|
||||
for (const EFI_DEVICE_PATH *node = file_path; !device_path_is_end(node);
|
||||
node = device_path_next_node(node))
|
||||
if (node->Type != MEDIA_DEVICE_PATH || node->SubType != MEDIA_FILEPATH_DP)
|
||||
return NULL;
|
||||
|
||||
_cleanup_free_ char16_t *file_path_str = NULL;
|
||||
if (device_path_to_str(file_path, &file_path_str) != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
convert_efi_path(file_path_str);
|
||||
return xasprintf("%ls.extra.d", file_path_str);
|
||||
}
|
||||
|
||||
@@ -212,3 +212,5 @@ static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) {
|
||||
}
|
||||
|
||||
void *find_configuration_table(const EFI_GUID *guid);
|
||||
|
||||
char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path);
|
||||
|
||||
@@ -83,6 +83,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --initrd=PATH Path to initrd image file %7$s .initrd\n"
|
||||
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||
" --dtb=PATH Path to Devicetree file %7$s .dtb\n"
|
||||
" --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
@@ -122,6 +123,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_INITRD,
|
||||
ARG_SPLASH,
|
||||
ARG_DTB,
|
||||
ARG_UNAME,
|
||||
_ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */
|
||||
_ARG_SECTION_LAST,
|
||||
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
||||
@@ -144,6 +146,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "initrd", required_argument, NULL, ARG_INITRD },
|
||||
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||
{ "uname", required_argument, NULL, ARG_UNAME },
|
||||
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
||||
{ "current", no_argument, NULL, 'c' },
|
||||
{ "bank", required_argument, NULL, ARG_BANK },
|
||||
|
||||
@@ -11,6 +11,7 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
|
||||
[UNIFIED_SECTION_INITRD] = ".initrd",
|
||||
[UNIFIED_SECTION_SPLASH] = ".splash",
|
||||
[UNIFIED_SECTION_DTB] = ".dtb",
|
||||
[UNIFIED_SECTION_UNAME] = ".uname",
|
||||
[UNIFIED_SECTION_PCRSIG] = ".pcrsig",
|
||||
[UNIFIED_SECTION_PCRPKEY] = ".pcrpkey",
|
||||
NULL,
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef enum UnifiedSection {
|
||||
UNIFIED_SECTION_INITRD,
|
||||
UNIFIED_SECTION_SPLASH,
|
||||
UNIFIED_SECTION_DTB,
|
||||
UNIFIED_SECTION_UNAME,
|
||||
UNIFIED_SECTION_PCRSIG,
|
||||
UNIFIED_SECTION_PCRPKEY,
|
||||
_UNIFIED_SECTION_MAX,
|
||||
|
||||
+18
-3
@@ -658,10 +658,10 @@ def make_uki(opts):
|
||||
('.osrel', opts.os_release, True ),
|
||||
('.cmdline', opts.cmdline, True ),
|
||||
('.dtb', opts.devicetree, True ),
|
||||
('.uname', opts.uname, True ),
|
||||
('.splash', opts.splash, True ),
|
||||
('.pcrpkey', pcrpkey, True ),
|
||||
('.initrd', initrd, True ),
|
||||
('.uname', opts.uname, False),
|
||||
|
||||
# linux shall be last to leave breathing room for decompression.
|
||||
# We'll add it later.
|
||||
@@ -679,10 +679,12 @@ def make_uki(opts):
|
||||
|
||||
call_systemd_measure(uki, linux, opts=opts)
|
||||
|
||||
# UKI creation
|
||||
# UKI or addon creation - addons don't use the stub so we add SBAT manually
|
||||
|
||||
if linux is not None:
|
||||
uki.add_section(Section.create('.linux', linux, measure=True))
|
||||
elif opts.sbat:
|
||||
uki.add_section(Section.create('.sbat', opts.sbat, measure=False))
|
||||
|
||||
if sign_args_present:
|
||||
unsigned = tempfile.NamedTemporaryFile(prefix='uki')
|
||||
@@ -927,6 +929,16 @@ CONFIG_ITEMS = [
|
||||
config_key = 'UKI/Stub',
|
||||
),
|
||||
|
||||
ConfigItem(
|
||||
'--sbat',
|
||||
metavar = 'TEXT|@PATH',
|
||||
help = 'SBAT policy [.sbat section] for addons',
|
||||
default = """sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
uki.addon,1,UKI Addon,uki.addon,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html
|
||||
""",
|
||||
config_key = 'Addon/SBAT',
|
||||
),
|
||||
|
||||
ConfigItem(
|
||||
'--section',
|
||||
dest = 'sections',
|
||||
@@ -1141,7 +1153,10 @@ def finalize_options(opts):
|
||||
opts.efi_arch = guess_efi_arch()
|
||||
|
||||
if opts.stub is None:
|
||||
opts.stub = pathlib.Path(f'/usr/lib/systemd/boot/efi/linux{opts.efi_arch}.efi.stub')
|
||||
if opts.linux is not None:
|
||||
opts.stub = pathlib.Path(f'/usr/lib/systemd/boot/efi/linux{opts.efi_arch}.efi.stub')
|
||||
else:
|
||||
opts.stub = pathlib.Path(f'/usr/lib/systemd/boot/efi/addon{opts.efi_arch}.efi.stub')
|
||||
|
||||
if opts.signing_engine is None:
|
||||
if opts.sb_key:
|
||||
|
||||
Reference in New Issue
Block a user