]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bpf: fix false overflow in eBPF ELF backend linker
authorJose E. Marchesi <jose.marchesi@oracle.com>
Wed, 12 Aug 2020 13:42:24 +0000 (15:42 +0200)
committerJose E. Marchesi <jose.marchesi@oracle.com>
Wed, 12 Aug 2020 13:42:24 +0000 (15:42 +0200)
When performing DISP{16,32} relocations, the eBPF ELF backend linker
needs to convert the relocation from an address into a signed number
of 64-bit words (minus one) to jump.

Because of this unsigned-to-signed conversion, special care needs to
be taken when dividing to ensure the sign bits remain correct.
Otherwise, a false relocation overflow error can be triggered.

bfd/ChangeLog

2020-08-07  David Faust  <david.faust@oracle.com>

* elf64-bpf.c (bpf_elf_relocate_section): Ensure signed division for
DISP16 and DISP32 relocations.

ld/ChangeLog

2020-08-07  David Faust  <david.faust@oracle.com>

* testsuite/ld-bpf/call-3.s: New file.
* testsuite/ld-bpf/call-3.d: Likewise.

bfd/ChangeLog
bfd/elf64-bpf.c
ld/ChangeLog

index 88ccf15ddc08505285b2ec32ac56d2761d30ec0f..4cbb28e742bd97cc647cf6a5b3f1353000d8d906 100644 (file)
@@ -3,6 +3,11 @@
        * po/ru.po: Updated Russian translation.
        * po/sr.po: Updated Serbian translation.
 
+2020-08-07  David Faust  <david.faust@oracle.com>
+
+       * elf64-bpf.c (bpf_elf_relocate_section): Ensure signed division for
+       DISP16 and DISP32 relocations.
+
 2020-08-05  David Faust  <david.faust@oracle.com>
 
        * elf64-bpf.c (bpf_elf_generic_reloc): New function.
index c6a726d932431da909a4f0cc627f2e7e350b1873..d5a160f8f14dfcad4a2562fcf02e2ad786f40bde 100644 (file)
@@ -442,10 +442,11 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
         case R_BPF_INSN_DISP32:
           {
             /* Make the relocation PC-relative, and change its unit to
-               64-bit words.  */
-            relocation -= sec_addr (input_section) + rel->r_offset;
-            /* Make it 64-bit words.  */
-            relocation = relocation / 8;
+               64-bit words.  Note we need *signed* arithmetic
+               here.  */
+            relocation = ((bfd_signed_vma) relocation
+                         - (sec_addr (input_section) + rel->r_offset));
+            relocation = (bfd_signed_vma) relocation / 8;
             
             /* Get the addend from the instruction and apply it.  */
             addend = bfd_get (howto->bitsize, input_bfd,
index 83ec27cfac28e933daddb9615f0a9eef6f74765b..046a9076a5159abe0a86e44d44eb8889d41308f6 100644 (file)
@@ -1,3 +1,8 @@
+2020-08-07  David Faust  <david.faust@oracle.com>
+
+       * testsuite/ld-bpf/call-3.s: New file.
+       * testsuite/ld-bpf/call-3.d: Likewise.
+
 2020-08-05  David Faust  <david.faust@oracle.com>
 
        * testsuite/ld-bpf/call-2.s: New file.