From 5eb5978c92ea95abfa38e5a5156f408d1a95d256 Mon Sep 17 00:00:00 2001 From: deepin-ci-robot Date: Wed, 15 Apr 2026 13:38:48 +0800 Subject: [PATCH] binutils: Fix CVE-2026-4647: Out-of-bounds read in XCOFF relocation processing A flaw was found in the GNU Binutils BFD library when processing XCOFF object files. The relocation type value is not properly validated before being used, which can cause the program to read memory outside of intended bounds. This fix adds proper validation of reloc r_type before accessing xcoff_howto_table to prevent out-of-bounds memory access. Upstream: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9e99dbc1f19ffaf18d0250788951706066ebe7f2 --- debian/changelog | 6 + debian/patches/CVE-2026-4647.patch | 236 +++++++++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 243 insertions(+) create mode 100644 debian/patches/CVE-2026-4647.patch diff --git a/debian/changelog b/debian/changelog index ed7691fa1..f15f5d1de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +binutils (2.41-6deepin11) unstable; urgency=medium + + * Fix CVE-2026-4647: Out-of-bounds read in XCOFF relocation processing + + -- deepin-ci-robot Wed, 15 Apr 2026 13:38:01 +0800 + binutils (2.41-6deepin10) unstable; urgency=medium * fix CVE-2024-57360 CVE-2024-53589 CVE-2025-0840 CVE-2025-1176 CVE-2025-1178 diff --git a/debian/patches/CVE-2026-4647.patch b/debian/patches/CVE-2026-4647.patch new file mode 100644 index 000000000..ee386d900 --- /dev/null +++ b/debian/patches/CVE-2026-4647.patch @@ -0,0 +1,236 @@ +Description: Fix out-of-bounds read in XCOFF relocation processing + A flaw was found in the GNU Binutils BFD library when processing XCOFF object + files. The relocation type value is not properly validated before being used, + which can cause the program to read memory outside of intended bounds. + . + This fix adds proper validation of reloc r_type before accessing + xcoff_howto_table to prevent out-of-bounds memory access. +Author: Alan Modra +Origin: upstream, https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9e99dbc1f19ffaf18d0250788951706066ebe7f2 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33919 +Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-4647 +Forwarded: not-needed +Last-Update: 2026-04-15 + +From 9e99dbc1f19ffaf18d0250788951706066ebe7f2 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 13 Mar 2026 17:28:28 +1030 +Subject: [PATCH] PR33919 Out-of-bounds read in XCOFF relocation processing + + PR 33919 + * coff-rs6000.c (xcoff_calculate_relocation): Don't use explicit + array size. + (xcoff_complain_overflow): Likewise. + (xcoff_rtype2howto): Return a NULL howto rather than aborting. + (_bfd_xcoff_reloc_name_lookup): Use ARRAY_SIZE. + (xcoff_ppc_relocate_section): Sanity check reloc r_type before + accessing xcoff_howto_table. Print r_type using %#x. Remove + now redundant later reloc r_type sanity check. + * coff64-rs6000.c: Similarly. + * libxcoff.h (XCOFF_MAX_CALCULATE_RELOCATION): Don't define. + (XCOFF_MAX_COMPLAIN_OVERFLOW): Don't define. +--- + bfd/coff-rs6000.c | 36 +++++++++++++++++++++--------------- + bfd/coff64-rs6000.c | 33 ++++++++++++++++++++------------- + bfd/libxcoff.h | 3 --- + 3 files changed, 41 insertions(+), 31 deletions(-) + +diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c +index 62caae64f4e..00e0f5442f7 100644 +--- a/bfd/coff-rs6000.c ++++ b/bfd/coff-rs6000.c +@@ -155,8 +155,7 @@ static xcoff_complain_function xcoff_complain_overflow_bitfield_func; + static xcoff_complain_function xcoff_complain_overflow_signed_func; + static xcoff_complain_function xcoff_complain_overflow_unsigned_func; + +-xcoff_reloc_function *const +-xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = ++xcoff_reloc_function *const xcoff_calculate_relocation[] = + { + xcoff_reloc_type_pos, /* R_POS (0x00) */ + xcoff_reloc_type_neg, /* R_NEG (0x01) */ +@@ -210,8 +209,7 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = + xcoff_reloc_type_toc, /* R_TOCL (0x31) */ + }; + +-xcoff_complain_function *const +-xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW] = ++xcoff_complain_function *const xcoff_complain_overflow[] = + { + xcoff_complain_overflow_dont_func, + xcoff_complain_overflow_bitfield_func, +@@ -1158,8 +1156,11 @@ reloc_howto_type xcoff_howto_table[] = + void + xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) + { +- if (internal->r_type > R_TOCL) +- abort (); ++ if (internal->r_type >= ARRAY_SIZE (xcoff_howto_table)) ++ { ++ relent->howto = NULL; ++ return; ++ } + + /* Default howto layout works most of the time */ + relent->howto = &xcoff_howto_table[internal->r_type]; +@@ -1183,7 +1184,7 @@ xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) + if (relent->howto->dst_mask != 0 + && (relent->howto->bitsize + != ((unsigned int) internal->r_size & 0x1f) + 1)) +- abort (); ++ relent->howto = NULL; + } + + reloc_howto_type * +@@ -1236,9 +1237,7 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + { + unsigned int i; + +- for (i = 0; +- i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]); +- i++) ++ for (i = 0; i < ARRAY_SIZE (xcoff_howto_table); i++) + if (xcoff_howto_table[i].name != NULL + && strcasecmp (xcoff_howto_table[i].name, r_name) == 0) + return &xcoff_howto_table[i]; +@@ -3768,6 +3767,14 @@ xcoff_ppc_relocate_section (bfd *output_bfd, + the csect including the symbol which it references. */ + if (rel->r_type == R_REF) + continue; ++ if (rel->r_type >= ARRAY_SIZE (xcoff_howto_table)) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), ++ input_bfd, rel->r_type); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } + + /* Retrieve default value in HOWTO table and fix up according + to r_size field, if it can be different. +@@ -3787,7 +3794,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd, + + default: + _bfd_error_handler +- (_("%pB: relocation (%d) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), ++ (_("%pB: relocation (%#x) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), + input_bfd, rel->r_type, (uint64_t) rel->r_vaddr, rel->r_size); + return false; + } +@@ -3863,10 +3870,9 @@ xcoff_ppc_relocate_section (bfd *output_bfd, + } + } + +- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION +- || !((*xcoff_calculate_relocation[rel->r_type]) +- (input_bfd, input_section, output_bfd, rel, sym, &howto, val, +- addend, &relocation, contents, info))) ++ if (!((*xcoff_calculate_relocation[rel->r_type]) ++ (input_bfd, input_section, output_bfd, rel, sym, &howto, val, ++ addend, &relocation, contents, info))) + return false; + + /* address */ +diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c +index fa1759b5925..f6a60433e62 100644 +--- a/bfd/coff64-rs6000.c ++++ b/bfd/coff64-rs6000.c +@@ -177,8 +177,7 @@ static bool xcoff64_bad_format_hook + /* Relocation functions */ + static xcoff_reloc_function xcoff64_reloc_type_br; + +-xcoff_reloc_function *const +-xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = ++xcoff_reloc_function *const xcoff64_calculate_relocation[] = + { + xcoff_reloc_type_pos, /* R_POS (0x00) */ + xcoff_reloc_type_neg, /* R_NEG (0x01) */ +@@ -1439,8 +1438,11 @@ reloc_howto_type xcoff64_howto_table[] = + void + xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) + { +- if (internal->r_type > R_TOCL) +- abort (); ++ if (internal->r_type >= ARRAY_SIZE (xcoff64_howto_table)) ++ { ++ relent->howto = NULL; ++ return; ++ } + + /* Default howto layout works most of the time */ + relent->howto = &xcoff64_howto_table[internal->r_type]; +@@ -1473,7 +1475,7 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) + if (relent->howto->dst_mask != 0 + && (relent->howto->bitsize + != ((unsigned int) internal->r_size & 0x3f) + 1)) +- abort (); ++ relent->howto = NULL; + } + + reloc_howto_type * +@@ -1528,9 +1530,7 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + { + unsigned int i; + +- for (i = 0; +- i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]); +- i++) ++ for (i = 0; i < ARRAY_SIZE (xcoff64_howto_table); i++) + if (xcoff64_howto_table[i].name != NULL + && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0) + return &xcoff64_howto_table[i]; +@@ -1574,6 +1574,14 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, + the csect including the symbol which it references. */ + if (rel->r_type == R_REF) + continue; ++ if (rel->r_type >= ARRAY_SIZE (xcoff64_howto_table)) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), ++ input_bfd, rel->r_type); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } + + /* Retrieve default value in HOWTO table and fix up according + to r_size field, if it can be different. +@@ -1595,7 +1603,7 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, + + default: + _bfd_error_handler +- (_("%pB: relocation (%d) at (0x%" PRIx64 ") has wrong" ++ (_("%pB: relocation (%#x) at (0x%" PRIx64 ") has wrong" + " r_rsize (0x%x)\n"), + input_bfd, rel->r_type, rel->r_vaddr, rel->r_size); + return false; +@@ -1668,10 +1676,9 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, + } + } + +- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION +- || !((*xcoff64_calculate_relocation[rel->r_type]) +- (input_bfd, input_section, output_bfd, rel, sym, &howto, val, +- addend, &relocation, contents, info))) ++ if (!((*xcoff64_calculate_relocation[rel->r_type]) ++ (input_bfd, input_section, output_bfd, rel, sym, &howto, val, ++ addend, &relocation, contents, info))) + return false; + + /* address */ +diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h +index c116d9b795f..e6b87975ff6 100644 +--- a/bfd/libxcoff.h ++++ b/bfd/libxcoff.h +@@ -217,9 +217,6 @@ struct xcoff_backend_data_rec + #define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power)) + #define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power)) + +-/* xcoff*_ppc_relocate_section macros */ +-#define XCOFF_MAX_CALCULATE_RELOCATION (0x32) +-#define XCOFF_MAX_COMPLAIN_OVERFLOW (4) + /* N_ONES produces N one bits, without overflowing machine arithmetic. */ + #ifdef N_ONES + #undef N_ONES +-- +2.43.7 + diff --git a/debian/patches/series b/debian/patches/series index be559da7e..e50d8b2fb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -186,3 +186,4 @@ CVE-2025-5245.patch CVE-2025-7545.patch CVE-2025-7546.patch CVE-2025-8225.patch +CVE-2026-4647.patch