mirror of
https://github.com/systemd/systemd.git
synced 2025-02-23 13:57:33 +03:00
stub: Add support for .ucode EFI addons
This extends #31872 to also load microcode from addon files.
This commit is contained in:
parent
cd8eb9605f
commit
fc31d929c7
@ -120,6 +120,16 @@ Devicetree addons are measured individually as a tagged event.
|
|||||||
|
|
||||||
→ **Measured hash** covers the content of the Devicetree.
|
→ **Measured hash** covers the content of the Devicetree.
|
||||||
|
|
||||||
|
### PCR 12, `EV_EVENT_TAG`, "Ucode addons"
|
||||||
|
|
||||||
|
Ucode addons are measured individually as a tagged event.
|
||||||
|
|
||||||
|
→ **Event Tag** `0xdac08e1a`
|
||||||
|
|
||||||
|
→ **Description** the addon filename.
|
||||||
|
|
||||||
|
→ **Measured hash** covers the contents of the ucode initrd.
|
||||||
|
|
||||||
### PCR 12, `EV_IPL`, "Per-UKI Credentials initrd"
|
### PCR 12, `EV_IPL`, "Per-UKI Credentials initrd"
|
||||||
|
|
||||||
→ **Description** in the event log record is the constant string "Credentials
|
→ **Description** in the event log record is the constant string "Credentials
|
||||||
|
@ -182,10 +182,10 @@
|
|||||||
|
|
||||||
<listitem><para>Similarly, files
|
<listitem><para>Similarly, files
|
||||||
<filename><replaceable>foo</replaceable>.efi.extra.d/*.addon.efi</filename> are loaded and verified as
|
<filename><replaceable>foo</replaceable>.efi.extra.d/*.addon.efi</filename> are loaded and verified as
|
||||||
PE binaries, and a <literal>.cmdline</literal> section is parsed from them. Addons are supposed to be
|
PE binaries, and a <literal>.cmdline</literal> or <literal>.ucode</literal> section is parsed from them.
|
||||||
used to pass additional kernel command line parameters or Devicetree blobs, regardless of the kernel
|
Addons are supposed to be used to pass additional kernel command line parameters, or Devicetree blobs,
|
||||||
image being booted, for example to allow platform vendors to ship platform-specific
|
and microcode updates, regardless of the kernel image being booted, for example to allow platform vendors
|
||||||
configuration.</para>
|
to ship platform-specific configuration.</para>
|
||||||
|
|
||||||
<para>In case Secure Boot is enabled, these files will be validated using keys in UEFI DB, Shim's DB or
|
<para>In case Secure Boot is enabled, these files will be validated using keys in UEFI DB, Shim's DB or
|
||||||
Shim's MOK, and will be rejected otherwise. Additionally, if both the addon and the UKI contain a
|
Shim's MOK, and will be rejected otherwise. Additionally, if both the addon and the UKI contain a
|
||||||
@ -199,7 +199,9 @@
|
|||||||
<para>Addon files are sorted, loaded, and measured into TPM PCR 12 (if a TPM is present) and appended
|
<para>Addon files are sorted, loaded, and measured into TPM PCR 12 (if a TPM is present) and appended
|
||||||
to the kernel command line. UKI command line options are listed first, then options from addons in
|
to the kernel command line. UKI command line options are listed first, then options from addons in
|
||||||
<filename>/loader/addons/*.addon.efi</filename>, and finally UKI-specific addons. Device tree blobs are
|
<filename>/loader/addons/*.addon.efi</filename>, and finally UKI-specific addons. Device tree blobs are
|
||||||
loaded and measured following the same algorithm. Addons are always loaded in the same order based on
|
loaded and measured following the same algorithm. Microcode addons are passed to the kernel in inverse
|
||||||
|
order (UKI specific addons, global addons, UKI embedded section). This is because the microcode update
|
||||||
|
driver stops on the first matching filename. Addons are always loaded in the same order based on
|
||||||
the filename, so that, given the same set of addons, the same set of measurements can be expected in
|
the filename, so that, given the same set of addons, the same set of measurements can be expected in
|
||||||
PCR12. However, note that the filename is not protected by the PE signature, and as such an attacker
|
PCR12. However, note that the filename is not protected by the PE signature, and as such an attacker
|
||||||
with write access to the ESP could potentially rename these files to change the order in which they are
|
with write access to the ESP could potentially rename these files to change the order in which they are
|
||||||
@ -215,9 +217,10 @@
|
|||||||
measured into TPM PCR 12 (if a TPM is present).</para></listitem>
|
measured into TPM PCR 12 (if a TPM is present).</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Additionally, files <filename>/loader/addons/*.addon.efi</filename> are loaded and
|
<listitem><para>Additionally, files <filename>/loader/addons/*.addon.efi</filename> are loaded and
|
||||||
verified as PE binaries, and <literal>.cmdline</literal> and/or <literal>.dtb</literal> sections are
|
verified as PE binaries, and <literal>.cmdline</literal>, <literal>.dtb</literal> and/or
|
||||||
parsed from them. This is supposed to be used to pass additional command line parameters or Devicetree
|
<literal>.ucode</literal>sections are parsed from them. This is supposed to be used to pass additional
|
||||||
blobs to the kernel, regardless of the kernel being booted.</para></listitem>
|
command line parameters, Devicetree blobs and microcode updates to the kernel, regardless of the
|
||||||
|
kernel being booted.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>These mechanisms may be used to parameterize and extend trusted (i.e. signed), immutable initrd
|
<para>These mechanisms may be used to parameterize and extend trusted (i.e. signed), immutable initrd
|
||||||
|
@ -104,7 +104,6 @@ static EFI_STATUS combine_initrds(
|
|||||||
|
|
||||||
FOREACH_ARRAY(i, initrds, n_initrds) {
|
FOREACH_ARRAY(i, initrds, n_initrds) {
|
||||||
/* some initrds (the ones from UKI sections) need padding, pad all to be safe */
|
/* some initrds (the ones from UKI sections) need padding, pad all to be safe */
|
||||||
|
|
||||||
size_t initrd_size = ALIGN4(i->iov_len);
|
size_t initrd_size = ALIGN4(i->iov_len);
|
||||||
if (n > SIZE_MAX - initrd_size)
|
if (n > SIZE_MAX - initrd_size)
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
@ -298,30 +297,30 @@ static void cmdline_append_and_measure_addons(
|
|||||||
*cmdline_append = xasprintf("%ls %ls", tmp, copy);
|
*cmdline_append = xasprintf("%ls %ls", tmp, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct DevicetreeAddon {
|
typedef struct NamedAddon {
|
||||||
char16_t *filename;
|
char16_t *filename;
|
||||||
struct iovec blob;
|
struct iovec blob;
|
||||||
} DevicetreeAddon;
|
} NamedAddon;
|
||||||
|
|
||||||
static void devicetree_addon_done(DevicetreeAddon *a) {
|
static void named_addon_done(NamedAddon *a) {
|
||||||
assert(a);
|
assert(a);
|
||||||
|
|
||||||
a->filename = mfree(a->filename);
|
a->filename = mfree(a->filename);
|
||||||
iovec_done(&a->blob);
|
iovec_done(&a->blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void devicetree_addon_free_many(DevicetreeAddon *a, size_t n) {
|
static void named_addon_free_many(NamedAddon *a, size_t n) {
|
||||||
assert(a || n == 0);
|
assert(a || n == 0);
|
||||||
|
|
||||||
FOREACH_ARRAY(i, a, n)
|
FOREACH_ARRAY(i, a, n)
|
||||||
devicetree_addon_done(i);
|
named_addon_done(i);
|
||||||
|
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void install_addon_devicetrees(
|
static void install_addon_devicetrees(
|
||||||
struct devicetree_state *dt_state,
|
struct devicetree_state *dt_state,
|
||||||
DevicetreeAddon *addons,
|
NamedAddon *addons,
|
||||||
size_t n_addons,
|
size_t n_addons,
|
||||||
int *parameters_measured) {
|
int *parameters_measured) {
|
||||||
|
|
||||||
@ -357,14 +356,78 @@ static void install_addon_devicetrees(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void iovec_array_extend(struct iovec **arr, size_t *n_arr, struct iovec elem) {
|
||||||
|
assert(arr);
|
||||||
|
assert(n_arr);
|
||||||
|
|
||||||
|
if (!iovec_is_set(&elem))
|
||||||
|
return;
|
||||||
|
|
||||||
|
*arr = xrealloc(*arr, *n_arr * sizeof(struct iovec), (*n_arr + 1) * sizeof(struct iovec));
|
||||||
|
(*arr)[(*n_arr)++] = elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void measure_and_append_ucode_addons(
|
||||||
|
struct iovec **all_initrds,
|
||||||
|
size_t *n_all_initrds,
|
||||||
|
NamedAddon *ucode_addons,
|
||||||
|
size_t n_ucode_addons,
|
||||||
|
int *sections_measured) {
|
||||||
|
|
||||||
|
EFI_STATUS err;
|
||||||
|
|
||||||
|
assert(all_initrds);
|
||||||
|
assert(n_all_initrds);
|
||||||
|
assert(ucode_addons || n_ucode_addons == 0);
|
||||||
|
assert(sections_measured);
|
||||||
|
|
||||||
|
/* Ucode addons need to be measured and copied into all_initrds in reverse order,
|
||||||
|
* the kernel takes the first one it finds. */
|
||||||
|
for (ssize_t i = n_ucode_addons - 1; i >= 0; i--) {
|
||||||
|
bool m = false;
|
||||||
|
err = tpm_log_tagged_event(
|
||||||
|
TPM2_PCR_KERNEL_CONFIG,
|
||||||
|
POINTER_TO_PHYSICAL_ADDRESS(ucode_addons[i].blob.iov_base),
|
||||||
|
ucode_addons[i].blob.iov_len,
|
||||||
|
UCODE_ADDON_EVENT_TAG_ID,
|
||||||
|
ucode_addons[i].filename,
|
||||||
|
&m);
|
||||||
|
if (err != EFI_SUCCESS)
|
||||||
|
return (void) log_error_status(
|
||||||
|
err,
|
||||||
|
"Unable to extend PCR %i with UCODE addon '%ls': %m",
|
||||||
|
TPM2_PCR_KERNEL_CONFIG,
|
||||||
|
ucode_addons[i].filename);
|
||||||
|
|
||||||
|
combine_measured_flag(sections_measured, m);
|
||||||
|
|
||||||
|
iovec_array_extend(all_initrds, n_all_initrds, ucode_addons[i].blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void extend_initrds(
|
||||||
|
struct iovec initrds[static _INITRD_MAX],
|
||||||
|
struct iovec **all_initrds,
|
||||||
|
size_t *n_all_initrds) {
|
||||||
|
|
||||||
|
assert(initrds);
|
||||||
|
assert(all_initrds);
|
||||||
|
assert(n_all_initrds);
|
||||||
|
|
||||||
|
FOREACH_ARRAY(i, initrds, _INITRD_MAX)
|
||||||
|
iovec_array_extend(all_initrds, n_all_initrds, *i);
|
||||||
|
}
|
||||||
|
|
||||||
static EFI_STATUS load_addons(
|
static EFI_STATUS load_addons(
|
||||||
EFI_HANDLE stub_image,
|
EFI_HANDLE stub_image,
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||||
const char16_t *prefix,
|
const char16_t *prefix,
|
||||||
const char *uname,
|
const char *uname,
|
||||||
char16_t **cmdline, /* Both input+output, extended with new addons we find */
|
char16_t **cmdline, /* Both input+output, extended with new addons we find */
|
||||||
DevicetreeAddon **devicetree_addons, /* Ditto */
|
NamedAddon **devicetree_addons, /* Ditto */
|
||||||
size_t *n_devicetree_addons) {
|
size_t *n_devicetree_addons,
|
||||||
|
NamedAddon **ucode_addons, /* Ditto */
|
||||||
|
size_t *n_ucode_addons) {
|
||||||
|
|
||||||
_cleanup_(strv_freep) char16_t **items = NULL;
|
_cleanup_(strv_freep) char16_t **items = NULL;
|
||||||
_cleanup_(file_closep) EFI_FILE *root = NULL;
|
_cleanup_(file_closep) EFI_FILE *root = NULL;
|
||||||
@ -429,11 +492,12 @@ static EFI_STATUS load_addons(
|
|||||||
err = pe_memory_locate_sections(loaded_addon->ImageBase, unified_sections, sections);
|
err = pe_memory_locate_sections(loaded_addon->ImageBase, unified_sections, sections);
|
||||||
if (err != EFI_SUCCESS ||
|
if (err != EFI_SUCCESS ||
|
||||||
(!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE) &&
|
(!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE) &&
|
||||||
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB))) {
|
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB) &&
|
||||||
|
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE))) {
|
||||||
if (err == EFI_SUCCESS)
|
if (err == EFI_SUCCESS)
|
||||||
err = EFI_NOT_FOUND;
|
err = EFI_NOT_FOUND;
|
||||||
log_error_status(err,
|
log_error_status(err,
|
||||||
"Unable to locate embedded .cmdline/.dtb sections in %ls, ignoring: %m",
|
"Unable to locate embedded .cmdline/.dtb/.ucode sections in %ls, ignoring: %m",
|
||||||
items[i]);
|
items[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -463,10 +527,10 @@ static EFI_STATUS load_addons(
|
|||||||
|
|
||||||
if (devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) {
|
if (devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) {
|
||||||
*devicetree_addons = xrealloc(*devicetree_addons,
|
*devicetree_addons = xrealloc(*devicetree_addons,
|
||||||
*n_devicetree_addons * sizeof(DevicetreeAddon),
|
*n_devicetree_addons * sizeof(NamedAddon),
|
||||||
(*n_devicetree_addons + 1) * sizeof(DevicetreeAddon));
|
(*n_devicetree_addons + 1) * sizeof(NamedAddon));
|
||||||
|
|
||||||
(*devicetree_addons)[(*n_devicetree_addons)++] = (DevicetreeAddon) {
|
(*devicetree_addons)[(*n_devicetree_addons)++] = (NamedAddon) {
|
||||||
.blob = {
|
.blob = {
|
||||||
.iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, sections[UNIFIED_SECTION_DTB].size),
|
.iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, sections[UNIFIED_SECTION_DTB].size),
|
||||||
.iov_len = sections[UNIFIED_SECTION_DTB].size,
|
.iov_len = sections[UNIFIED_SECTION_DTB].size,
|
||||||
@ -474,6 +538,19 @@ static EFI_STATUS load_addons(
|
|||||||
.filename = xstrdup16(items[i]),
|
.filename = xstrdup16(items[i]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ucode_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE)) {
|
||||||
|
*ucode_addons = xrealloc(*ucode_addons,
|
||||||
|
*n_ucode_addons * sizeof(NamedAddon),
|
||||||
|
(*n_ucode_addons + 1) * sizeof(NamedAddon));
|
||||||
|
(*ucode_addons)[(*n_ucode_addons)++] = (NamedAddon) {
|
||||||
|
.blob = {
|
||||||
|
.iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_UCODE].memory_offset, sections[UNIFIED_SECTION_UCODE].size),
|
||||||
|
.iov_len = sections[UNIFIED_SECTION_UCODE].size,
|
||||||
|
},
|
||||||
|
.filename = xstrdup16(items[i]),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
@ -587,23 +664,6 @@ static void initrds_free(struct iovec (*initrds)[_INITRD_MAX]) {
|
|||||||
iovec_done((*initrds) + i);
|
iovec_done((*initrds) + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool initrds_need_combine(struct iovec initrds[static _INITRD_MAX]) {
|
|
||||||
assert(initrds);
|
|
||||||
|
|
||||||
/* Returns true if we have any initrds set that aren't the base initrd. In that case we need to
|
|
||||||
* merge, otherwise we can pass the embedded initrd as is */
|
|
||||||
|
|
||||||
for (size_t i = 0; i < _INITRD_MAX; i++) {
|
|
||||||
if (i == INITRD_BASE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (iovec_is_set(initrds + i))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generate_sidecar_initrds(
|
static void generate_sidecar_initrds(
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||||
struct iovec initrds[static _INITRD_MAX],
|
struct iovec initrds[static _INITRD_MAX],
|
||||||
@ -782,8 +842,10 @@ static void load_all_addons(
|
|||||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||||
const char *uname,
|
const char *uname,
|
||||||
char16_t **cmdline_addons,
|
char16_t **cmdline_addons,
|
||||||
DevicetreeAddon **dt_addons,
|
NamedAddon **dt_addons,
|
||||||
size_t *n_dt_addons) {
|
size_t *n_dt_addons,
|
||||||
|
NamedAddon **ucode_addons,
|
||||||
|
size_t *n_ucode_addons) {
|
||||||
|
|
||||||
EFI_STATUS err;
|
EFI_STATUS err;
|
||||||
|
|
||||||
@ -791,6 +853,8 @@ static void load_all_addons(
|
|||||||
assert(cmdline_addons);
|
assert(cmdline_addons);
|
||||||
assert(dt_addons);
|
assert(dt_addons);
|
||||||
assert(n_dt_addons);
|
assert(n_dt_addons);
|
||||||
|
assert(ucode_addons);
|
||||||
|
assert(n_ucode_addons);
|
||||||
|
|
||||||
err = load_addons(
|
err = load_addons(
|
||||||
image,
|
image,
|
||||||
@ -799,7 +863,9 @@ static void load_all_addons(
|
|||||||
uname,
|
uname,
|
||||||
cmdline_addons,
|
cmdline_addons,
|
||||||
dt_addons,
|
dt_addons,
|
||||||
n_dt_addons);
|
n_dt_addons,
|
||||||
|
ucode_addons,
|
||||||
|
n_ucode_addons);
|
||||||
if (err != EFI_SUCCESS)
|
if (err != EFI_SUCCESS)
|
||||||
log_error_status(err, "Error loading global addons, ignoring: %m");
|
log_error_status(err, "Error loading global addons, ignoring: %m");
|
||||||
|
|
||||||
@ -815,7 +881,9 @@ static void load_all_addons(
|
|||||||
uname,
|
uname,
|
||||||
cmdline_addons,
|
cmdline_addons,
|
||||||
dt_addons,
|
dt_addons,
|
||||||
n_dt_addons);
|
n_dt_addons,
|
||||||
|
ucode_addons,
|
||||||
|
n_ucode_addons);
|
||||||
if (err != EFI_SUCCESS)
|
if (err != EFI_SUCCESS)
|
||||||
log_error_status(err, "Error loading UKI-specific addons, ignoring: %m");
|
log_error_status(err, "Error loading UKI-specific addons, ignoring: %m");
|
||||||
}
|
}
|
||||||
@ -863,8 +931,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
|||||||
PeSectionVector sections[ELEMENTSOF(unified_sections)] = {};
|
PeSectionVector sections[ELEMENTSOF(unified_sections)] = {};
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
|
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
|
||||||
_cleanup_free_ char *uname = NULL;
|
_cleanup_free_ char *uname = NULL;
|
||||||
DevicetreeAddon *dt_addons = NULL;
|
NamedAddon *dt_addons = NULL, *ucode_addons = NULL;
|
||||||
size_t n_dt_addons = 0;
|
size_t n_dt_addons = 0, n_ucode_addons = 0;
|
||||||
|
_cleanup_free_ struct iovec *all_initrds = NULL;
|
||||||
|
size_t n_all_initrds = 0;
|
||||||
EFI_STATUS err;
|
EFI_STATUS err;
|
||||||
|
|
||||||
err = BS->HandleProtocol(image, MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL), (void **) &loaded_image);
|
err = BS->HandleProtocol(image, MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL), (void **) &loaded_image);
|
||||||
@ -890,8 +960,9 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
|||||||
|
|
||||||
/* Now that we have the UKI sections loaded, also load global first and then local (per-UKI)
|
/* Now that we have the UKI sections loaded, also load global first and then local (per-UKI)
|
||||||
* addons. The data is loaded at once, and then used later. */
|
* addons. The data is loaded at once, and then used later. */
|
||||||
CLEANUP_ARRAY(dt_addons, n_dt_addons, devicetree_addon_free_many);
|
CLEANUP_ARRAY(dt_addons, n_dt_addons, named_addon_free_many);
|
||||||
load_all_addons(image, loaded_image, uname, &cmdline_addons, &dt_addons, &n_dt_addons);
|
CLEANUP_ARRAY(ucode_addons, n_ucode_addons, named_addon_free_many);
|
||||||
|
load_all_addons(image, loaded_image, uname, &cmdline_addons, &dt_addons, &n_dt_addons, &ucode_addons, &n_ucode_addons);
|
||||||
|
|
||||||
/* If we have any extra command line to add via PE addons, load them now and append, and measure the
|
/* If we have any extra command line to add via PE addons, load them now and append, and measure the
|
||||||
* additions together, after the embedded options, but before the smbios ones, so that the order is
|
* additions together, after the embedded options, but before the smbios ones, so that the order is
|
||||||
@ -912,16 +983,20 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
|||||||
generate_embedded_initrds(loaded_image, sections, initrds);
|
generate_embedded_initrds(loaded_image, sections, initrds);
|
||||||
lookup_embedded_initrds(loaded_image, sections, initrds);
|
lookup_embedded_initrds(loaded_image, sections, initrds);
|
||||||
|
|
||||||
|
/* Measures ucode addons and puts them into all_initrds */
|
||||||
|
measure_and_append_ucode_addons(&all_initrds, &n_all_initrds, ucode_addons, n_ucode_addons, ¶meters_measured);
|
||||||
|
/* Adds all other initrds to all_initrds */
|
||||||
|
extend_initrds(initrds, &all_initrds, &n_all_initrds);
|
||||||
|
|
||||||
/* Export variables indicating what we measured */
|
/* Export variables indicating what we measured */
|
||||||
export_pcr_variables(sections_measured, parameters_measured, sysext_measured, confext_measured);
|
export_pcr_variables(sections_measured, parameters_measured, sysext_measured, confext_measured);
|
||||||
|
|
||||||
/* Combine the initrds into one */
|
/* Combine the initrds into one */
|
||||||
_cleanup_pages_ Pages initrd_pages = {};
|
_cleanup_pages_ Pages initrd_pages = {};
|
||||||
struct iovec final_initrd;
|
struct iovec final_initrd;
|
||||||
if (initrds_need_combine(initrds)) {
|
if (n_all_initrds > 1) {
|
||||||
/* If we have generated initrds dynamically or there is a microcode initrd, combine them with
|
/* There will always be a base initrd, if this counter is higher, we need to combine them */
|
||||||
* the built-in initrd. */
|
err = combine_initrds(all_initrds, n_all_initrds, &initrd_pages, &final_initrd.iov_len);
|
||||||
err = combine_initrds(initrds, _INITRD_MAX, &initrd_pages, &final_initrd.iov_len);
|
|
||||||
if (err != EFI_SUCCESS)
|
if (err != EFI_SUCCESS)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -930,7 +1005,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
|||||||
/* Given these might be large let's free them explicitly before we pass control to Linux */
|
/* Given these might be large let's free them explicitly before we pass control to Linux */
|
||||||
initrds_free(&initrds);
|
initrds_free(&initrds);
|
||||||
} else
|
} else
|
||||||
final_initrd = initrds[INITRD_BASE];
|
final_initrd = all_initrds[0];
|
||||||
|
|
||||||
struct iovec kernel = IOVEC_MAKE(
|
struct iovec kernel = IOVEC_MAKE(
|
||||||
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_LINUX].memory_offset,
|
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_LINUX].memory_offset,
|
||||||
|
@ -49,3 +49,6 @@ enum {
|
|||||||
|
|
||||||
/* The tag used for EV_EVENT_TAG event log records covering Devicetree blobs */
|
/* The tag used for EV_EVENT_TAG event log records covering Devicetree blobs */
|
||||||
#define DEVICETREE_ADDON_EVENT_TAG_ID UINT32_C(0x6c46f751)
|
#define DEVICETREE_ADDON_EVENT_TAG_ID UINT32_C(0x6c46f751)
|
||||||
|
|
||||||
|
/* The tag used for EV_EVENT_TAG event log records covering ucode addons (effectively initrds) */
|
||||||
|
#define UCODE_ADDON_EVENT_TAG_ID UINT32_C(0xdac08e1a)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user