From ea8aa2ea8548584f864ac3f651062df59bef2205 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2024 17:50:56 +0200 Subject: [PATCH] boot: only open type2 ukis once when parsing --- src/boot/efi/boot.c | 56 ++++++++++++++++++++++++++++++++++++--------- src/boot/efi/pe.c | 34 --------------------------- src/boot/efi/pe.h | 6 ----- 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 097dceb9588..c788978eaa7 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1872,23 +1872,40 @@ static void generate_boot_entry_titles(Config *config) { } static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) { - static const char * const sections[] = { + static const char * const section_names[] = { ".sdmagic", NULL }; _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, &vector); - if (err != EFI_SUCCESS || vector.size != sizeof(SD_MAGIC)) + _cleanup_(file_closep) EFI_FILE *handle = NULL; + err = root_dir->Open(root_dir, &handle, (char16_t *) loader_path, EFI_FILE_MODE_READ, 0ULL); + if (err != EFI_SUCCESS) return false; - err = file_read(root_dir, loader_path, vector.file_offset, vector.size, &content, &read); + _cleanup_free_ PeSectionHeader *section_table = NULL; + size_t n_section_table; + err = pe_section_table_from_file(handle, §ion_table, &n_section_table); + if (err != EFI_SUCCESS) + return false; + + PeSectionVector vector = {}; + pe_locate_profile_sections( + section_table, + n_section_table, + section_names, + /* profile= */ UINT_MAX, + /* validate_base= */ 0, + &vector); + if (vector.size != sizeof(SD_MAGIC)) + return false; + + err = file_handle_read(handle, vector.file_offset, vector.size, &content, &read); if (err != EFI_SUCCESS || vector.size != read) return false; @@ -2119,15 +2136,32 @@ static void boot_entry_add_type2( assert(dir); assert(filename); + _cleanup_(file_closep) EFI_FILE *handle = NULL; + err = dir->Open(dir, &handle, (char16_t *) filename, EFI_FILE_MODE_READ, 0ULL); + if (err != EFI_SUCCESS) + return; + + _cleanup_free_ PeSectionHeader *section_table = NULL; + size_t n_section_table; + err = pe_section_table_from_file(handle, §ion_table, &n_section_table); + if (err != EFI_SUCCESS) + return; + /* Look for .osrel and .cmdline sections in the .efi binary */ PeSectionVector sections[_SECTION_MAX] = {}; - err = pe_file_locate_sections(dir, filename, section_names, sections); - if (err != EFI_SUCCESS || !PE_SECTION_VECTOR_IS_SET(sections + SECTION_OSREL)) + pe_locate_profile_sections( + section_table, + n_section_table, + section_names, + /* profile= */ UINT_MAX, + /* validate_base= */ 0, + sections); + if (!PE_SECTION_VECTOR_IS_SET(sections + SECTION_OSREL)) return; _cleanup_free_ char *content = NULL; - err = file_read(dir, - filename, + err = file_handle_read( + handle, sections[SECTION_OSREL].file_offset, sections[SECTION_OSREL].size, &content, @@ -2215,8 +2249,8 @@ static void boot_entry_add_type2( /* read the embedded cmdline file */ size_t cmdline_len; - err = file_read(dir, - filename, + err = file_handle_read( + handle, sections[SECTION_CMDLINE].file_offset, sections[SECTION_CMDLINE].size, &content, diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c index 7eb8c4fa202..7cae3e7131a 100644 --- a/src/boot/efi/pe.c +++ b/src/boot/efi/pe.c @@ -410,40 +410,6 @@ EFI_STATUS pe_section_table_from_file( return EFI_SUCCESS; } -EFI_STATUS pe_file_locate_sections( - EFI_FILE *dir, - const char16_t *path, - const char* const section_names[], - PeSectionVector sections[]) { - - _cleanup_free_ PeSectionHeader *section_table = NULL; - _cleanup_(file_closep) EFI_FILE *handle = NULL; - size_t n_section_table; - EFI_STATUS err; - - assert(dir); - assert(path); - assert(section_names); - assert(sections); - - err = dir->Open(dir, &handle, (char16_t *) path, EFI_FILE_MODE_READ, 0ULL); - if (err != EFI_SUCCESS) - return err; - - err = pe_section_table_from_file(handle, §ion_table, &n_section_table); - if (err != EFI_SUCCESS) - return err; - - pe_locate_sections( - section_table, - n_section_table, - section_names, - /* validate_base= */ 0, /* don't validate base */ - sections); - - return EFI_SUCCESS; -} - static const PeSectionHeader* pe_section_table_find_profile_start( const PeSectionHeader *section_table, size_t n_section_table, diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h index 31efbebbeb6..b9838579cf6 100644 --- a/src/boot/efi/pe.h +++ b/src/boot/efi/pe.h @@ -52,10 +52,4 @@ EFI_STATUS pe_memory_locate_sections( const char *const section_names[], PeSectionVector sections[]); -EFI_STATUS pe_file_locate_sections( - EFI_FILE *dir, - const char16_t *path, - const char *const section_names[], - PeSectionVector sections[]); - EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address, size_t *ret_size_in_memory);