]> www.infradead.org Git - nvme.git/commit
bpf: Track delta between "linked" registers.
authorAlexei Starovoitov <ast@kernel.org>
Thu, 13 Jun 2024 01:38:13 +0000 (18:38 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 14 Jun 2024 19:52:39 +0000 (21:52 +0200)
commit98d7ca374ba4b39e7535613d40e159f09ca14da2
treecc45a92aa7645787141a5f250bc085c9f815fbc3
parent124e8c2b1b5d08a10d3a44ed082eaaf98a78c91f
bpf: Track delta between "linked" registers.

Compilers can generate the code
  r1 = r2
  r1 += 0x1
  if r2 < 1000 goto ...
  use knowledge of r2 range in subsequent r1 operations

So remember constant delta between r2 and r1 and update r1 after 'if' condition.

Unfortunately LLVM still uses this pattern for loops with 'can_loop' construct:
for (i = 0; i < 1000 && can_loop; i++)

The "undo" pass was introduced in LLVM
https://reviews.llvm.org/D121937
to prevent this optimization, but it cannot cover all cases.
Instead of fighting middle end optimizer in BPF backend teach the verifier
about this pattern.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20240613013815.953-3-alexei.starovoitov@gmail.com
include/linux/bpf_verifier.h
kernel/bpf/log.c
kernel/bpf/verifier.c
tools/testing/selftests/bpf/verifier/precise.c