]> git.baikalelectronics.ru Git - kernel.git/commit
bpf: Propagate scalar ranges through register assignments.
authorAlexei Starovoitov <ast@kernel.org>
Fri, 9 Oct 2020 01:12:37 +0000 (18:12 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 9 Oct 2020 20:03:06 +0000 (22:03 +0200)
commitc7ba9b04eb337beb277c457f928eec4213f1b082
treebfd56c2579306096eb3cd30fd6a261b0c38bc1c8
parent8d22305e281292a7de87215eeaadfd1887d40c7f
bpf: Propagate scalar ranges through register assignments.

The llvm register allocator may use two different registers representing the
same virtual register. In such case the following pattern can be observed:
1047: (bf) r9 = r6
1048: (a5) if r6 < 0x1000 goto pc+1
1050: ...
1051: (a5) if r9 < 0x2 goto pc+66
1052: ...
1053: (bf) r2 = r9 /* r2 needs to have upper and lower bounds */

This is normal behavior of greedy register allocator.
The slides 137+ explain why regalloc introduces such register copy:
http://llvm.org/devmtg/2018-04/slides/Yatsina-LLVM%20Greedy%20Register%20Allocator.pdf
There is no way to tell llvm 'not to do this'.
Hence the verifier has to recognize such patterns.

In order to track this information without backtracking allocate ID
for scalars in a similar way as it's done for find_good_pkt_pointers().

When the verifier encounters r9 = r6 assignment it will assign the same ID
to both registers. Later if either register range is narrowed via conditional
jump propagate the register state into the other register.

Clear register ID in adjust_reg_min_max_vals() for any alu instruction. The
register ID is ignored for scalars in regsafe() and doesn't affect state
pruning. mark_reg_unknown() clears the ID. It's used to process call, endian
and other instructions. Hence ID is explicitly cleared only in
adjust_reg_min_max_vals() and in 32-bit mov.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20201009011240.48506-2-alexei.starovoitov@gmail.com
kernel/bpf/verifier.c
tools/testing/selftests/bpf/prog_tests/align.c
tools/testing/selftests/bpf/verifier/direct_packet_access.c