pe-binary: add pe_load_headers_and_sections()

Most callers load the PE headers and the section table together, and
only keep the DOS header to pass it to pe_load_sections(). Add a helper
that does both, and use it instead of the private copy in bootspec.c.

(cherry picked from commit 5902fb429f52d75e7b25e6dea4be113e769b2ff8)
This commit is contained in:
Daan De Meyer
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent 899a314271
commit 6f076ff729
6 changed files with 31 additions and 58 deletions
+2 -9
View File
@@ -142,21 +142,14 @@ int get_file_version(int fd, char **ret) {
* section, i.e. a string such as "#### LoaderInfo: systemd-boot 218 ####", and returns the inner
* part, e.g. "systemd-boot 218". Does not reposition the file offset (as it uses pread()). */
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
r = pe_load_headers(fd, &dos_header, &pe_header);
r = pe_load_headers_and_sections(fd, &pe_header, &sections);
if (r == -EBADMSG)
return log_debug_errno(SYNTHETIC_ERRNO(ESRCH), "EFI binary is not a valid PE file, assuming no version information.");
if (r < 0)
return r;
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
r = pe_load_sections(fd, dos_header, pe_header, &sections);
if (r == -EBADMSG)
return log_debug_errno(SYNTHETIC_ERRNO(ESRCH), "Failed to load PE section table, assuming no version information.");
if (r < 0)
return r;
_cleanup_free_ char *sdmagic = NULL;
r = pe_read_section_data_by_name(
fd,
+4 -34
View File
@@ -1045,36 +1045,6 @@ static int boot_entry_load_unified(
return 0;
}
static int pe_load_headers_and_sections(
int fd,
const char *path,
IMAGE_SECTION_HEADER **ret_sections,
PeHeader **ret_pe_header) {
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
int r;
assert(fd >= 0);
assert(path);
r = pe_load_headers(fd, &dos_header, &pe_header);
if (r < 0)
return log_error_errno(r, "Failed to parse PE file '%s': %m", path);
r = pe_load_sections(fd, dos_header, pe_header, &sections);
if (r < 0)
return log_error_errno(r, "Failed to parse PE sections of '%s': %m", path);
if (ret_pe_header)
*ret_pe_header = TAKE_PTR(pe_header);
if (ret_sections)
*ret_sections = TAKE_PTR(sections);
return 0;
}
static const IMAGE_SECTION_HEADER* pe_find_profile_section_table(
const PeHeader *pe_header,
const IMAGE_SECTION_HEADER *sections,
@@ -1178,9 +1148,9 @@ int pe_find_uki_sections(
assert(path);
assert(profile != UINT_MAX);
r = pe_load_headers_and_sections(fd, path, &sections, &pe_header);
r = pe_load_headers_and_sections(fd, &pe_header, &sections);
if (r < 0)
return r;
return log_error_errno(r, "Failed to parse PE file '%s': %m", path);
if (!pe_is_uki(pe_header, sections))
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Parsed PE file '%s' is not a UKI.", path);
@@ -1270,9 +1240,9 @@ static int pe_find_addon_sections(
assert(path);
assert(ret_cmdline);
r = pe_load_headers_and_sections(fd, path, &sections, &pe_header);
r = pe_load_headers_and_sections(fd, &pe_header, &sections);
if (r < 0)
return r;
return log_error_errno(r, "Failed to parse PE file '%s': %m", path);
if (!pe_is_addon(pe_header, sections))
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Parse PE file '%s' is not an add-on.", path);
+1 -8
View File
@@ -124,7 +124,6 @@ int inspect_kernel_full(
char **ret_pretty_name) {
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
KernelImageType t = KERNEL_IMAGE_TYPE_UNKNOWN;
_cleanup_free_ PeHeader *pe_header = NULL;
_cleanup_close_ int fd = -EBADF;
@@ -136,18 +135,12 @@ int inspect_kernel_full(
if (fd < 0)
return log_debug_errno(fd, "Failed to open kernel image file '%s': %m", strna(filename));
r = pe_load_headers(fd, &dos_header, &pe_header);
r = pe_load_headers_and_sections(fd, &pe_header, &sections);
if (r == -EBADMSG) /* not a valid PE file */
goto not_uki;
if (r < 0)
return log_debug_errno(r, "Failed to parse kernel image file '%s': %m", strna(filename));
r = pe_load_sections(fd, dos_header, pe_header, &sections);
if (r == -EBADMSG) /* not a valid PE file */
goto not_uki;
if (r < 0)
return log_debug_errno(r, "Failed to load PE sections from kernel image file '%s': %m", strna(filename));
if (pe_is_uki(pe_header, sections)) {
r = inspect_uki(fd, pe_header, sections, ret_cmdline, ret_uname, ret_pretty_name);
if (r < 0)
+21
View File
@@ -220,6 +220,27 @@ int pe_load_sections(
return 0;
}
int pe_load_headers_and_sections(int fd, PeHeader **ret_pe_header, IMAGE_SECTION_HEADER **ret_sections) {
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
int r;
assert(fd >= 0);
r = pe_load_headers(fd, &dos_header, &pe_header);
if (r < 0)
return r;
r = pe_load_sections(fd, dos_header, pe_header, ret_sections);
if (r < 0)
return r;
if (ret_pe_header)
*ret_pe_header = TAKE_PTR(pe_header);
return 0;
}
int pe_read_section_data(
int fd,
const IMAGE_SECTION_HEADER *section,
+1
View File
@@ -141,6 +141,7 @@ const IMAGE_SECTION_HEADER* pe_section_table_find(const IMAGE_SECTION_HEADER *se
int pe_load_headers(int fd, IMAGE_DOS_HEADER **ret_dos_header, PeHeader **ret_pe_header);
int pe_load_sections(int fd, const IMAGE_DOS_HEADER *dos_header, const PeHeader *pe_header, IMAGE_SECTION_HEADER **ret_sections);
int pe_load_headers_and_sections(int fd, PeHeader **ret_pe_header, IMAGE_SECTION_HEADER **ret_sections);
int pe_read_section_data(int fd, const IMAGE_SECTION_HEADER *section, size_t max_size, void **ret, size_t *ret_size);
int pe_read_section_data_by_name(int fd, const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections, const char *name, size_t max_size, void **ret, size_t *ret_size);
+2 -7
View File
@@ -381,17 +381,12 @@ static int extract_uki(const char *path, int fd, int *ret_kernel_fd, int *ret_in
assert(fd >= 0);
assert(ret_kernel_fd);
_cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
_cleanup_free_ PeHeader *pe_header = NULL;
r = pe_load_headers(fd, &dos_header, &pe_header);
r = pe_load_headers_and_sections(fd, &pe_header, &sections);
if (r < 0)
return log_debug_errno(r, "Not a valid PE file '%s': %m", path);
_cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
r = pe_load_sections(fd, dos_header, pe_header, &sections);
if (r < 0)
return log_debug_errno(r, "Failed to load PE sections from '%s': %m", path);
if (!pe_is_uki(pe_header, sections))
return 0; /* Not a UKI */