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.
This commit is contained in:
Lennart Poettering
2024-09-12 10:02:15 +02:00
parent a8e912f01b
commit f3c1d7fea1
4 changed files with 38 additions and 27 deletions
+2 -2
View File
@@ -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);
+3 -3
View File
@@ -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;
}
+31 -21
View File
@@ -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);
+2 -1
View File
@@ -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);