From: Lennart Poettering Date: Fri, 5 Jul 2024 08:15:56 +0000 (+0200) Subject: pe-binary: split pe_read_section_data() into two X-Git-Tag: v257-rc1~441^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3c1d7fea124c5a68534ffe14bab2996ffe84732;p=thirdparty%2Fsystemd.git pe-binary: split pe_read_section_data() into two This renames pe_read_section_data() to pe_read_section_data_by_name() and makes pe_read_section_data() a bit more low-level: it takes a header table entry directly, instead of searching it first by name. --- diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index 29338ac7c42..b902fe54803 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -790,7 +790,7 @@ static int find_cmdline_section( if (!ret_cmdline) return 0; - r = pe_read_section_data(fd, pe_header, sections, ".cmdline", PE_SECTION_SIZE_MAX, (void**) &cmdline, NULL); + r = pe_read_section_data_by_name(fd, pe_header, sections, ".cmdline", PE_SECTION_SIZE_MAX, (void**) &cmdline, NULL); if (r == -ENXIO) { /* cmdline is optional */ *ret_cmdline = NULL; return 0; @@ -824,7 +824,7 @@ static int find_osrel_section( if (!ret_osrelease) return 0; - r = pe_read_section_data(fd, pe_header, sections, ".osrel", PE_SECTION_SIZE_MAX, (void**) ret_osrelease, NULL); + r = pe_read_section_data_by_name(fd, pe_header, sections, ".osrel", PE_SECTION_SIZE_MAX, (void**) ret_osrelease, NULL); if (r < 0) return log_error_errno(r, "Failed to read .osrel section of '%s': %m", path); diff --git a/src/shared/kernel-image.c b/src/shared/kernel-image.c index 7dc9e01e92f..4230d012be9 100644 --- a/src/shared/kernel-image.c +++ b/src/shared/kernel-image.c @@ -36,7 +36,7 @@ static int uki_read_pretty_name( assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0); assert(ret); - r = pe_read_section_data( + r = pe_read_section_data_by_name( fd, pe_header, sections, @@ -91,13 +91,13 @@ static int inspect_uki( assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0); if (ret_cmdline) { - r = pe_read_section_data(fd, pe_header, sections, ".cmdline", PE_SECTION_READ_MAX, (void**) &cmdline, NULL); + r = pe_read_section_data_by_name(fd, pe_header, sections, ".cmdline", PE_SECTION_READ_MAX, (void**) &cmdline, NULL); if (r < 0 && r != -ENXIO) /* If the section doesn't exist, that's fine */ return r; } if (ret_uname) { - r = pe_read_section_data(fd, pe_header, sections, ".uname", PE_SECTION_READ_MAX, (void**) &uname, NULL); + r = pe_read_section_data_by_name(fd, pe_header, sections, ".uname", PE_SECTION_READ_MAX, (void**) &uname, NULL); if (r < 0 && r != -ENXIO) /* If the section doesn't exist, that's fine */ return r; } diff --git a/src/shared/pe-binary.c b/src/shared/pe-binary.c index a3aceb909e4..448ace7571a 100644 --- a/src/shared/pe-binary.c +++ b/src/shared/pe-binary.c @@ -173,43 +173,28 @@ int pe_load_sections( int pe_read_section_data( int fd, - const PeHeader *pe_header, - const IMAGE_SECTION_HEADER *sections, - const char *name, + const IMAGE_SECTION_HEADER *section, size_t max_size, void **ret, size_t *ret_size) { - const IMAGE_SECTION_HEADER *section; - _cleanup_free_ void *data = NULL; - size_t n; - ssize_t ss; - assert(fd >= 0); - assert(pe_header); - assert(sections || pe_header->pe.NumberOfSections == 0); - assert(name); + assert(section); - section = pe_header_find_section(pe_header, sections, name); - if (!section) - return -ENXIO; - - n = le32toh(section->VirtualSize); + size_t n = le32toh(section->VirtualSize); if (n > MIN(max_size, (size_t) SSIZE_MAX)) return -E2BIG; - data = malloc(n+1); + _cleanup_free_ void *data = malloc(n+1); if (!data) return -ENOMEM; - ss = pread(fd, data, n, le32toh(section->PointerToRawData)); + ssize_t ss = pread(fd, data, n, le32toh(section->PointerToRawData)); if (ss < 0) return -errno; if ((size_t) ss != n) return -EIO; - ((uint8_t*) data)[n] = 0; /* NUL terminate, no matter what */ - if (ret_size) *ret_size = n; else { @@ -221,12 +206,37 @@ int pe_read_section_data( if (nul && !memeqzero(nul, n - (nul - (const char*) data))) /* If there's a NUL it must only be NULs from there on */ return -EBADMSG; } - if (ret) + if (ret) { + ((uint8_t*) data)[n] = 0; /* NUL terminate, no matter what */ *ret = TAKE_PTR(data); + } return 0; } +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) { + + const IMAGE_SECTION_HEADER *section; + + assert(fd >= 0); + assert(pe_header); + assert(sections || pe_header->pe.NumberOfSections == 0); + assert(name); + + section = pe_header_find_section(pe_header, sections, name); + if (!section) + return -ENXIO; + + return pe_read_section_data(fd, section, max_size, ret, ret_size); +} + bool pe_is_uki(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections) { assert(pe_header); assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0); diff --git a/src/shared/pe-binary.h b/src/shared/pe-binary.h index f0979711c83..08cc6a75ad7 100644 --- a/src/shared/pe-binary.h +++ b/src/shared/pe-binary.h @@ -139,7 +139,8 @@ const IMAGE_SECTION_HEADER *pe_header_find_section(const PeHeader *pe_header, co 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_read_section_data(int fd, const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections, const char *name, size_t max_size, void **ret, size_t *ret_size); +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); bool pe_is_uki(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections); bool pe_is_addon(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections);