Skip to content

Commit 5eb5978

Browse files
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
1 parent 4e73a0b commit 5eb5978

3 files changed

Lines changed: 243 additions & 0 deletions

File tree

debian/changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
binutils (2.41-6deepin11) unstable; urgency=medium
2+
3+
* Fix CVE-2026-4647: Out-of-bounds read in XCOFF relocation processing
4+
5+
-- deepin-ci-robot <packages@deepin.org> Wed, 15 Apr 2026 13:38:01 +0800
6+
17
binutils (2.41-6deepin10) unstable; urgency=medium
28

39
* fix CVE-2024-57360 CVE-2024-53589 CVE-2025-0840 CVE-2025-1176 CVE-2025-1178

debian/patches/CVE-2026-4647.patch

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
Description: Fix out-of-bounds read in XCOFF relocation processing
2+
A flaw was found in the GNU Binutils BFD library when processing XCOFF object
3+
files. The relocation type value is not properly validated before being used,
4+
which can cause the program to read memory outside of intended bounds.
5+
.
6+
This fix adds proper validation of reloc r_type before accessing
7+
xcoff_howto_table to prevent out-of-bounds memory access.
8+
Author: Alan Modra <amodra@gmail.com>
9+
Origin: upstream, https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9e99dbc1f19ffaf18d0250788951706066ebe7f2
10+
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33919
11+
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-4647
12+
Forwarded: not-needed
13+
Last-Update: 2026-04-15
14+
15+
From 9e99dbc1f19ffaf18d0250788951706066ebe7f2 Mon Sep 17 00:00:00 2001
16+
From: Alan Modra <amodra@gmail.com>
17+
Date: Fri, 13 Mar 2026 17:28:28 +1030
18+
Subject: [PATCH] PR33919 Out-of-bounds read in XCOFF relocation processing
19+
20+
PR 33919
21+
* coff-rs6000.c (xcoff_calculate_relocation): Don't use explicit
22+
array size.
23+
(xcoff_complain_overflow): Likewise.
24+
(xcoff_rtype2howto): Return a NULL howto rather than aborting.
25+
(_bfd_xcoff_reloc_name_lookup): Use ARRAY_SIZE.
26+
(xcoff_ppc_relocate_section): Sanity check reloc r_type before
27+
accessing xcoff_howto_table. Print r_type using %#x. Remove
28+
now redundant later reloc r_type sanity check.
29+
* coff64-rs6000.c: Similarly.
30+
* libxcoff.h (XCOFF_MAX_CALCULATE_RELOCATION): Don't define.
31+
(XCOFF_MAX_COMPLAIN_OVERFLOW): Don't define.
32+
---
33+
bfd/coff-rs6000.c | 36 +++++++++++++++++++++---------------
34+
bfd/coff64-rs6000.c | 33 ++++++++++++++++++++-------------
35+
bfd/libxcoff.h | 3 ---
36+
3 files changed, 41 insertions(+), 31 deletions(-)
37+
38+
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
39+
index 62caae64f4e..00e0f5442f7 100644
40+
--- a/bfd/coff-rs6000.c
41+
+++ b/bfd/coff-rs6000.c
42+
@@ -155,8 +155,7 @@ static xcoff_complain_function xcoff_complain_overflow_bitfield_func;
43+
static xcoff_complain_function xcoff_complain_overflow_signed_func;
44+
static xcoff_complain_function xcoff_complain_overflow_unsigned_func;
45+
46+
-xcoff_reloc_function *const
47+
-xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
48+
+xcoff_reloc_function *const xcoff_calculate_relocation[] =
49+
{
50+
xcoff_reloc_type_pos, /* R_POS (0x00) */
51+
xcoff_reloc_type_neg, /* R_NEG (0x01) */
52+
@@ -210,8 +209,7 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
53+
xcoff_reloc_type_toc, /* R_TOCL (0x31) */
54+
};
55+
56+
-xcoff_complain_function *const
57+
-xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW] =
58+
+xcoff_complain_function *const xcoff_complain_overflow[] =
59+
{
60+
xcoff_complain_overflow_dont_func,
61+
xcoff_complain_overflow_bitfield_func,
62+
@@ -1158,8 +1156,11 @@ reloc_howto_type xcoff_howto_table[] =
63+
void
64+
xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal)
65+
{
66+
- if (internal->r_type > R_TOCL)
67+
- abort ();
68+
+ if (internal->r_type >= ARRAY_SIZE (xcoff_howto_table))
69+
+ {
70+
+ relent->howto = NULL;
71+
+ return;
72+
+ }
73+
74+
/* Default howto layout works most of the time */
75+
relent->howto = &xcoff_howto_table[internal->r_type];
76+
@@ -1183,7 +1184,7 @@ xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal)
77+
if (relent->howto->dst_mask != 0
78+
&& (relent->howto->bitsize
79+
!= ((unsigned int) internal->r_size & 0x1f) + 1))
80+
- abort ();
81+
+ relent->howto = NULL;
82+
}
83+
84+
reloc_howto_type *
85+
@@ -1236,9 +1237,7 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
86+
{
87+
unsigned int i;
88+
89+
- for (i = 0;
90+
- i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]);
91+
- i++)
92+
+ for (i = 0; i < ARRAY_SIZE (xcoff_howto_table); i++)
93+
if (xcoff_howto_table[i].name != NULL
94+
&& strcasecmp (xcoff_howto_table[i].name, r_name) == 0)
95+
return &xcoff_howto_table[i];
96+
@@ -3768,6 +3767,14 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
97+
the csect including the symbol which it references. */
98+
if (rel->r_type == R_REF)
99+
continue;
100+
+ if (rel->r_type >= ARRAY_SIZE (xcoff_howto_table))
101+
+ {
102+
+ /* xgettext:c-format */
103+
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
104+
+ input_bfd, rel->r_type);
105+
+ bfd_set_error (bfd_error_bad_value);
106+
+ return false;
107+
+ }
108+
109+
/* Retrieve default value in HOWTO table and fix up according
110+
to r_size field, if it can be different.
111+
@@ -3787,7 +3794,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
112+
113+
default:
114+
_bfd_error_handler
115+
- (_("%pB: relocation (%d) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"),
116+
+ (_("%pB: relocation (%#x) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"),
117+
input_bfd, rel->r_type, (uint64_t) rel->r_vaddr, rel->r_size);
118+
return false;
119+
}
120+
@@ -3863,10 +3870,9 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
121+
}
122+
}
123+
124+
- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
125+
- || !((*xcoff_calculate_relocation[rel->r_type])
126+
- (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
127+
- addend, &relocation, contents, info)))
128+
+ if (!((*xcoff_calculate_relocation[rel->r_type])
129+
+ (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
130+
+ addend, &relocation, contents, info)))
131+
return false;
132+
133+
/* address */
134+
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
135+
index fa1759b5925..f6a60433e62 100644
136+
--- a/bfd/coff64-rs6000.c
137+
+++ b/bfd/coff64-rs6000.c
138+
@@ -177,8 +177,7 @@ static bool xcoff64_bad_format_hook
139+
/* Relocation functions */
140+
static xcoff_reloc_function xcoff64_reloc_type_br;
141+
142+
-xcoff_reloc_function *const
143+
-xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
144+
+xcoff_reloc_function *const xcoff64_calculate_relocation[] =
145+
{
146+
xcoff_reloc_type_pos, /* R_POS (0x00) */
147+
xcoff_reloc_type_neg, /* R_NEG (0x01) */
148+
@@ -1439,8 +1438,11 @@ reloc_howto_type xcoff64_howto_table[] =
149+
void
150+
xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal)
151+
{
152+
- if (internal->r_type > R_TOCL)
153+
- abort ();
154+
+ if (internal->r_type >= ARRAY_SIZE (xcoff64_howto_table))
155+
+ {
156+
+ relent->howto = NULL;
157+
+ return;
158+
+ }
159+
160+
/* Default howto layout works most of the time */
161+
relent->howto = &xcoff64_howto_table[internal->r_type];
162+
@@ -1473,7 +1475,7 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal)
163+
if (relent->howto->dst_mask != 0
164+
&& (relent->howto->bitsize
165+
!= ((unsigned int) internal->r_size & 0x3f) + 1))
166+
- abort ();
167+
+ relent->howto = NULL;
168+
}
169+
170+
reloc_howto_type *
171+
@@ -1528,9 +1530,7 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
172+
{
173+
unsigned int i;
174+
175+
- for (i = 0;
176+
- i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
177+
- i++)
178+
+ for (i = 0; i < ARRAY_SIZE (xcoff64_howto_table); i++)
179+
if (xcoff64_howto_table[i].name != NULL
180+
&& strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
181+
return &xcoff64_howto_table[i];
182+
@@ -1574,6 +1574,14 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
183+
the csect including the symbol which it references. */
184+
if (rel->r_type == R_REF)
185+
continue;
186+
+ if (rel->r_type >= ARRAY_SIZE (xcoff64_howto_table))
187+
+ {
188+
+ /* xgettext:c-format */
189+
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
190+
+ input_bfd, rel->r_type);
191+
+ bfd_set_error (bfd_error_bad_value);
192+
+ return false;
193+
+ }
194+
195+
/* Retrieve default value in HOWTO table and fix up according
196+
to r_size field, if it can be different.
197+
@@ -1595,7 +1603,7 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
198+
199+
default:
200+
_bfd_error_handler
201+
- (_("%pB: relocation (%d) at (0x%" PRIx64 ") has wrong"
202+
+ (_("%pB: relocation (%#x) at (0x%" PRIx64 ") has wrong"
203+
" r_rsize (0x%x)\n"),
204+
input_bfd, rel->r_type, rel->r_vaddr, rel->r_size);
205+
return false;
206+
@@ -1668,10 +1676,9 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
207+
}
208+
}
209+
210+
- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
211+
- || !((*xcoff64_calculate_relocation[rel->r_type])
212+
- (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
213+
- addend, &relocation, contents, info)))
214+
+ if (!((*xcoff64_calculate_relocation[rel->r_type])
215+
+ (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
216+
+ addend, &relocation, contents, info)))
217+
return false;
218+
219+
/* address */
220+
diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h
221+
index c116d9b795f..e6b87975ff6 100644
222+
--- a/bfd/libxcoff.h
223+
+++ b/bfd/libxcoff.h
224+
@@ -217,9 +217,6 @@ struct xcoff_backend_data_rec
225+
#define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power))
226+
#define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power))
227+
228+
-/* xcoff*_ppc_relocate_section macros */
229+
-#define XCOFF_MAX_CALCULATE_RELOCATION (0x32)
230+
-#define XCOFF_MAX_COMPLAIN_OVERFLOW (4)
231+
/* N_ONES produces N one bits, without overflowing machine arithmetic. */
232+
#ifdef N_ONES
233+
#undef N_ONES
234+
--
235+
2.43.7
236+

debian/patches/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,4 @@ CVE-2025-5245.patch
186186
CVE-2025-7545.patch
187187
CVE-2025-7546.patch
188188
CVE-2025-8225.patch
189+
CVE-2026-4647.patch

0 commit comments

Comments
 (0)