| Message ID | 20260401100022.1173083-1-deeratho@cisco.com |
|---|---|
| State | Changes Requested |
| Delegated to: | Yoann Congal |
| Headers | show |
| Series | [whinlatter,v2,1/4] binutils: Fix CVE-2025-69648 | expand |
Thank you for your submission. Patchtest identified one or more issues with the patch. Please see the log below for more information: --- Testing patch /home/patchtest/share/mboxes/whinlatter-v2-1-4-binutils-Fix-CVE-2025-69648.patch FAIL: test Upstream-Status presence: Added patch file is missing Upstream-Status: <Valid status> in the commit message (test_patch.TestPatch.test_upstream_status_presence_format) PASS: test CVE tag format (test_patch.TestPatch.test_cve_tag_format) PASS: test Signed-off-by presence (test_mbox.TestMbox.test_signed_off_by_presence) PASS: test Signed-off-by presence (test_patch.TestPatch.test_signed_off_by_presence) PASS: test author valid (test_mbox.TestMbox.test_author_valid) PASS: test commit message presence (test_mbox.TestMbox.test_commit_message_presence) PASS: test commit message user tags (test_mbox.TestMbox.test_commit_message_user_tags) PASS: test mbox format (test_mbox.TestMbox.test_mbox_format) PASS: test non-AUH upgrade (test_mbox.TestMbox.test_non_auh_upgrade) PASS: test shortlog format (test_mbox.TestMbox.test_shortlog_format) PASS: test shortlog length (test_mbox.TestMbox.test_shortlog_length) PASS: test target mailing list (test_mbox.TestMbox.test_target_mailing_list) SKIP: pretest pylint: No python related patches, skipping test (test_python_pylint.PyLint.pretest_pylint) SKIP: test bugzilla entry format: No bug ID found (test_mbox.TestMbox.test_bugzilla_entry_format) SKIP: test pylint: No python related patches, skipping test (test_python_pylint.PyLint.test_pylint) SKIP: test series merge on head: Merge test is disabled for now (test_mbox.TestMbox.test_series_merge_on_head) --- Please address the issues identified and submit a new revision of the patch, or alternatively, reply to this email with an explanation of why the patch should be accepted. If you believe these results are due to an error in patchtest, please submit a bug at https://bugzilla.yoctoproject.org/ (use the 'Patchtest' category under 'Yocto Project Subprojects'). For more information on specific failures, see: https://wiki.yoctoproject.org/wiki/Patchtest. Thank you!
On Wed Apr 1, 2026 at 12:00 PM CEST, Deepak Rathore via lists.openembedded.org wrote: > From: Deepak Rathore <deeratho@cisco.com> > > pick the patch [1] as mentioned in [2] > > [1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33 > [2] https://nvd.nist.gov/vuln/detail/CVE-2025-69648 > > Signed-off-by: Deepak Rathore <deeratho@cisco.com> > > diff --git a/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch b/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch > new file mode 100644 > index 0000000000..70866fd7da > --- /dev/null > +++ b/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch > @@ -0,0 +1,222 @@ > +From 507f05eb8f3a132a536c593e232fdc7878fb9bba Mon Sep 17 00:00:00 2001 > +From: Deepak Rathore <deeratho@cisco.com> > +Date: Tue, 31 Mar 2026 11:25:32 +0000 > +Subject: [PATCH] pick the patch [1] as mentioned in [2]. > + > +[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33 > +[2] https://nvd.nist.gov/vuln/detail/CVE-2025-69648 > + > +Signed-off-by: Deepak Rathore <deeratho@cisco.com> > +--- > + .../binutils/binutils-2.45.inc | 1 + > + .../binutils/binutils/CVE-2025-69648.patch | 188 ++++++++++++++++++ That added patch is targeted at oe-core not binutils? Something went wrong... > + 2 files changed, 189 insertions(+) > + create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch > + > +diff --git a/meta/recipes-devtools/binutils/binutils-2.45.inc b/meta/recipes-devtools/binutils/binutils-2.45.inc > +index 16a63cabc5..b6d7b3d60f 100644 > +--- a/meta/recipes-devtools/binutils/binutils-2.45.inc > ++++ b/meta/recipes-devtools/binutils/binutils-2.45.inc > +@@ -46,4 +46,5 @@ SRC_URI = "\ > + file://0018-CVE-2025-11494.patch \ > + file://0019-CVE-2025-11839.patch \ > + file://0020-CVE-2025-11840.patch \ > ++ file://CVE-2025-69648.patch \ > + " > +diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch > +new file mode 100644 > +index 0000000000..2346b18f01 > +--- /dev/null > ++++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch > +@@ -0,0 +1,188 @@ > ++From 7df481dd76c05c89782721e9df5468be829c356b Mon Sep 17 00:00:00 2001 > ++From: Alan Modra <amodra@gmail.com> > ++Date: Sat, 22 Nov 2025 09:22:10 +1030 > ++Subject: [PATCH] PR 33638, debug_rnglists output > ++ > ++The fuzzed testcase in this PR continuously outputs an error about > ++the debug_rnglists header. Fixed by taking notice of the error and > ++stopping output. The patch also limits the length in all cases, not > ++just when a relocation is present, and limits the offset entry count > ++read from the header. I removed the warning and the test for relocs > ++because the code can't work reliably with unresolved relocs in the > ++length field. > ++ > ++ PR 33638 > ++ * dwarf.c (display_debug_rnglists_list): Return bool. Rename > ++ "inital_length" to plain "length". Verify length is large > ++ enough to read header. Limit length to rest of section. > ++ Similarly limit offset_entry_count. > ++ (display_debug_ranges): Check display_debug_rnglists_unit_header > ++ return status. Stop output on error. > ++ > ++CVE: CVE-2025-69648 > ++Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33] > ++ > ++(cherry picked from commit 598704a00cbac5e85c2bedd363357b5bf6fcee33) > ++Signed-off-by: Deepak Rathore <deeratho@cisco.com> > ++--- > ++ binutils/dwarf.c | 67 ++++++++++++++++++++++++------------------------ > ++ 1 file changed, 34 insertions(+), 33 deletions(-) > ++ > ++diff --git a/binutils/dwarf.c b/binutils/dwarf.c > ++index f4bcb677761..b4fb56351ec 100644 > ++--- a/binutils/dwarf.c > +++++ b/binutils/dwarf.c > ++@@ -8282,7 +8282,7 @@ display_debug_rnglists_list (unsigned char * start, > ++ return start; > ++ } > ++ > ++-static int > +++static bool > ++ display_debug_rnglists_unit_header (struct dwarf_section * section, > ++ uint64_t * unit_offset, > ++ unsigned char * poffset_size) > ++@@ -8290,7 +8290,8 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > ++ uint64_t start_offset = *unit_offset; > ++ unsigned char * p = section->start + start_offset; > ++ unsigned char * finish = section->start + section->size; > ++- uint64_t initial_length; > +++ unsigned char * hdr; > +++ uint64_t length; > ++ unsigned char segment_selector_size; > ++ unsigned int offset_entry_count; > ++ unsigned int i; > ++@@ -8299,66 +8300,59 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > ++ unsigned char offset_size; > ++ > ++ /* Get and check the length of the block. */ > ++- SAFE_BYTE_GET_AND_INC (initial_length, p, 4, finish); > +++ SAFE_BYTE_GET_AND_INC (length, p, 4, finish); > ++ > ++- if (initial_length == 0xffffffff) > +++ if (length == 0xffffffff) > ++ { > ++ /* This section is 64-bit DWARF 3. */ > ++- SAFE_BYTE_GET_AND_INC (initial_length, p, 8, finish); > +++ SAFE_BYTE_GET_AND_INC (length, p, 8, finish); > ++ *poffset_size = offset_size = 8; > ++ } > ++ else > ++ *poffset_size = offset_size = 4; > ++ > ++- if (initial_length > (size_t) (finish - p)) > ++- { > ++- /* If the length field has a relocation against it, then we should > ++- not complain if it is inaccurate (and probably negative). > ++- It is copied from .debug_line handling code. */ > ++- if (reloc_at (section, (p - section->start) - offset_size)) > ++- initial_length = finish - p; > ++- else > ++- { > ++- warn (_("The length field (%#" PRIx64 > ++- ") in the debug_rnglists header is wrong" > ++- " - the section is too small\n"), > ++- initial_length); > ++- return 0; > ++- } > ++- } > ++- > ++- /* Report the next unit offset to the caller. */ > ++- *unit_offset = (p - section->start) + initial_length; > +++ if (length < 8) > +++ return false; > ++ > ++ /* Get the other fields in the header. */ > +++ hdr = p; > ++ SAFE_BYTE_GET_AND_INC (version, p, 2, finish); > ++ SAFE_BYTE_GET_AND_INC (address_size, p, 1, finish); > ++ SAFE_BYTE_GET_AND_INC (segment_selector_size, p, 1, finish); > ++ SAFE_BYTE_GET_AND_INC (offset_entry_count, p, 4, finish); > ++ > ++ printf (_(" Table at Offset: %#" PRIx64 ":\n"), start_offset); > ++- printf (_(" Length: %#" PRIx64 "\n"), initial_length); > +++ printf (_(" Length: %#" PRIx64 "\n"), length); > ++ printf (_(" DWARF version: %u\n"), version); > ++ printf (_(" Address size: %u\n"), address_size); > ++ printf (_(" Segment size: %u\n"), segment_selector_size); > ++ printf (_(" Offset entries: %u\n"), offset_entry_count); > ++ > +++ if (length > (size_t) (finish - hdr)) > +++ length = finish - hdr; > +++ > +++ /* Report the next unit offset to the caller. */ > +++ *unit_offset = (hdr - section->start) + length; > +++ > ++ /* Check the fields. */ > ++ if (segment_selector_size != 0) > ++ { > ++ warn (_("The %s section contains " > ++ "unsupported segment selector size: %d.\n"), > ++ section->name, segment_selector_size); > ++- return 0; > +++ return false; > ++ } > ++ > ++ if (version < 5) > ++ { > ++ warn (_("Only DWARF version 5+ debug_rnglists info " > ++ "is currently supported.\n")); > ++- return 0; > +++ return false; > ++ } > ++ > +++ uint64_t max_off_count = (length - 8) / offset_size; > +++ if (offset_entry_count > max_off_count) > +++ offset_entry_count = max_off_count; > ++ if (offset_entry_count != 0) > ++ { > ++ printf (_("\n Offsets starting at %#tx:\n"), p - section->start); > ++@@ -8372,7 +8366,7 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > ++ } > ++ } > ++ > ++- return 1; > +++ return true; > ++ } > ++ > ++ static bool > ++@@ -8404,6 +8398,7 @@ display_debug_ranges (struct dwarf_section *section, > ++ uint64_t last_offset = 0; > ++ uint64_t next_rnglists_cu_offset = 0; > ++ unsigned char offset_size; > +++ bool ok_header = true; > ++ > ++ if (bytes == 0) > ++ { > ++@@ -8493,8 +8488,12 @@ display_debug_ranges (struct dwarf_section *section, > ++ /* If we've moved on to the next compile unit in the rnglists section - dump the unit header(s). */ > ++ if (is_rnglists && next_rnglists_cu_offset < offset) > ++ { > ++- while (next_rnglists_cu_offset < offset) > ++- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); > +++ while (ok_header && next_rnglists_cu_offset < offset) > +++ ok_header = display_debug_rnglists_unit_header (section, > +++ &next_rnglists_cu_offset, > +++ &offset_size); > +++ if (!ok_header) > +++ break; > ++ printf (_(" Offset Begin End\n")); > ++ } > ++ > ++@@ -8548,10 +8547,12 @@ display_debug_ranges (struct dwarf_section *section, > ++ } > ++ > ++ /* Display trailing empty (or unreferenced) compile units, if any. */ > ++- if (is_rnglists) > +++ if (is_rnglists && ok_header) > ++ while (next_rnglists_cu_offset < section->size) > ++- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); > ++- > +++ if (!display_debug_rnglists_unit_header (section, > +++ &next_rnglists_cu_offset, > +++ &offset_size)) > +++ break; > ++ putchar ('\n'); > ++ > ++ free (range_entries); > ++-- > ++2.35.6 > +-- > +2.51.0 > + > diff --git a/meta/recipes-devtools/binutils/binutils-2.45.inc b/meta/recipes-devtools/binutils/binutils-2.45.inc > index 16a63cabc5..b6d7b3d60f 100644 > --- a/meta/recipes-devtools/binutils/binutils-2.45.inc > +++ b/meta/recipes-devtools/binutils/binutils-2.45.inc > @@ -46,4 +46,5 @@ SRC_URI = "\ > file://0018-CVE-2025-11494.patch \ > file://0019-CVE-2025-11839.patch \ > file://0020-CVE-2025-11840.patch \ > + file://CVE-2025-69648.patch \ > " > diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch > new file mode 100644 > index 0000000000..ce0e764762 > --- /dev/null > +++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch > @@ -0,0 +1,189 @@ > +From 7df481dd76c05c89782721e9df5468be829c356b Mon Sep 17 00:00:00 2001 > +From: Alan Modra <amodra@gmail.com> > +Date: Sat, 22 Nov 2025 09:22:10 +1030 > +Subject: [PATCH] PR 33638, debug_rnglists output > + > +The fuzzed testcase in this PR continuously outputs an error about > +the debug_rnglists header. Fixed by taking notice of the error and > +stopping output. The patch also limits the length in all cases, not > +just when a relocation is present, and limits the offset entry count > +read from the header. I removed the warning and the test for relocs > +because the code can't work reliably with unresolved relocs in the > +length field. > + > + PR 33638 > + * dwarf.c (display_debug_rnglists_list): Return bool. Rename > + "inital_length" to plain "length". Verify length is large > + enough to read header. Limit length to rest of section. > + Similarly limit offset_entry_count. > + (display_debug_ranges): Check display_debug_rnglists_unit_header > + return status. Stop output on error. > + > +CVE: CVE-2025-69648 > +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33] > + > +(cherry picked from commit 598704a00cbac5e85c2bedd363357b5bf6fcee33) > +Signed-off-by: Deepak Rathore <deeratho@cisco.com> > +--- > + binutils/dwarf.c | 67 ++++++++++++++++++++++++------------------------ > + 1 file changed, 34 insertions(+), 33 deletions(-) > + > +diff --git a/binutils/dwarf.c b/binutils/dwarf.c > +index f4bcb677761..b4fb56351ec 100644 > +--- a/binutils/dwarf.c > ++++ b/binutils/dwarf.c > +@@ -8282,7 +8282,7 @@ display_debug_rnglists_list (unsigned char * start, > + return start; > + } > + > +-static int > ++static bool > + display_debug_rnglists_unit_header (struct dwarf_section * section, > + uint64_t * unit_offset, > + unsigned char * poffset_size) > +@@ -8290,7 +8290,8 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > + uint64_t start_offset = *unit_offset; > + unsigned char * p = section->start + start_offset; > + unsigned char * finish = section->start + section->size; > +- uint64_t initial_length; > ++ unsigned char * hdr; > ++ uint64_t length; > + unsigned char segment_selector_size; > + unsigned int offset_entry_count; > + unsigned int i; > +@@ -8299,66 +8300,59 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > + unsigned char offset_size; > + > + /* Get and check the length of the block. */ > +- SAFE_BYTE_GET_AND_INC (initial_length, p, 4, finish); > ++ SAFE_BYTE_GET_AND_INC (length, p, 4, finish); > + > +- if (initial_length == 0xffffffff) > ++ if (length == 0xffffffff) > + { > + /* This section is 64-bit DWARF 3. */ > +- SAFE_BYTE_GET_AND_INC (initial_length, p, 8, finish); > ++ SAFE_BYTE_GET_AND_INC (length, p, 8, finish); > + *poffset_size = offset_size = 8; > + } > + else > + *poffset_size = offset_size = 4; > + > +- if (initial_length > (size_t) (finish - p)) > +- { > +- /* If the length field has a relocation against it, then we should > +- not complain if it is inaccurate (and probably negative). > +- It is copied from .debug_line handling code. */ > +- if (reloc_at (section, (p - section->start) - offset_size)) > +- initial_length = finish - p; > +- else > +- { > +- warn (_("The length field (%#" PRIx64 > +- ") in the debug_rnglists header is wrong" > +- " - the section is too small\n"), > +- initial_length); > +- return 0; > +- } > +- } > +- > +- /* Report the next unit offset to the caller. */ > +- *unit_offset = (p - section->start) + initial_length; > ++ if (length < 8) > ++ return false; > + > + /* Get the other fields in the header. */ > ++ hdr = p; > + SAFE_BYTE_GET_AND_INC (version, p, 2, finish); > + SAFE_BYTE_GET_AND_INC (address_size, p, 1, finish); > + SAFE_BYTE_GET_AND_INC (segment_selector_size, p, 1, finish); > + SAFE_BYTE_GET_AND_INC (offset_entry_count, p, 4, finish); > + > + printf (_(" Table at Offset: %#" PRIx64 ":\n"), start_offset); > +- printf (_(" Length: %#" PRIx64 "\n"), initial_length); > ++ printf (_(" Length: %#" PRIx64 "\n"), length); > + printf (_(" DWARF version: %u\n"), version); > + printf (_(" Address size: %u\n"), address_size); > + printf (_(" Segment size: %u\n"), segment_selector_size); > + printf (_(" Offset entries: %u\n"), offset_entry_count); > + > ++ if (length > (size_t) (finish - hdr)) > ++ length = finish - hdr; > ++ > ++ /* Report the next unit offset to the caller. */ > ++ *unit_offset = (hdr - section->start) + length; > ++ > + /* Check the fields. */ > + if (segment_selector_size != 0) > + { > + warn (_("The %s section contains " > + "unsupported segment selector size: %d.\n"), > + section->name, segment_selector_size); > +- return 0; > ++ return false; > + } > + > + if (version < 5) > + { > + warn (_("Only DWARF version 5+ debug_rnglists info " > + "is currently supported.\n")); > +- return 0; > ++ return false; > + } > + > ++ uint64_t max_off_count = (length - 8) / offset_size; > ++ if (offset_entry_count > max_off_count) > ++ offset_entry_count = max_off_count; > + if (offset_entry_count != 0) > + { > + printf (_("\n Offsets starting at %#tx:\n"), p - section->start); > +@@ -8372,7 +8366,7 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, > + } > + } > + > +- return 1; > ++ return true; > + } > + > + static bool > +@@ -8404,6 +8398,7 @@ display_debug_ranges (struct dwarf_section *section, > + uint64_t last_offset = 0; > + uint64_t next_rnglists_cu_offset = 0; > + unsigned char offset_size; > ++ bool ok_header = true; > + > + if (bytes == 0) > + { > +@@ -8493,8 +8488,12 @@ display_debug_ranges (struct dwarf_section *section, > + /* If we've moved on to the next compile unit in the rnglists section - dump the unit header(s). */ > + if (is_rnglists && next_rnglists_cu_offset < offset) > + { > +- while (next_rnglists_cu_offset < offset) > +- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); > ++ while (ok_header && next_rnglists_cu_offset < offset) > ++ ok_header = display_debug_rnglists_unit_header (section, > ++ &next_rnglists_cu_offset, > ++ &offset_size); > ++ if (!ok_header) > ++ break; > + printf (_(" Offset Begin End\n")); > + } > + > +@@ -8548,10 +8547,12 @@ display_debug_ranges (struct dwarf_section *section, > + } > + > + /* Display trailing empty (or unreferenced) compile units, if any. */ > +- if (is_rnglists) > ++ if (is_rnglists && ok_header) > + while (next_rnglists_cu_offset < section->size) > +- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); > +- > ++ if (!display_debug_rnglists_unit_header (section, > ++ &next_rnglists_cu_offset, > ++ &offset_size)) > ++ break; > + putchar ('\n'); > + > + free (range_entries); > +-- > +2.35.6 > +
diff --git a/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch b/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch new file mode 100644 index 0000000000..70866fd7da --- /dev/null +++ b/meta/recipes-devtools/binutils/0001-pick-the-patch-1-as-mentioned-in-2.patch @@ -0,0 +1,222 @@ +From 507f05eb8f3a132a536c593e232fdc7878fb9bba Mon Sep 17 00:00:00 2001 +From: Deepak Rathore <deeratho@cisco.com> +Date: Tue, 31 Mar 2026 11:25:32 +0000 +Subject: [PATCH] pick the patch [1] as mentioned in [2]. + +[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33 +[2] https://nvd.nist.gov/vuln/detail/CVE-2025-69648 + +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + .../binutils/binutils-2.45.inc | 1 + + .../binutils/binutils/CVE-2025-69648.patch | 188 ++++++++++++++++++ + 2 files changed, 189 insertions(+) + create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch + +diff --git a/meta/recipes-devtools/binutils/binutils-2.45.inc b/meta/recipes-devtools/binutils/binutils-2.45.inc +index 16a63cabc5..b6d7b3d60f 100644 +--- a/meta/recipes-devtools/binutils/binutils-2.45.inc ++++ b/meta/recipes-devtools/binutils/binutils-2.45.inc +@@ -46,4 +46,5 @@ SRC_URI = "\ + file://0018-CVE-2025-11494.patch \ + file://0019-CVE-2025-11839.patch \ + file://0020-CVE-2025-11840.patch \ ++ file://CVE-2025-69648.patch \ + " +diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch +new file mode 100644 +index 0000000000..2346b18f01 +--- /dev/null ++++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch +@@ -0,0 +1,188 @@ ++From 7df481dd76c05c89782721e9df5468be829c356b Mon Sep 17 00:00:00 2001 ++From: Alan Modra <amodra@gmail.com> ++Date: Sat, 22 Nov 2025 09:22:10 +1030 ++Subject: [PATCH] PR 33638, debug_rnglists output ++ ++The fuzzed testcase in this PR continuously outputs an error about ++the debug_rnglists header. Fixed by taking notice of the error and ++stopping output. The patch also limits the length in all cases, not ++just when a relocation is present, and limits the offset entry count ++read from the header. I removed the warning and the test for relocs ++because the code can't work reliably with unresolved relocs in the ++length field. ++ ++ PR 33638 ++ * dwarf.c (display_debug_rnglists_list): Return bool. Rename ++ "inital_length" to plain "length". Verify length is large ++ enough to read header. Limit length to rest of section. ++ Similarly limit offset_entry_count. ++ (display_debug_ranges): Check display_debug_rnglists_unit_header ++ return status. Stop output on error. ++ ++CVE: CVE-2025-69648 ++Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33] ++ ++(cherry picked from commit 598704a00cbac5e85c2bedd363357b5bf6fcee33) ++Signed-off-by: Deepak Rathore <deeratho@cisco.com> ++--- ++ binutils/dwarf.c | 67 ++++++++++++++++++++++++------------------------ ++ 1 file changed, 34 insertions(+), 33 deletions(-) ++ ++diff --git a/binutils/dwarf.c b/binutils/dwarf.c ++index f4bcb677761..b4fb56351ec 100644 ++--- a/binutils/dwarf.c +++++ b/binutils/dwarf.c ++@@ -8282,7 +8282,7 @@ display_debug_rnglists_list (unsigned char * start, ++ return start; ++ } ++ ++-static int +++static bool ++ display_debug_rnglists_unit_header (struct dwarf_section * section, ++ uint64_t * unit_offset, ++ unsigned char * poffset_size) ++@@ -8290,7 +8290,8 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, ++ uint64_t start_offset = *unit_offset; ++ unsigned char * p = section->start + start_offset; ++ unsigned char * finish = section->start + section->size; ++- uint64_t initial_length; +++ unsigned char * hdr; +++ uint64_t length; ++ unsigned char segment_selector_size; ++ unsigned int offset_entry_count; ++ unsigned int i; ++@@ -8299,66 +8300,59 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, ++ unsigned char offset_size; ++ ++ /* Get and check the length of the block. */ ++- SAFE_BYTE_GET_AND_INC (initial_length, p, 4, finish); +++ SAFE_BYTE_GET_AND_INC (length, p, 4, finish); ++ ++- if (initial_length == 0xffffffff) +++ if (length == 0xffffffff) ++ { ++ /* This section is 64-bit DWARF 3. */ ++- SAFE_BYTE_GET_AND_INC (initial_length, p, 8, finish); +++ SAFE_BYTE_GET_AND_INC (length, p, 8, finish); ++ *poffset_size = offset_size = 8; ++ } ++ else ++ *poffset_size = offset_size = 4; ++ ++- if (initial_length > (size_t) (finish - p)) ++- { ++- /* If the length field has a relocation against it, then we should ++- not complain if it is inaccurate (and probably negative). ++- It is copied from .debug_line handling code. */ ++- if (reloc_at (section, (p - section->start) - offset_size)) ++- initial_length = finish - p; ++- else ++- { ++- warn (_("The length field (%#" PRIx64 ++- ") in the debug_rnglists header is wrong" ++- " - the section is too small\n"), ++- initial_length); ++- return 0; ++- } ++- } ++- ++- /* Report the next unit offset to the caller. */ ++- *unit_offset = (p - section->start) + initial_length; +++ if (length < 8) +++ return false; ++ ++ /* Get the other fields in the header. */ +++ hdr = p; ++ SAFE_BYTE_GET_AND_INC (version, p, 2, finish); ++ SAFE_BYTE_GET_AND_INC (address_size, p, 1, finish); ++ SAFE_BYTE_GET_AND_INC (segment_selector_size, p, 1, finish); ++ SAFE_BYTE_GET_AND_INC (offset_entry_count, p, 4, finish); ++ ++ printf (_(" Table at Offset: %#" PRIx64 ":\n"), start_offset); ++- printf (_(" Length: %#" PRIx64 "\n"), initial_length); +++ printf (_(" Length: %#" PRIx64 "\n"), length); ++ printf (_(" DWARF version: %u\n"), version); ++ printf (_(" Address size: %u\n"), address_size); ++ printf (_(" Segment size: %u\n"), segment_selector_size); ++ printf (_(" Offset entries: %u\n"), offset_entry_count); ++ +++ if (length > (size_t) (finish - hdr)) +++ length = finish - hdr; +++ +++ /* Report the next unit offset to the caller. */ +++ *unit_offset = (hdr - section->start) + length; +++ ++ /* Check the fields. */ ++ if (segment_selector_size != 0) ++ { ++ warn (_("The %s section contains " ++ "unsupported segment selector size: %d.\n"), ++ section->name, segment_selector_size); ++- return 0; +++ return false; ++ } ++ ++ if (version < 5) ++ { ++ warn (_("Only DWARF version 5+ debug_rnglists info " ++ "is currently supported.\n")); ++- return 0; +++ return false; ++ } ++ +++ uint64_t max_off_count = (length - 8) / offset_size; +++ if (offset_entry_count > max_off_count) +++ offset_entry_count = max_off_count; ++ if (offset_entry_count != 0) ++ { ++ printf (_("\n Offsets starting at %#tx:\n"), p - section->start); ++@@ -8372,7 +8366,7 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, ++ } ++ } ++ ++- return 1; +++ return true; ++ } ++ ++ static bool ++@@ -8404,6 +8398,7 @@ display_debug_ranges (struct dwarf_section *section, ++ uint64_t last_offset = 0; ++ uint64_t next_rnglists_cu_offset = 0; ++ unsigned char offset_size; +++ bool ok_header = true; ++ ++ if (bytes == 0) ++ { ++@@ -8493,8 +8488,12 @@ display_debug_ranges (struct dwarf_section *section, ++ /* If we've moved on to the next compile unit in the rnglists section - dump the unit header(s). */ ++ if (is_rnglists && next_rnglists_cu_offset < offset) ++ { ++- while (next_rnglists_cu_offset < offset) ++- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); +++ while (ok_header && next_rnglists_cu_offset < offset) +++ ok_header = display_debug_rnglists_unit_header (section, +++ &next_rnglists_cu_offset, +++ &offset_size); +++ if (!ok_header) +++ break; ++ printf (_(" Offset Begin End\n")); ++ } ++ ++@@ -8548,10 +8547,12 @@ display_debug_ranges (struct dwarf_section *section, ++ } ++ ++ /* Display trailing empty (or unreferenced) compile units, if any. */ ++- if (is_rnglists) +++ if (is_rnglists && ok_header) ++ while (next_rnglists_cu_offset < section->size) ++- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); ++- +++ if (!display_debug_rnglists_unit_header (section, +++ &next_rnglists_cu_offset, +++ &offset_size)) +++ break; ++ putchar ('\n'); ++ ++ free (range_entries); ++-- ++2.35.6 +-- +2.51.0 + diff --git a/meta/recipes-devtools/binutils/binutils-2.45.inc b/meta/recipes-devtools/binutils/binutils-2.45.inc index 16a63cabc5..b6d7b3d60f 100644 --- a/meta/recipes-devtools/binutils/binutils-2.45.inc +++ b/meta/recipes-devtools/binutils/binutils-2.45.inc @@ -46,4 +46,5 @@ SRC_URI = "\ file://0018-CVE-2025-11494.patch \ file://0019-CVE-2025-11839.patch \ file://0020-CVE-2025-11840.patch \ + file://CVE-2025-69648.patch \ " diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch new file mode 100644 index 0000000000..ce0e764762 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-69648.patch @@ -0,0 +1,189 @@ +From 7df481dd76c05c89782721e9df5468be829c356b Mon Sep 17 00:00:00 2001 +From: Alan Modra <amodra@gmail.com> +Date: Sat, 22 Nov 2025 09:22:10 +1030 +Subject: [PATCH] PR 33638, debug_rnglists output + +The fuzzed testcase in this PR continuously outputs an error about +the debug_rnglists header. Fixed by taking notice of the error and +stopping output. The patch also limits the length in all cases, not +just when a relocation is present, and limits the offset entry count +read from the header. I removed the warning and the test for relocs +because the code can't work reliably with unresolved relocs in the +length field. + + PR 33638 + * dwarf.c (display_debug_rnglists_list): Return bool. Rename + "inital_length" to plain "length". Verify length is large + enough to read header. Limit length to rest of section. + Similarly limit offset_entry_count. + (display_debug_ranges): Check display_debug_rnglists_unit_header + return status. Stop output on error. + +CVE: CVE-2025-69648 +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=598704a00cbac5e85c2bedd363357b5bf6fcee33] + +(cherry picked from commit 598704a00cbac5e85c2bedd363357b5bf6fcee33) +Signed-off-by: Deepak Rathore <deeratho@cisco.com> +--- + binutils/dwarf.c | 67 ++++++++++++++++++++++++------------------------ + 1 file changed, 34 insertions(+), 33 deletions(-) + +diff --git a/binutils/dwarf.c b/binutils/dwarf.c +index f4bcb677761..b4fb56351ec 100644 +--- a/binutils/dwarf.c ++++ b/binutils/dwarf.c +@@ -8282,7 +8282,7 @@ display_debug_rnglists_list (unsigned char * start, + return start; + } + +-static int ++static bool + display_debug_rnglists_unit_header (struct dwarf_section * section, + uint64_t * unit_offset, + unsigned char * poffset_size) +@@ -8290,7 +8290,8 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, + uint64_t start_offset = *unit_offset; + unsigned char * p = section->start + start_offset; + unsigned char * finish = section->start + section->size; +- uint64_t initial_length; ++ unsigned char * hdr; ++ uint64_t length; + unsigned char segment_selector_size; + unsigned int offset_entry_count; + unsigned int i; +@@ -8299,66 +8300,59 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, + unsigned char offset_size; + + /* Get and check the length of the block. */ +- SAFE_BYTE_GET_AND_INC (initial_length, p, 4, finish); ++ SAFE_BYTE_GET_AND_INC (length, p, 4, finish); + +- if (initial_length == 0xffffffff) ++ if (length == 0xffffffff) + { + /* This section is 64-bit DWARF 3. */ +- SAFE_BYTE_GET_AND_INC (initial_length, p, 8, finish); ++ SAFE_BYTE_GET_AND_INC (length, p, 8, finish); + *poffset_size = offset_size = 8; + } + else + *poffset_size = offset_size = 4; + +- if (initial_length > (size_t) (finish - p)) +- { +- /* If the length field has a relocation against it, then we should +- not complain if it is inaccurate (and probably negative). +- It is copied from .debug_line handling code. */ +- if (reloc_at (section, (p - section->start) - offset_size)) +- initial_length = finish - p; +- else +- { +- warn (_("The length field (%#" PRIx64 +- ") in the debug_rnglists header is wrong" +- " - the section is too small\n"), +- initial_length); +- return 0; +- } +- } +- +- /* Report the next unit offset to the caller. */ +- *unit_offset = (p - section->start) + initial_length; ++ if (length < 8) ++ return false; + + /* Get the other fields in the header. */ ++ hdr = p; + SAFE_BYTE_GET_AND_INC (version, p, 2, finish); + SAFE_BYTE_GET_AND_INC (address_size, p, 1, finish); + SAFE_BYTE_GET_AND_INC (segment_selector_size, p, 1, finish); + SAFE_BYTE_GET_AND_INC (offset_entry_count, p, 4, finish); + + printf (_(" Table at Offset: %#" PRIx64 ":\n"), start_offset); +- printf (_(" Length: %#" PRIx64 "\n"), initial_length); ++ printf (_(" Length: %#" PRIx64 "\n"), length); + printf (_(" DWARF version: %u\n"), version); + printf (_(" Address size: %u\n"), address_size); + printf (_(" Segment size: %u\n"), segment_selector_size); + printf (_(" Offset entries: %u\n"), offset_entry_count); + ++ if (length > (size_t) (finish - hdr)) ++ length = finish - hdr; ++ ++ /* Report the next unit offset to the caller. */ ++ *unit_offset = (hdr - section->start) + length; ++ + /* Check the fields. */ + if (segment_selector_size != 0) + { + warn (_("The %s section contains " + "unsupported segment selector size: %d.\n"), + section->name, segment_selector_size); +- return 0; ++ return false; + } + + if (version < 5) + { + warn (_("Only DWARF version 5+ debug_rnglists info " + "is currently supported.\n")); +- return 0; ++ return false; + } + ++ uint64_t max_off_count = (length - 8) / offset_size; ++ if (offset_entry_count > max_off_count) ++ offset_entry_count = max_off_count; + if (offset_entry_count != 0) + { + printf (_("\n Offsets starting at %#tx:\n"), p - section->start); +@@ -8372,7 +8366,7 @@ display_debug_rnglists_unit_header (struct dwarf_section * section, + } + } + +- return 1; ++ return true; + } + + static bool +@@ -8404,6 +8398,7 @@ display_debug_ranges (struct dwarf_section *section, + uint64_t last_offset = 0; + uint64_t next_rnglists_cu_offset = 0; + unsigned char offset_size; ++ bool ok_header = true; + + if (bytes == 0) + { +@@ -8493,8 +8488,12 @@ display_debug_ranges (struct dwarf_section *section, + /* If we've moved on to the next compile unit in the rnglists section - dump the unit header(s). */ + if (is_rnglists && next_rnglists_cu_offset < offset) + { +- while (next_rnglists_cu_offset < offset) +- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); ++ while (ok_header && next_rnglists_cu_offset < offset) ++ ok_header = display_debug_rnglists_unit_header (section, ++ &next_rnglists_cu_offset, ++ &offset_size); ++ if (!ok_header) ++ break; + printf (_(" Offset Begin End\n")); + } + +@@ -8548,10 +8547,12 @@ display_debug_ranges (struct dwarf_section *section, + } + + /* Display trailing empty (or unreferenced) compile units, if any. */ +- if (is_rnglists) ++ if (is_rnglists && ok_header) + while (next_rnglists_cu_offset < section->size) +- display_debug_rnglists_unit_header (section, &next_rnglists_cu_offset, &offset_size); +- ++ if (!display_debug_rnglists_unit_header (section, ++ &next_rnglists_cu_offset, ++ &offset_size)) ++ break; + putchar ('\n'); + + free (range_entries); +-- +2.35.6 +