Public bug reported:

Source package: binutils
Affected release: Ubuntu 24.04 LTS (Noble), amd64
Observed package: binutils-x86-64-linux-gnu 2.42-4ubuntu2.10

[ Impact ]

Noble's ld.bfd can silently generate incorrect executable code when linking
precompiled x86-64 objects produced by newer assemblers. A PUSH instruction
carrying R_X86_64_GOTPCRELX can be rewritten into a direct CALL to its data
symbol. The link succeeds, but the resulting application crashes when the
instruction is executed, for example by attempting to execute a .bss object.

This affects applications consuming newer prebuilt libraries on Noble. The
same-release assembler/linker combination does not normally generate this
particular input, so ordinary native rebuilds can miss the incompatibility.

The requested change is the existing upstream binutils-2_42-branch backport
for PR ld/32991. It checks the ModRM byte before applying the indirect branch
relaxation. This retains BFD and existing valid relaxations, unlike disabling
linker relaxation globally or replacing the linker implementation.

[ Test Plan ]

1. On Ubuntu 24.04 amd64, record the installed version:
     dpkg-query -W binutils binutils-x86-64-linux-gnu
     /usr/bin/ld.bfd --version

2. Save the attached repro.s and reproduce.py in the same directory. They
   require Python 3 and binutils, but no GPU, compiler SDK, or proprietary 
input.

3. Run:
     python3 reproduce.py

   The assembly uses .reloc to express the input generated by newer GNU as,
   so reproducing the problem does not require installing a new assembler.

   Affected package:
   - readelf shows R_X86_64_GOTPCRELX against marker.
   - objdump shows an incorrect 'addr32 call ... <marker>'.
   - The child process receives SIGSEGV; the test prints FAIL and exits 1.

   Fixed package, WITHOUT --no-relax:
   - The PUSH remains a PUSH.
   - The probe returns a non-null address; the test prints PASS and exits 0.

4. Diagnostic control on the affected package:
     python3 reproduce.py --no-relax
   This should pass. Passing this control alone does not validate a fixed ld.

5. Before upload, run the package's relevant x86 linker tests, including
   existing GOT load and indirect CALL/JMP relaxation coverage. The upstream
   patch also touches i386, so exercise its PUSH/CALL/JMP regression coverage
   as well. Check package builds and applicable autopkgtests on all affected
   architectures.

6. After acceptance into noble-proposed, repeat the acceptance test against
   the actual proposed binary package, record its exact version and output,
   and report the result on this bug. Also verify the original application
   workload without the --no-relax workaround.

[ Where problems could occur ]

The patch changes x86 linker instruction classification during GOT
relaxation. An incorrect guard could suppress valid CALL/JMP optimizations
or misclassify another instruction, resulting in wrong branch targets,
application startup/runtime crashes, or code/GOT size changes. Both x86-64
and i386 paths are modified by the upstream backport. Regression testing
should therefore cover ordinary GOT loads, indirect calls/jumps, PUSH,
shared libraries and executables; the PUSH reproducer alone is insufficient
to cover all regression risk.

[ Other Info ]

Upstream bug:
https://sourceware.org/bugzilla/show_bug.cgi?id=32991

Existing upstream 2.42 backport:
https://gnu.googlesource.com/binutils-gdb/+/f9488b0d92b591bdf3ff8cce485cb0e1b3727cc0

Patch title: x86: Check MODRM for call and jmp in binutils older than 2.45
Commit date: 2025-05-22 UTC.

New assembler support exposing the older-linker incompatibility:
https://gnu.googlesource.com/binutils-gdb/+/11c2852449825a5f486f63bc40aabed56b7c04c1

Verified locally: the installed Noble linker fails the default reproducer
and passes its --no-relax control. The proposed patched Ubuntu binary
package has not yet been built or tested by this reporter.

Please nominate a Noble task. Before an SRU upload, verify and document the
fix status of the current development release and newer supported releases,
as required by SRU policy. Do not mark those tasks fixed solely from an
upstream version number.

The attached upstream patch is not yet a complete Ubuntu packaging debdiff.
It still needs integration into the Noble source package, a changelog entry
referencing this Launchpad bug, package testing, and sponsorship/upload.

** Affects: binutils (Ubuntu)
     Importance: Undecided
         Status: New

** Attachment added: "pr32991-sru-materials.tar.gz"
   
https://bugs.launchpad.net/bugs/2172541/+attachment/6013466/+files/pr32991-sru-materials.tar.gz

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172541

Title:
  Noble ld.bfd misrelaxes x86-64 GOTPCRELX PUSH into CALL (upstream
  PR32991)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/2172541/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to