]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bpf: enforce precision of R0 on callback return
authorAndrii Nakryiko <andrii@kernel.org>
Sat, 2 Dec 2023 17:56:57 +0000 (09:56 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 2 Dec 2023 19:36:50 +0000 (11:36 -0800)
Given verifier checks actual value, r0 has to be precise, so we need to
propagate precision properly. r0 also has to be marked as read,
otherwise subsequent state comparisons will ignore such register as
unimportant and precision won't really help here.

Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper")
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231202175705.885270-4-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 25b9d470957eadd8c17035c8fcbe77735e37b3f0..849fbf47b5f352cf5dc04a791c42b768a3c369ef 100644 (file)
@@ -9590,6 +9590,13 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
                        verbose(env, "R0 not a scalar value\n");
                        return -EACCES;
                }
+
+               /* we are going to rely on register's precise value */
+               err = mark_reg_read(env, r0, r0->parent, REG_LIVE_READ64);
+               err = err ?: mark_chain_precision(env, BPF_REG_0);
+               if (err)
+                       return err;
+
                if (!tnum_in(range, r0->var_off)) {
                        verbose_invalid_scalar(env, r0, &range, "callback return", "R0");
                        return -EINVAL;