From: Alan Modra Date: Fri, 21 Nov 2025 23:22:18 +0000 (+1030) Subject: PR 33639 .debug_loclists output X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=455446bbdc8675f34808187de2bbad4682016ff7;p=thirdparty%2Fbinutils-gdb.git PR 33639 .debug_loclists output The fuzzed testcase in this PR prints an almost endless table of offsets, due to a bogus offset count. Limit that count, and the total length too. PR 33639 * dwarf.c (display_loclists_unit_header): Return error on length too small to read header. Limit length to section size. Limit offset count similarly. --- diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 407c6477788..a3d40cb4fc8 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -7255,8 +7255,6 @@ display_loclists_unit_header (struct dwarf_section * section, bool is_64bit; uint32_t i; - printf (_("Table at Offset %#" PRIx64 "\n"), header_offset); - SAFE_BYTE_GET_AND_INC (length, start, 4, end); if (length == 0xffffffff) { @@ -7265,6 +7263,11 @@ display_loclists_unit_header (struct dwarf_section * section, } else is_64bit = false; + if (length < 8) + return (uint64_t) -1; + + printf (_("Table at Offset %#" PRIx64 "\n"), header_offset); + header_offset = start - section->start; SAFE_BYTE_GET_AND_INC (version, start, 2, end); SAFE_BYTE_GET_AND_INC (address_size, start, 1, end); @@ -7277,15 +7280,21 @@ display_loclists_unit_header (struct dwarf_section * section, printf (_(" Segment size: %u\n"), segment_selector_size); printf (_(" Offset entries: %u\n"), *offset_count); + if (length > section->size - header_offset) + length = section->size - header_offset; + if (segment_selector_size != 0) { warn (_("The %s section contains an " "unsupported segment selector size: %d.\n"), section->name, segment_selector_size); - return (uint64_t)-1; + return (uint64_t) -1; } - if ( *offset_count) + uint64_t max_off_count = length >> (is_64bit ? 3 : 2); + if (*offset_count > max_off_count) + *offset_count = max_off_count; + if (*offset_count) { printf (_("\n Offset Entries starting at %#tx:\n"), start - section->start); @@ -7302,8 +7311,7 @@ display_loclists_unit_header (struct dwarf_section * section, putchar ('\n'); *loclists_start = start; - /* The length field doesn't include the length field itself. */ - return header_offset + length + (is_64bit ? 12 : 4); + return header_offset + length; } static int