tmp_suning_uos_patched/arch/mips
Piotr Krysiuk c61736a994 bpf, mips: Validate conditional branch offsets
[ Upstream commit 37cb28ec7d3a36a5bace7063a3dba633ab110f8b ]

The conditional branch instructions on MIPS use 18-bit signed offsets
allowing for a branch range of 128 KBytes (backward and forward).
However, this limit is not observed by the cBPF JIT compiler, and so
the JIT compiler emits out-of-range branches when translating certain
cBPF programs. A specific example of such a cBPF program is included in
the "BPF_MAXINSNS: exec all MSH" test from lib/test_bpf.c that executes
anomalous machine code containing incorrect branch offsets under JIT.

Furthermore, this issue can be abused to craft undesirable machine
code, where the control flow is hijacked to execute arbitrary Kernel
code.

The following steps can be used to reproduce the issue:

  # echo 1 > /proc/sys/net/core/bpf_jit_enable
  # modprobe test_bpf test_name="BPF_MAXINSNS: exec all MSH"

This should produce multiple warnings from build_bimm() similar to:

  ------------[ cut here ]------------
  WARNING: CPU: 0 PID: 209 at arch/mips/mm/uasm-mips.c:210 build_insn+0x558/0x590
  Micro-assembler field overflow
  Modules linked in: test_bpf(+)
  CPU: 0 PID: 209 Comm: modprobe Not tainted 5.14.3 #1
  Stack : 00000000 807bb824 82b33c9c 801843c0 00000000 00000004 00000000 63c9b5ee
          82b33af4 80999898 80910000 80900000 82fd6030 00000001 82b33a98 82087180
          00000000 00000000 80873b28 00000000 000000fc 82b3394c 00000000 2e34312e
          6d6d6f43 809a180f 809a1836 6f6d203a 80900000 00000001 82b33bac 80900000
          00027f80 00000000 00000000 807bb824 00000000 804ed790 001cc317 00000001
  [...]
  Call Trace:
  [<80108f44>] show_stack+0x38/0x118
  [<807a7aac>] dump_stack_lvl+0x5c/0x7c
  [<807a4b3c>] __warn+0xcc/0x140
  [<807a4c3c>] warn_slowpath_fmt+0x8c/0xb8
  [<8011e198>] build_insn+0x558/0x590
  [<8011e358>] uasm_i_bne+0x20/0x2c
  [<80127b48>] build_body+0xa58/0x2a94
  [<80129c98>] bpf_jit_compile+0x114/0x1e4
  [<80613fc4>] bpf_prepare_filter+0x2ec/0x4e4
  [<8061423c>] bpf_prog_create+0x80/0xc4
  [<c0a006e4>] test_bpf_init+0x300/0xba8 [test_bpf]
  [<8010051c>] do_one_initcall+0x50/0x1d4
  [<801c5e54>] do_init_module+0x60/0x220
  [<801c8b20>] sys_finit_module+0xc4/0xfc
  [<801144d0>] syscall_common+0x34/0x58
  [...]
  ---[ end trace a287d9742503c645 ]---

Then the anomalous machine code executes:

=> 0xc0a18000:  addiu   sp,sp,-16
   0xc0a18004:  sw      s3,0(sp)
   0xc0a18008:  sw      s4,4(sp)
   0xc0a1800c:  sw      s5,8(sp)
   0xc0a18010:  sw      ra,12(sp)
   0xc0a18014:  move    s5,a0
   0xc0a18018:  move    s4,zero
   0xc0a1801c:  move    s3,zero

   # __BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 0)
   0xc0a18020:  lui     t6,0x8012
   0xc0a18024:  ori     t4,t6,0x9e14
   0xc0a18028:  li      a1,0
   0xc0a1802c:  jalr    t4
   0xc0a18030:  move    a0,s5
   0xc0a18034:  bnez    v0,0xc0a1ffb8           # incorrect branch offset
   0xc0a18038:  move    v0,zero
   0xc0a1803c:  andi    s4,s3,0xf
   0xc0a18040:  b       0xc0a18048
   0xc0a18044:  sll     s4,s4,0x2
   [...]

   # __BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 0)
   0xc0a1ffa0:  lui     t6,0x8012
   0xc0a1ffa4:  ori     t4,t6,0x9e14
   0xc0a1ffa8:  li      a1,0
   0xc0a1ffac:  jalr    t4
   0xc0a1ffb0:  move    a0,s5
   0xc0a1ffb4:  bnez    v0,0xc0a1ffb8           # incorrect branch offset
   0xc0a1ffb8:  move    v0,zero
   0xc0a1ffbc:  andi    s4,s3,0xf
   0xc0a1ffc0:  b       0xc0a1ffc8
   0xc0a1ffc4:  sll     s4,s4,0x2

   # __BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 0)
   0xc0a1ffc8:  lui     t6,0x8012
   0xc0a1ffcc:  ori     t4,t6,0x9e14
   0xc0a1ffd0:  li      a1,0
   0xc0a1ffd4:  jalr    t4
   0xc0a1ffd8:  move    a0,s5
   0xc0a1ffdc:  bnez    v0,0xc0a3ffb8           # correct branch offset
   0xc0a1ffe0:  move    v0,zero
   0xc0a1ffe4:  andi    s4,s3,0xf
   0xc0a1ffe8:  b       0xc0a1fff0
   0xc0a1ffec:  sll     s4,s4,0x2
   [...]

   # epilogue
   0xc0a3ffb8:  lw      s3,0(sp)
   0xc0a3ffbc:  lw      s4,4(sp)
   0xc0a3ffc0:  lw      s5,8(sp)
   0xc0a3ffc4:  lw      ra,12(sp)
   0xc0a3ffc8:  addiu   sp,sp,16
   0xc0a3ffcc:  jr      ra
   0xc0a3ffd0:  nop

