efi: introduce PeSectionVector structure, and use it for referencing PE sections

This commit is contained in:
Lennart Poettering
2024-06-26 17:09:44 +02:00
parent 9e63e28aa6
commit fb974ac485
4 changed files with 164 additions and 97 deletions
+25 -13
View File
@@ -1855,23 +1855,24 @@ static void generate_boot_entry_titles(Config *config) {
}
static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) {
EFI_STATUS err;
static const char * const sections[] = {
".sdmagic",
NULL
};
size_t offset = 0, size = 0, read;
_cleanup_free_ char *content = NULL;
PeSectionVector vector = {};
EFI_STATUS err;
size_t read;
assert(root_dir);
assert(loader_path);
err = pe_file_locate_sections(root_dir, loader_path, sections, &offset, &size);
if (err != EFI_SUCCESS || size != sizeof(SD_MAGIC))
err = pe_file_locate_sections(root_dir, loader_path, sections, &vector);
if (err != EFI_SUCCESS || vector.size != sizeof(SD_MAGIC))
return false;
err = file_read(root_dir, loader_path, offset, size, &content, &read);
if (err != EFI_SUCCESS || size != read)
err = file_read(root_dir, loader_path, vector.file_offset, vector.size, &content, &read);
if (err != EFI_SUCCESS || vector.size != read)
return false;
return memcmp(content, SD_MAGIC, sizeof(SD_MAGIC)) == 0;
@@ -2104,7 +2105,7 @@ static void config_load_type2_entries(
_SECTION_MAX,
};
static const char * const sections[_SECTION_MAX + 1] = {
static const char * const section_names[_SECTION_MAX + 1] = {
[SECTION_CMDLINE] = ".cmdline",
[SECTION_OSREL] = ".osrel",
NULL,
@@ -2114,8 +2115,9 @@ static void config_load_type2_entries(
*os_image_version = NULL, *os_version = NULL, *os_version_id = NULL, *os_build_id = NULL;
const char16_t *good_name, *good_version, *good_sort_key;
_cleanup_free_ char *content = NULL;
size_t offs[_SECTION_MAX] = {}, szs[_SECTION_MAX] = {}, pos = 0;
PeSectionVector sections[_SECTION_MAX] = {};
char *line, *key, *value;
size_t pos = 0;
err = readdir(linux_dir, &f, &f_size);
if (err != EFI_SUCCESS || !f)
@@ -2131,11 +2133,16 @@ static void config_load_type2_entries(
continue;
/* look for .osrel and .cmdline sections in the .efi binary */
err = pe_file_locate_sections(linux_dir, f->FileName, sections, offs, szs);
if (err != EFI_SUCCESS || szs[SECTION_OSREL] == 0)
err = pe_file_locate_sections(linux_dir, f->FileName, section_names, sections);
if (err != EFI_SUCCESS || !PE_SECTION_VECTOR_IS_SET(sections + SECTION_OSREL))
continue;
err = file_read(linux_dir, f->FileName, offs[SECTION_OSREL], szs[SECTION_OSREL], &content, NULL);
err = file_read(linux_dir,
f->FileName,
sections[SECTION_OSREL].file_offset,
sections[SECTION_OSREL].size,
&content,
NULL);
if (err != EFI_SUCCESS)
continue;
@@ -2206,14 +2213,19 @@ static void config_load_type2_entries(
config_add_entry(config, entry);
boot_entry_parse_tries(entry, u"\\EFI\\Linux", f->FileName, u".efi");
if (szs[SECTION_CMDLINE] == 0)
if (!PE_SECTION_VECTOR_IS_SET(sections + SECTION_CMDLINE))
continue;
content = mfree(content);
/* read the embedded cmdline file */
size_t cmdline_len;
err = file_read(linux_dir, f->FileName, offs[SECTION_CMDLINE], szs[SECTION_CMDLINE], &content, &cmdline_len);
err = file_read(linux_dir,
f->FileName,
sections[SECTION_CMDLINE].file_offset,
sections[SECTION_CMDLINE].size,
&content,
&cmdline_len);
if (err == EFI_SUCCESS) {
entry->options = xstrn8_to_16(content, cmdline_len);
mangle_stub_cmdline(entry->options);
+72 -35
View File
@@ -101,7 +101,7 @@ typedef struct PeOptionalHeader {
} _packed_ PeOptionalHeader;
typedef struct PeFileHeader {
uint8_t Magic[4];
uint8_t Magic[4];
CoffFileHeader FileHeader;
PeOptionalHeader OptionalHeader;
} _packed_ PeFileHeader;
@@ -175,48 +175,78 @@ static bool pe_section_name_equal(const char *a, const char *b) {
return true;
}
static void locate_sections(
static void pe_locate_sections(
const PeSectionHeader section_table[],
size_t n_table,
size_t n_section_table,
const char * const sections[],
size_t *offsets,
size_t *sizes,
bool in_memory) {
size_t validate_base,
PeSectionVector *ret_sections) {
assert(section_table);
assert(section_table || n_section_table == 0);
assert(sections);
assert(offsets);
assert(sizes);
assert(ret_sections);
for (size_t i = 0; i < n_table; i++) {
const PeSectionHeader *sect = section_table + i;
/* Searches for the sections listed in 'sections[]' within the section table. Validates the resulted
* data. If 'validate_base' is non-zero also takes base offset when loaded into memory into account for
* qchecking for overflows. */
for (size_t j = 0; sections[j]; j++) {
if (!pe_section_name_equal((const char*) sect->Name, sections[j]))
for (size_t i = 0; sections[i]; i++)
FOREACH_ARRAY(j, section_table, n_section_table) {
if (!pe_section_name_equal((const char*) j->Name, sections[i]))
continue;
offsets[j] = in_memory ? sect->VirtualAddress : sect->PointerToRawData;
sizes[j] = sect->VirtualSize;
/* Overflow check: ignore sections that are impossibly large, relative to the file
* address for the section. */
size_t size_max = SIZE_MAX - j->PointerToRawData;
if ((size_t) j->VirtualSize > size_max)
continue;
/* Overflow check: ignore sections that are impossibly large, given the virtual
* address for the section */
size_max = SIZE_MAX - j->VirtualAddress;
if (j->VirtualSize > size_max)
continue;
/* 2nd overflow check: ignore sections that are impossibly large also taking the
* loaded base into account. */
if (validate_base != 0) {
if (validate_base > size_max)
continue;
size_max -= validate_base;
if (j->VirtualAddress > size_max)
continue;
}
/* At this time, the sizes and offsets have been validated. Store them away */
ret_sections[i] = (PeSectionVector) {
.size = j->VirtualSize,
.file_offset = j->PointerToRawData,
.memory_offset = j->VirtualAddress,
};
/* First matching section wins, ignore the rest */
break;
}
}
}
static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const PeFileHeader *pe) {
size_t addr = 0, size = 0;
static const char *sections[] = { ".compat", NULL };
PeSectionVector vector = {};
/* The kernel may provide alternative PE entry points for different PE architectures. This allows
* booting a 64-bit kernel on 32-bit EFI that is otherwise running on a 64-bit CPU. The locations of any
* such compat entry points are located in a special PE section. */
locate_sections((const PeSectionHeader *) ((const uint8_t *) dos + section_table_offset(dos, pe)),
pe_locate_sections(
(const PeSectionHeader *) ((const uint8_t *) dos + section_table_offset(dos, pe)),
pe->FileHeader.NumberOfSections,
sections,
&addr,
&size,
/*in_memory=*/true);
PTR_TO_SIZE(dos),
&vector);
if (size == 0)
if (vector.size == 0) /* not found */
return 0;
typedef struct {
@@ -226,6 +256,8 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
uint32_t entry_point;
} _packed_ LinuxPeCompat1;
size_t addr = vector.memory_offset, size = vector.size;
while (size >= sizeof(LinuxPeCompat1) && addr % alignof(LinuxPeCompat1) == 0) {
LinuxPeCompat1 *compat = (LinuxPeCompat1 *) ((uint8_t *) dos + addr);
@@ -274,15 +306,18 @@ EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address) {
return EFI_SUCCESS;
}
EFI_STATUS pe_memory_locate_sections(const void *base, const char * const sections[], size_t *addrs, size_t *sizes) {
EFI_STATUS pe_memory_locate_sections(
const void *base,
const char* const sections[],
PeSectionVector *ret_sections) {
const DosFileHeader *dos;
const PeFileHeader *pe;
size_t offset;
assert(base);
assert(sections);
assert(addrs);
assert(sizes);
assert(ret_sections);
dos = (const DosFileHeader *) base;
if (!verify_dos(dos))
@@ -293,12 +328,12 @@ EFI_STATUS pe_memory_locate_sections(const void *base, const char * const sectio
return EFI_LOAD_ERROR;
offset = section_table_offset(dos, pe);
locate_sections((PeSectionHeader *) ((uint8_t *) base + offset),
pe_locate_sections(
(const PeSectionHeader *) ((const uint8_t *) base + offset),
pe->FileHeader.NumberOfSections,
sections,
addrs,
sizes,
/*in_memory=*/true);
PTR_TO_SIZE(base),
ret_sections);
return EFI_SUCCESS;
}
@@ -307,8 +342,7 @@ EFI_STATUS pe_file_locate_sections(
EFI_FILE *dir,
const char16_t *path,
const char * const sections[],
size_t *offsets,
size_t *sizes) {
PeSectionVector *ret_sections) {
_cleanup_free_ PeSectionHeader *section_table = NULL;
_cleanup_(file_closep) EFI_FILE *handle = NULL;
DosFileHeader dos;
@@ -319,8 +353,7 @@ EFI_STATUS pe_file_locate_sections(
assert(dir);
assert(path);
assert(sections);
assert(offsets);
assert(sizes);
assert(ret_sections);
err = dir->Open(dir, &handle, (char16_t *) path, EFI_FILE_MODE_READ, 0ULL);
if (err != EFI_SUCCESS)
@@ -366,8 +399,12 @@ EFI_STATUS pe_file_locate_sections(
if (len != section_table_len)
return EFI_LOAD_ERROR;
locate_sections(section_table, pe.FileHeader.NumberOfSections,
sections, offsets, sizes, /*in_memory=*/false);
pe_locate_sections(
section_table,
pe.FileHeader.NumberOfSections,
sections,
/* validate_base= */ 0, /* don't validate base */
ret_sections);
return EFI_SUCCESS;
}
+14 -4
View File
@@ -3,17 +3,27 @@
#include "efi.h"
/* This is a subset of the full PE section header structure, with validated values, and without
* the noise. */
typedef struct PeSectionVector {
size_t size;
size_t memory_offset; /* Offset in memory, relative to base address */
uint64_t file_offset; /* Offset on disk, relative to beginning of file */
} PeSectionVector;
static inline bool PE_SECTION_VECTOR_IS_SET(const PeSectionVector *v) {
return v && v->size != 0;
}
EFI_STATUS pe_memory_locate_sections(
const void *base,
const char * const sections[],
size_t *addrs,
size_t *sizes);
PeSectionVector *ret_sections);
EFI_STATUS pe_file_locate_sections(
EFI_FILE *dir,
const char16_t *path,
const char * const sections[],
size_t *offsets,
size_t *sizes);
PeSectionVector *ret_sections);
EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address);
+53 -45
View File
@@ -413,7 +413,7 @@ static EFI_STATUS load_addons(
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] = {};
PeSectionVector sections[ELEMENTSOF(unified_sections)] = {};
_cleanup_free_ EFI_DEVICE_PATH *addon_path = NULL;
_cleanup_(unload_imagep) EFI_HANDLE addon = NULL;
EFI_LOADED_IMAGE_PROTOCOL *loaded_addon = NULL;
@@ -441,9 +441,10 @@ static EFI_STATUS load_addons(
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);
err = pe_memory_locate_sections(loaded_addon->ImageBase, unified_sections, sections);
if (err != EFI_SUCCESS ||
(szs[UNIFIED_SECTION_CMDLINE] == 0 && szs[UNIFIED_SECTION_DTB] == 0)) {
(!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE) &&
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB))) {
if (err == EFI_SUCCESS)
err = EFI_NOT_FOUND;
log_error_status(err,
@@ -453,38 +454,38 @@ static EFI_STATUS load_addons(
}
/* We want to enforce that addons are not UKIs, i.e.: they must not embed a kernel. */
if (szs[UNIFIED_SECTION_LINUX] > 0) {
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_LINUX)) {
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 &&
if (uname && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UNAME) &&
!strneq8(uname,
(char *)loaded_addon->ImageBase + addrs[UNIFIED_SECTION_UNAME],
szs[UNIFIED_SECTION_UNAME])) {
(char *)loaded_addon->ImageBase + sections[UNIFIED_SECTION_UNAME].memory_offset,
sections[UNIFIED_SECTION_UNAME].size)) {
log_error(".uname mismatch between %ls and UKI, ignoring", items[i]);
continue;
}
if (ret_cmdline && szs[UNIFIED_SECTION_CMDLINE] > 0) {
if (ret_cmdline && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE)) {
_cleanup_free_ char16_t *tmp = TAKE_PTR(cmdline),
*extra16 = xstrn8_to_16((char *)loaded_addon->ImageBase + addrs[UNIFIED_SECTION_CMDLINE],
szs[UNIFIED_SECTION_CMDLINE]);
*extra16 = xstrn8_to_16((char *)loaded_addon->ImageBase + sections[UNIFIED_SECTION_CMDLINE].memory_offset,
sections[UNIFIED_SECTION_CMDLINE].size);
cmdline = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", extra16);
}
if (ret_dt_bases && szs[UNIFIED_SECTION_DTB] > 0) {
if (ret_dt_bases && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) {
dt_sizes = xrealloc(dt_sizes,
n_dt * sizeof(size_t),
(n_dt + 1) * sizeof(size_t));
dt_sizes[n_dt] = szs[UNIFIED_SECTION_DTB];
dt_sizes[n_dt] = sections[UNIFIED_SECTION_DTB].size;
dt_bases = xrealloc(dt_bases,
n_dt * sizeof(void *),
(n_dt + 1) * sizeof(void *));
dt_bases[n_dt] = xmemdup((uint8_t*)loaded_addon->ImageBase + addrs[UNIFIED_SECTION_DTB],
dt_bases[n_dt] = xmemdup((uint8_t*)loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset,
dt_sizes[n_dt]);
dt_filenames = xrealloc(dt_filenames,
@@ -515,11 +516,11 @@ static EFI_STATUS run(EFI_HANDLE image) {
void **dt_bases_addons_global = NULL, **dt_bases_addons_uki = NULL;
char16_t **dt_filenames_addons_global = NULL, **dt_filenames_addons_uki = NULL;
_cleanup_free_ size_t *dt_sizes_addons_global = NULL, *dt_sizes_addons_uki = NULL;
size_t linux_size, initrd_size, ucode_size, dt_size, n_dts_addons_global = 0, n_dts_addons_uki = 0;
EFI_PHYSICAL_ADDRESS linux_base, initrd_base, ucode_base, dt_base;
size_t linux_size, initrd_size = 0, ucode_size = 0, dt_size = 0, n_dts_addons_global = 0, n_dts_addons_uki = 0;
EFI_PHYSICAL_ADDRESS linux_base, initrd_base = 0, ucode_base = 0, dt_base = 0;
_cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {};
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
size_t addrs[_UNIFIED_SECTION_MAX] = {}, szs[_UNIFIED_SECTION_MAX] = {};
PeSectionVector sections[ELEMENTSOF(unified_sections)] = {};
_cleanup_free_ char16_t *cmdline = NULL, *cmdline_addons_global = NULL, *cmdline_addons_uki = NULL;
int sections_measured = -1, parameters_measured = -1, sysext_measured = -1, confext_measured = -1;
_cleanup_free_ char *uname = NULL;
@@ -541,8 +542,8 @@ static EFI_STATUS run(EFI_HANDLE image) {
(void) process_random_seed(esp_dir);
}
err = pe_memory_locate_sections(loaded_image->ImageBase, unified_sections, addrs, szs);
if (err != EFI_SUCCESS || szs[UNIFIED_SECTION_LINUX] == 0) {
err = pe_memory_locate_sections(loaded_image->ImageBase, unified_sections, sections);
if (err != EFI_SUCCESS || !PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_LINUX)) {
if (err == EFI_SUCCESS)
err = EFI_NOT_FOUND;
return log_error_status(err, "Unable to locate embedded .linux section: %m");
@@ -553,9 +554,9 @@ static EFI_STATUS run(EFI_HANDLE image) {
CLEANUP_ARRAY(dt_filenames_addons_global, n_dts_addons_global, dt_filenames_free);
CLEANUP_ARRAY(dt_filenames_addons_uki, n_dts_addons_uki, dt_filenames_free);
if (szs[UNIFIED_SECTION_UNAME] > 0)
uname = xstrndup8((char *)loaded_image->ImageBase + addrs[UNIFIED_SECTION_UNAME],
szs[UNIFIED_SECTION_UNAME]);
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UNAME))
uname = xstrndup8((char *)loaded_image->ImageBase + sections[UNIFIED_SECTION_UNAME].memory_offset,
sections[UNIFIED_SECTION_UNAME].size);
/* 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. */
@@ -597,7 +598,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
if (!unified_section_measure(section)) /* shall not measure? */
continue;
if (szs[section] == 0) /* not found */
if (!PE_SECTION_VECTOR_IS_SET(sections + section)) /* not found */
continue;
/* First measure the name of the section */
@@ -614,11 +615,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
m = false;
(void) tpm_log_ipl_event_ascii(
TPM2_PCR_KERNEL_BOOT,
POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[section],
szs[section],
POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[section].memory_offset,
sections[section].size,
unified_sections[section],
&m);
combine_measured_flag(&sections_measured, m);
}
@@ -628,9 +628,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
(void) efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"StubPcrKernelImage", TPM2_PCR_KERNEL_BOOT, 0);
/* Show splash screen as early as possible */
graphics_splash((const uint8_t*) loaded_image->ImageBase + addrs[UNIFIED_SECTION_SPLASH], szs[UNIFIED_SECTION_SPLASH]);
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_SPLASH))
graphics_splash((const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_SPLASH].memory_offset, sections[UNIFIED_SECTION_SPLASH].size);
if (use_load_options(image, loaded_image, szs[UNIFIED_SECTION_CMDLINE] > 0, &cmdline)) {
if (use_load_options(image, loaded_image, /* have_cmdline= */ PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE), &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
* we want the boot menu to support an EFI binary, and want to this stub to be usable from
@@ -638,10 +639,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
m = false;
(void) tpm_log_load_options(cmdline, &m);
combine_measured_flag(&parameters_measured, m);
} else if (szs[UNIFIED_SECTION_CMDLINE] > 0) {
} else if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE)) {
cmdline = xstrn8_to_16(
(char *) loaded_image->ImageBase + addrs[UNIFIED_SECTION_CMDLINE],
szs[UNIFIED_SECTION_CMDLINE]);
(char *) loaded_image->ImageBase + sections[UNIFIED_SECTION_CMDLINE].memory_offset,
sections[UNIFIED_SECTION_CMDLINE].size);
mangle_stub_cmdline(cmdline);
}
@@ -727,8 +728,11 @@ static EFI_STATUS run(EFI_HANDLE image) {
&m) == EFI_SUCCESS)
combine_measured_flag(&confext_measured, m);
dt_size = szs[UNIFIED_SECTION_DTB];
dt_base = dt_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_DTB] : 0;
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) {
dt_size = sections[UNIFIED_SECTION_DTB].size;
dt_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[UNIFIED_SECTION_DTB].memory_offset;
}
/* First load the base device tree, then fix it up using addons - global first, then per-UKI. */
if (dt_size > 0) {
@@ -767,10 +771,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
* is not measured, neither as raw section (see above), nor as cpio (here), because it is the
* signature of expected PCR values, i.e. its input are PCR measurements, and hence it shouldn't
* itself be input for PCR measurements. */
if (szs[UNIFIED_SECTION_PCRSIG] > 0)
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_PCRSIG))
(void) pack_cpio_literal(
(uint8_t*) loaded_image->ImageBase + addrs[UNIFIED_SECTION_PCRSIG],
szs[UNIFIED_SECTION_PCRSIG],
(uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_PCRSIG].memory_offset,
sections[UNIFIED_SECTION_PCRSIG].size,
".extra",
u"tpm2-pcr-signature.json",
/* dir_mode= */ 0555,
@@ -785,10 +789,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
* a cpio and also pass it to the kernel, so that it can be read from
* /.extra/tpm2-pcr-public-key.pem. This section is already measure above, hence we won't measure the
* cpio. */
if (szs[UNIFIED_SECTION_PCRPKEY] > 0)
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_PCRPKEY))
(void) pack_cpio_literal(
(uint8_t*) loaded_image->ImageBase + addrs[UNIFIED_SECTION_PCRPKEY],
szs[UNIFIED_SECTION_PCRPKEY],
(uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_PCRPKEY].memory_offset,
sections[UNIFIED_SECTION_PCRPKEY].size,
".extra",
u"tpm2-pcr-public-key.pem",
/* dir_mode= */ 0555,
@@ -799,14 +803,18 @@ static EFI_STATUS run(EFI_HANDLE image) {
&pcrpkey_initrd_size,
/* ret_measured= */ NULL);
linux_size = szs[UNIFIED_SECTION_LINUX];
linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_LINUX];
linux_size = sections[UNIFIED_SECTION_LINUX].size;
linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[UNIFIED_SECTION_LINUX].memory_offset;
initrd_size = szs[UNIFIED_SECTION_INITRD];
initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_INITRD] : 0;
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_INITRD)) {
initrd_size = sections[UNIFIED_SECTION_INITRD].size;
initrd_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[UNIFIED_SECTION_INITRD].memory_offset;
}
ucode_size = szs[UNIFIED_SECTION_UCODE];
ucode_base = ucode_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_UCODE] : 0;
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE)) {
ucode_size = sections[UNIFIED_SECTION_UCODE].size;
ucode_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[UNIFIED_SECTION_UCODE].memory_offset;
}
_cleanup_pages_ Pages initrd_pages = {};
if (ucode_base || credential_initrd || global_credential_initrd || sysext_initrd || confext_initrd || pcrsig_initrd || pcrpkey_initrd) {
@@ -857,4 +865,4 @@ static EFI_STATUS run(EFI_HANDLE image) {
return err;
}
DEFINE_EFI_MAIN_FUNCTION(run, "systemd-stub", /*wait_for_debugger=*/false);
DEFINE_EFI_MAIN_FUNCTION(run, "systemd-stub", /* wait_for_debugger= */ false);