[llvm-bugs] [Bug 49165] New: BPF target: emits invalid jump offsets in large programs

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Feb 12 09:57:00 PST 2021


https://bugs.llvm.org/show_bug.cgi?id=49165

            Bug ID: 49165
           Summary: BPF target: emits invalid jump offsets in large
                    programs
           Product: libraries
           Version: 11.0
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Backend: BPF
          Assignee: unassignedbugs at nondot.org
          Reporter: evanthmp at amazon.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 24521
  --> https://bugs.llvm.org/attachment.cgi?id=24521&action=edit
LLVM miscompiles this program

The BPF instruction set uses a signed 16-bit jump offset. For large programs (>
32k instructions), LLVM emits incorrect jumps outside the program bounds or to
the wrong location.

I have attached a minimal reproduction program, emits_illegal_jump.c

When the attached test program is compiled:
% /usr/local/opt/llvm/bin/clang -target bpf -Wall -O3 -c emits_illegal_jump.c
-o objfile.o

We can see an incorrect jump at address 0x46718:
% /usr/local/opt/binutils/bin/objdump -S objfile.o
...
   46718:       55 04 30 73 04 00 00 00         jne %r4,4,29488

0000000000046720 <LBB0_11>:
   46720:       b7 00 00 00 04 00 00 00         mov %r0,4
   46728:       05 00 03 00 00 00 00 00         ja 3

0000000000046730 <LBB0_13>:
   46730:       b7 00 00 00 02 00 00 00         mov %r0,2
   46738:       05 00 01 00 00 00 00 00         ja 1

0000000000046740 <LBB0_12>:
   46740:       bf 30 00 00 00 00 00 00         mov %r0,%r3

0000000000046748 <LBB0_14>:
   46748:       95 00 00 00 00 00 00 00         exit


0x46748 is the end of the program, so at 0x46718, jumping forward by 29488
takes us well outside the bounds of the program. 

29488 is 0x7330. I am guessing this instruction was actually supposed to be a
jump by -33056, or 0xffff7330 in 2's complement. It appears that LLVM
calculates a jump offset with larger-than-16-bit integer math, and then stuffs
the lower 16 bits into the BPF jump offset field without considering whether
the value can actually be represented by a signed 16-bit integer.


The correct behavior would be to emit an error and fail to compile the program
in this case. Or even better (but more complicated), emit a series of multiple
valid jumps, or a trampoline (bpf / ebpf doesn't have an indirect jump
instruction so this may be tough).



Other details: I am using LLVM 11.0.1 from homebrew
% /usr/local/opt/llvm/bin/clang --version
clang version 11.0.1
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210212/2e308db8/attachment.html>


More information about the llvm-bugs mailing list