From: Oblivionsage Date: Tue, 17 Feb 2026 18:39:05 +0000 (+0100) Subject: pe-binary: fix missing le16toh() on NumberOfSections in pe_hash/uki_hash X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02cab70acf5ca67e838d0d34860baacbf9fc3b6c;p=thirdparty%2Fsystemd.git pe-binary: fix missing le16toh() on NumberOfSections in pe_hash/uki_hash pe_hash() and uki_hash() pass pe_header->pe.NumberOfSections directly to typesafe_qsort() and FOREACH_ARRAY() without le16toh(). On big-endian (s390x), NumberOfSections=3 gets read as 0x0300 (768), while pe_load_sections() correctly converts it and only allocates 3 sections. This makes qsort process 768 elements on a 3-element buffer, causing a heap-buffer-overflow (confirmed with ASAN on native s390x). Wrap all three raw usages with le16toh() to match pe_load_sections(). --- diff --git a/src/shared/pe-binary.c b/src/shared/pe-binary.c index 0a1b93118c2..2818fae2cb8 100644 --- a/src/shared/pe-binary.c +++ b/src/shared/pe-binary.c @@ -243,7 +243,7 @@ int pe_read_section_data_by_name( assert(fd >= 0); assert(pe_header); - assert(sections || pe_header->pe.NumberOfSections == 0); + assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0); assert(name); section = pe_header_find_section(pe_header, sections, name); @@ -408,9 +408,9 @@ int pe_hash(int fd, return r; /* Sort by location in file */ - typesafe_qsort(sections, pe_header->pe.NumberOfSections, section_offset_cmp); + typesafe_qsort(sections, le16toh(pe_header->pe.NumberOfSections), section_offset_cmp); - FOREACH_ARRAY(section, sections, pe_header->pe.NumberOfSections) { + FOREACH_ARRAY(section, sections, le16toh(pe_header->pe.NumberOfSections)) { r = hash_file(fd, mdctx, section->PointerToRawData, section->SizeOfRawData); if (r < 0) return r; @@ -537,7 +537,7 @@ int uki_hash(int fd, if (hsz < 0) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get hash size."); - FOREACH_ARRAY(section, sections, pe_header->pe.NumberOfSections) { + FOREACH_ARRAY(section, sections, le16toh(pe_header->pe.NumberOfSections)) { _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *mdctx = NULL; _cleanup_free_ char *n = NULL; ssize_t i;