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:
committed by
Luca Boccassi
parent
899a314271
commit
6f076ff729
@@ -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, §ions);
|
||||
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, §ions);
|
||||
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
@@ -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, §ions);
|
||||
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, §ions, &pe_header);
|
||||
r = pe_load_headers_and_sections(fd, &pe_header, §ions);
|
||||
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, §ions, &pe_header);
|
||||
r = pe_load_headers_and_sections(fd, &pe_header, §ions);
|
||||
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);
|
||||
|
||||
@@ -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, §ions);
|
||||
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, §ions);
|
||||
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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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, §ions);
|
||||
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, §ions);
|
||||
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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user