[binutils-gdb/binutils-2_35-branch] bpf: fix false overflow in eBPF ELF backend linker

Jose E. Marchesi jemarch@sourceware.org
Wed Aug 12 14:02:47 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9fdc8d96598883ae2ab4dae4f2e73b9276f3a629

commit 9fdc8d96598883ae2ab4dae4f2e73b9276f3a629
Author: Jose E. Marchesi <jose.marchesi@oracle.com>
Date:   Wed Aug 12 15:42:24 2020 +0200

    bpf: fix false overflow in eBPF ELF backend linker
    
    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.

Diff:
---
 bfd/ChangeLog   | 5 +++++
 bfd/elf64-bpf.c | 9 +++++----
 ld/ChangeLog    | 5 +++++
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 88ccf15ddc0..4cbb28e742b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c
index c6a726d9324..d5a160f8f14 100644
--- a/bfd/elf64-bpf.c
+++ b/bfd/elf64-bpf.c
@@ -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,
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 83ec27cfac2..046a9076a51 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.


More information about the Binutils-cvs mailing list