Bug 2507670 (CVE-2026-18220)
| Summary: | CVE-2026-18220 binutils: binutils: Out-of-bounds write in BFD DLX ELF backend relocation processing | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security <prodsec-ir-bot> |
| Status: | NEW --- | QA Contact: | |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | unspecified | CC: | aburgess, gtanzill, jbuscemi, patrick, rhel-process-autobot, security-response-team, watson-tool-maintainers |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
An out-of-bounds write vulnerability was found in the BFD library's DLX ELF backend (bfd/elf32-dlx.c) in GNU binutils. The dlx_rtype_to_howto() function maps ELF relocation types to internal howto structures but fails to perform adequate bounds checking on attacker-controlled relocation type values (via ELF32_R_TYPE(r_info)) before indexing into the dlx_elf_howto_table[] array. The DLX relocation type number space is non-contiguous (basic types 0-6, extended types at 0x10000+), but the default case in the switch statement allows arbitrary index values to reach the array access.
A specially crafted ELF/DLX object file can trigger this out-of-bounds write when processed by any BFD-consuming tool (objdump, readelf, strip, ld, nm, objcopy). The vulnerability has been demonstrated to achieve arbitrary code execution via a File Stream Oriented Programming (FSOP) attack against glibc FILE structures (stderr), redirecting control flow to system().
Attack scenarios include CI/CD pipelines performing automated binary analysis, developer workstations running objdump/readelf on untrusted binaries, automated security scanning or malware analysis tools invoking binutils, and package build systems processing third-party code.
Note: This vulnerability is only exploitable when binutils is built with the DLX backend enabled (typically via --enable-targets=all).
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 2508331, 2508332, 2508335, 2508337, 2508330, 2508333 | ||
| Bug Blocks: | |||
|
Description
OSIDB Bzimport
2026-07-27 20:25:55 UTC
I took a look at the code discussed here. First the claim that: "The DLX relocation type number space is non-contiguous (basic types 0-6, extended types at 0x10000+), ..."
As far as I can see the DLS relocation numbers are defined in include/elf/dlx.h and run from 0 to 9 inclusive with R_DLX_max being defined as 10. So this claim seems to be incorrect.
Then the function `dlx_rtype_to_howto`, here it is with some additional annotation comments added by me:
static reloc_howto_type *
dlx_rtype_to_howto (bfd *abfd, unsigned int r_type)
{
switch (r_type)
{
case R_DLX_RELOC_16_PCREL: /* r_type == 8 */
return & elf_dlx_gnu_rel16_s2;
case R_DLX_RELOC_26_PCREL: /* r_type == 9 */
return & elf_dlx_gnu_rel26_s2;
case R_DLX_RELOC_16_HI: /* r_type == 6 */
return & elf_dlx_reloc_16_hi;
case R_DLX_RELOC_16_LO: /* r_type == 7 */
return & elf_dlx_reloc_16_lo;
default:
if (r_type >= (unsigned int) R_DLX_max) /* R_DLX_max == 10 */
{
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
abfd, r_type);
bfd_set_error (bfd_error_bad_value);
return NULL;
}
return & dlx_elf_howto_table[r_type]; /* r_type == 0 -> 5 (inclusive) */
}
}
As r_type is unsigned the minimum value is 0. The value of R_DLX_max is 10 (see include/elf/dlx.h). The specific case labels that are handled cover r_type values 6, 7, 8, and 9. That leaves the default case to handle 0 -> 5 and 10+. But the error handling case within the default block gives an error for any value of 10+, this means that we only index the dlx_elf_howto_table value r_type values 0, 1, 2, 3, 4, 5, for a total of 6 possible array indexes. And the dlx_elf_howto_table table has 6 entries. I also checked the HOWTO r_type for each entry and they align with the r_type values 0 to 5 in the correct order.
In short, I don't believe that this is actually a bug.
> In short, I don't believe that this is actually a bug. I second this and made the same reasoning. I addition, the advisory refers to an out-of-bounds write, but there is no indexed write in this procedure. I suspect some AI found something bad and talked rubbish by inference, and wonder if the tested code snapshot was taken prior to recent commit https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=114e3aae2b7e34057c8909301eaf78c15687e8e5 that fixed a buffer overflow, although I do not find a direct relationship. Does this commit fix the current problem? Here is a PoC I found after being sent to several dead ends by the wild bug details in CVE. https://github.com/4D4J/objdump-Out-Of-Bounds-write If the info there is legitimate, the commit linked in comment 2 is the fix, and should be be mentioned on https://access.redhat.com/security/cve/cve-2026-18220 But again, the CVE details do not match the real bug. I hope it helps. |