bpf: Recognize that two registers are safe when their ranges match
authorAlexei Starovoitov <ast@kernel.org>
Wed, 6 Mar 2024 03:19:27 +0000 (19:19 -0800)
committerAndrii Nakryiko <andrii@kernel.org>
Wed, 6 Mar 2024 23:18:00 +0000 (15:18 -0800)
commit4f81c16f50baf6d5d8bfa6eef3250dcfa22cbc08
tree9d0f0fd22a3c61db123c1e02ca4874ec34ad8f96
parent011832b97b311bb9e3c27945bc0d1089a14209c9
bpf: Recognize that two registers are safe when their ranges match

When open code iterators, bpf_loop or may_goto are used the following two
states are equivalent and safe to prune the search:

cur state: fp-8_w=scalar(id=3,smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=11,var_off=(0x0; 0xf))
old state: fp-8_rw=scalar(id=2,smin=umin=smin32=umin32=1,smax=umax=smax32=umax32=11,var_off=(0x0; 0xf))

In other words "exact" state match should ignore liveness and precision
marks, since open coded iterator logic didn't complete their propagation,
reg_old->type == NOT_INIT && reg_cur->type != NOT_INIT is also not safe to
prune while looping, but range_within logic that applies to scalars,
ptr_to_mem, map_value, pkt_ptr is safe to rely on.

Avoid doing such comparison when regular infinite loop detection logic is
used, otherwise bounded loop logic will declare such "infinite loop" as
false positive. Such example is in progs/verifier_loops1.c
not_an_inifinite_loop().

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Tested-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20240306031929.42666-3-alexei.starovoitov@gmail.com
kernel/bpf/verifier.c