Bug 2507670 (CVE-2026-18220) - CVE-2026-18220 binutils: binutils: Out-of-bounds write in BFD DLX ELF backend relocation processing
Summary: CVE-2026-18220 binutils: binutils: Out-of-bounds write in BFD DLX ELF backend...
Keywords:
Status: NEW
Alias: CVE-2026-18220
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2508331 2508332 2508335 2508337 2508330 2508333
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-07-27 20:25 UTC by OSIDB Bzimport
Modified: 2026-08-04 16:24 UTC (History)
7 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-07-27 20:25:55 UTC
*** This is a vulnerability report sent to us through https://issues.redhat.com/browse/PSIRTSUPT-18741 and was created using the PoC auto-triage agents. It contains hints on the vulnerability extracted by the IA and the full report. ALWAYS review it before any action. Once working on this, don't forget to also update the JSM ticket. ***

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). Manual verification of Red Hat package build configurations is required to confirm affected product scope.

Comment 1 Andrew Burgess 2026-07-30 20:53:57 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.

Comment 2 Patrick Monnerat 2026-07-31 11:27:45 UTC
> 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?

Comment 3 Patrick Monnerat 2026-08-04 16:24:55 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.