Binutils objdump contains a denial-of-service vulnerability when processing a crafted binary with malformed DWARF debug information. A logic error in the handling of DWARF compilation units can result in an invalid offset_size value being used inside byte_get_little_endian, leading to an abort (SIGABRT). A local attacker can trigger the crash by supplying a malicious input file.
Signed-off-by: Roland Kovacs <[email protected]> --- .../binutils/binutils-2.42.inc | 1 + .../binutils/binutils/CVE-2025-69645.patch | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2025-69645.patch diff --git a/meta/recipes-devtools/binutils/binutils-2.42.inc b/meta/recipes-devtools/binutils/binutils-2.42.inc index 7e83f72632..8f775f20e7 100644 --- a/meta/recipes-devtools/binutils/binutils-2.42.inc +++ b/meta/recipes-devtools/binutils/binutils-2.42.inc @@ -74,5 +74,6 @@ SRC_URI = "\ file://0030-CVE-2025-11840.patch \ file://CVE-2025-69644-CVE-2025-69647.patch \ file://CVE-2025-69648.patch \ + file://CVE-2025-69645.patch \ " S = "${WORKDIR}/git" diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-69645.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-69645.patch new file mode 100644 index 0000000000..78d2d62a50 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-69645.patch @@ -0,0 +1,135 @@ +From 3fe207e0625a76c8cba932e435762bfb5f544131 Mon Sep 17 00:00:00 2001 +From: Alan Modra <[email protected]> +Date: Sun, 30 Nov 2025 12:51:54 +1030 +Subject: [PATCH] PR 33637, abort in byte_get + +When DWARF5 support was added to binutils in commit 77145576fadc, +the loop over CUs in process_debug_info set do_types when finding a +DW_UT_type unit, in order to process the signature and type offset +entries. Unfortunately that broke debug_information/debug_info_p +handling, which previously was allocated and initialised for each unit +in .debug_info. debug_info_p was NULL when processing a DWARF4 +.debug_types section. After the 77145576fadc change it was possible +for debug_infp_p to be non-NULL but point to zeroed data, in +particular a zeroed offset_size. A zero for offset_size led to the +byte_get_little_endian abort triggered by the fuzzer testcase. + +I haven't investigated whether there is any need for a valid +offset_size when processing a non-fuzzed DWARF4 .debug_types section. +Presumably we'd have found that out in the last 6 years if that was +the case. We don't want to change debug_information[] for +.debug_types! + + PR 33637 + * dwarf.c (process_debug_info): Don't change DO_TYPES flag bit + depending on cu_unit_type. Instead test cu_unit_type along + with DO_TYPES to handle signature and type_offset for a type + unit. Move find_cu_tu_set_v2 call a little later. + +CVE: CVE-2025-69645 +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cdb728d4da6184631989b192f1022c219dea7677] + +Note: + Backported patch differs from upstream as commit + 1f7e70ddd2c49dd5442b8873dd6ef29b0a10fdc3 is not cherry-picked + just to introduce `do_flags` instead of the separate `do_type` + and `do_loc` booleans for it to apply cleanly. + +Signed-off-by: Roland Kovacs <[email protected]> +--- + binutils/dwarf.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/binutils/dwarf.c b/binutils/dwarf.c +index 615e051b2bf..836872f1b26 100644 +--- a/binutils/dwarf.c ++++ b/binutils/dwarf.c +@@ -3865,8 +3865,6 @@ process_debug_info (struct dwarf_section * section, + + SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu); + +- this_set = find_cu_tu_set_v2 (cu_offset, do_types); +- + if (compunit.cu_version < 5) + { + compunit.cu_unit_type = DW_UT_compile; +@@ -3876,8 +3874,6 @@ process_debug_info (struct dwarf_section * section, + else + { + SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu); +- do_types = (compunit.cu_unit_type == DW_UT_type); +- + SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu); + } + +@@ -3891,6 +3887,7 @@ process_debug_info (struct dwarf_section * section, + SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end_cu); + } + ++ this_set = find_cu_tu_set_v2 (cu_offset, do_types); + if (this_set == NULL) + { + abbrev_base = 0; +@@ -3947,8 +3944,6 @@ process_debug_info (struct dwarf_section * section, + + SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu); + +- this_set = find_cu_tu_set_v2 (cu_offset, do_types); +- + if (compunit.cu_version < 5) + { + compunit.cu_unit_type = DW_UT_compile; +@@ -3958,13 +3953,12 @@ process_debug_info (struct dwarf_section * section, + else + { + SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu); +- do_types = (compunit.cu_unit_type == DW_UT_type); +- + SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu); + } + + SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end_cu); + ++ this_set = find_cu_tu_set_v2 (cu_offset, do_types); + if (this_set == NULL) + { + abbrev_base = 0; +@@ -3996,7 +3990,7 @@ process_debug_info (struct dwarf_section * section, + compunit.cu_pointer_size = offset_size; + } + +- if (do_types) ++ if (do_types || compunit.cu_unit_type == DW_UT_type) + { + SAFE_BYTE_GET_AND_INC (signature, hdrptr, 8, end_cu); + SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end_cu); +@@ -4011,7 +4005,7 @@ process_debug_info (struct dwarf_section * section, + if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info) + && num_debug_info_entries == 0 + && alloc_num_debug_info_entries > unit +- && ! do_types) ++ && !do_types) + { + free_debug_information (&debug_information[unit]); + memset (&debug_information[unit], 0, sizeof (*debug_information)); +@@ -4042,7 +4036,7 @@ process_debug_info (struct dwarf_section * section, + printf (_(" Abbrev Offset: %#" PRIx64 "\n"), + compunit.cu_abbrev_offset); + printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size); +- if (do_types) ++ if (do_types || compunit.cu_unit_type == DW_UT_type) + { + printf (_(" Signature: %#" PRIx64 "\n"), signature); + printf (_(" Type Offset: %#" PRIx64 "\n"), type_offset); +@@ -4319,7 +4313,7 @@ process_debug_info (struct dwarf_section * section, + we need to process .debug_loc and .debug_ranges sections. */ + if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info) + && num_debug_info_entries == 0 +- && ! do_types) ++ && !do_types) + { + if (num_units > alloc_num_debug_info_entries) + num_debug_info_entries = alloc_num_debug_info_entries; +-- +2.34.1 + -- 2.34.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#241075): https://lists.openembedded.org/g/openembedded-core/message/241075 Mute This Topic: https://lists.openembedded.org/mt/120296032/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
