ARM: net: bpf: fix tail call jumps
authorRussell King <rmk+kernel@armlinux.org.uk>
Sat, 13 Jan 2018 11:39:54 +0000 (11:39 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Jan 2018 13:03:43 +0000 (14:03 +0100)
commite7119caa7cd93ff4a01788ebd2fc95edeaa16da3
tree5715d5c75330b264cc5347488486ac2770f654b5
parent124047a81eae1fad08482aa122e683f602fe85dc
ARM: net: bpf: fix tail call jumps

commit f4483f2cc1fdc03488c8a1452e545545ae5bda93 upstream.

When a tail call fails, it is documented that the tail call should
continue execution at the following instruction.  An example tail call
sequence is:

  12: (85) call bpf_tail_call#12
  13: (b7) r0 = 0
  14: (95) exit

The ARM assembler for the tail call in this case ends up branching to
instruction 14 instead of instruction 13, resulting in the BPF filter
returning a non-zero value:

  178: ldr r8, [sp, #588] ; insn 12
  17c: ldr r6, [r8, r6]
  180: ldr r8, [sp, #580]
  184: cmp r8, r6
  188: bcs 0x1e8
  18c: ldr r6, [sp, #524]
  190: ldr r7, [sp, #528]
  194: cmp r7, #0
  198: cmpeq r6, #32
  19c: bhi 0x1e8
  1a0: adds r6, r6, #1
  1a4: adc r7, r7, #0
  1a8: str r6, [sp, #524]
  1ac: str r7, [sp, #528]
  1b0: mov r6, #104
  1b4: ldr r8, [sp, #588]
  1b8: add r6, r8, r6
  1bc: ldr r8, [sp, #580]
  1c0: lsl r7, r8, #2
  1c4: ldr r6, [r6, r7]
  1c8: cmp r6, #0
  1cc: beq 0x1e8
  1d0: mov r8, #32
  1d4: ldr r6, [r6, r8]
  1d8: add r6, r6, #44
  1dc: bx r6
  1e0: mov r0, #0 ; insn 13
  1e4: mov r1, #0
  1e8: add sp, sp, #596 ; insn 14
  1ec: pop {r4, r5, r6, r7, r8, sl, pc}

For other sequences, the tail call could end up branching midway through
the following BPF instructions, or maybe off the end of the function,
leading to unknown behaviours.

Fixes: 39c13c204bb1 ("arm: eBPF JIT compiler")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm/net/bpf_jit_32.c