To mitigate this issue, we assert the branch ranges for each emit call
that could generate an out-of-range branch.

Fixes: 36366e367e ("MIPS: BPF: Restore MIPS32 cBPF JIT")
Fixes: c6610de353 ("MIPS: net: Add BPF JIT")
Signed-off-by: Piotr Krysiuk <piotras@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Acked-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Link: https://lore.kernel.org/bpf/20210915160437.4080-1-piotras@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-10-06 15:55:51 +02:00
..
alchemy MIPS: alchemy: xxs1500: add gpio-au1000.h header file 2021-06-03 09:00:50 +02:00
ar7 MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
ath25 MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
ath79 MIPS: ath79: Remove unused include <asm/mips_machine.h> 2020-07-28 10:20:44 +02:00
bcm47xx MIPS: BCM47XX: fix kconfig dependency bug for BCM47XX_BCMA 2020-12-30 11:53:09 +01:00
bcm63xx MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
bmips dma-direct: rename and cleanup __phys_to_dma 2020-09-11 09:14:43 +02:00
boot mips: disable branch profiling in boot/decompress.o 2021-07-20 16:05:58 +02:00
cavium-octeon Revert "MIPS: Octeon: Remove special handling of CONFIG_MIPS_ELF_APPENDED_DTB=y" 2021-03-04 11:38:26 +01:00
cobalt MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
configs MIPS: Loongson64: Select SMP in Kconfig to avoid build error 2020-10-12 11:22:40 +02:00
crypto crypto: poly1305 - fix poly1305_core_setkey() declaration 2021-05-14 09:50:13 +02:00
dec MIPS: DEC: Restore bootmem reservation for firmware working memory area 2020-10-14 23:57:57 +02:00
fw MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
generic MIPS: generic: Update node names to avoid unit addresses 2021-06-30 08:47:16 -04:00
include MIPS: check return value of pgtable_pmd_page_ctor 2021-08-12 13:22:07 +02:00
ingenic MIPS: jz4740: Rename jz4740 folders to ingenic 2020-09-18 16:35:05 +02:00
jazz dma-mapping: merge <linux/dma-noncoherent.h> into <linux/dma-map-ops.h> 2020-10-06 07:07:06 +02:00
kernel drivers: base: cacheinfo: Get rid of DEFINE_SMP_CALL_CACHE_FUNCTION() 2021-09-26 14:08:59 +02:00
kvm KVM: MIPS: clean up redundant kvm_run parameters in assembly 2020-09-28 07:57:21 -04:00
lantiq MIPS: lantiq: Explicitly compare LTQ_EBU_PCC_ISTAT against 0 2021-03-04 11:37:38 +01:00
lib MIPS: Fix kernel hang under FUNCTION_GRAPH_TRACER and PREEMPT_TRACER 2021-06-16 12:01:37 +02:00
loongson2ef MIPS updates for v5.10: 2020-10-16 12:40:55 -07:00
loongson32 MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
loongson64 MIPS: loongsoon64: Reserve memory below starting pfn to prevent Oops 2021-07-19 09:44:55 +02:00
math-emu
mm MIPS: c-r4k: Fix section mismatch for loongson2_sc_init 2021-03-04 11:37:38 +01:00
mti-malta MIPS: Malta: fix alignment of the devicetree buffer 2021-09-18 13:40:16 +02:00
net bpf, mips: Validate conditional branch offsets 2021-10-06 15:55:51 +02:00
netlogic MIPS updates for v5.10: 2020-10-16 12:40:55 -07:00
oprofile mips/oprofile: Fix fallthrough placement 2020-08-22 09:23:15 +02:00
pci MIPS: pci-legacy: stop using of_pci_range_to_resource 2021-05-14 09:50:39 +02:00
pic32
pistachio
power
ralink MIPS: ralink: export rt_sysc_membase for rt2880_wdt.c 2021-06-03 09:00:50 +02:00
rb532 MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
sgi-ip22
sgi-ip27 mm/sparse: cleanup the code surrounding memory_present() 2020-08-07 11:33:27 -07:00
sgi-ip30 MIPS: SGI-IP30: Move irq bits to better header files 2020-09-21 22:15:49 +02:00
sgi-ip32 MIPS updates for v5.10: 2020-10-16 12:40:55 -07:00
sibyte MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
sni MIPS: SNI: Fix spurious interrupts 2020-09-16 22:40:58 +02:00
tools
txx9 MIPS: replace add_memory_region with memblock 2020-10-12 12:01:36 +02:00
vdso MIPS: VDSO: Use CLANG_FLAGS instead of filtering out '--target=' 2021-03-04 11:38:26 +01:00
vr41xx
Kbuild
Kbuild.platforms MIPS: generic: Add support for Ingenic SoCs 2020-09-18 16:33:59 +02:00
Kconfig MIPS: ingenic: Select CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER 2021-07-19 09:44:44 +02:00
Kconfig.debug
Makefile mips: Fix non-POSIX regexp 2021-08-12 13:22:07 +02:00
Makefile.postlink