]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Exit early if reg_bounds_sync gets invalid inputs
authorHarishankar Vishwanathan <harishankar.vishwanathan@gmail.com>
Thu, 2 Apr 2026 15:10:09 +0000 (17:10 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 3 Apr 2026 01:23:25 +0000 (18:23 -0700)
In the subsequent commit, to prune dead branches we will rely on
detecting ill-formed ranges using range_bounds_violations()
(e.g., umin > umax) after refining register bounds using
regs_refine_cond_op().

However, reg_bounds_sync() can sometimes "repair" ill-formed bounds,
potentially masking a violation that was produced by
regs_refine_cond_op().

This commit modifies reg_bounds_sync() to exit early if an invariant
violation is already present in the input.

This ensures ill-formed reg_states remain ill-formed after
reg_bounds_sync(), allowing simulate_both_branches_taken() to correctly
identify dead branches with a single check to range_bounds_violation().

Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Harishankar Vishwanathan <harishankar.vishwanathan@gmail.com>
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/73127d628841c59cb7423d6bdcd204bf90bcdc80.1775142354.git.paul.chaignon@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 15defae1d7edd3b18615bd179aca4fa3e69d3d9e..8215355f6be003a313b23cc4854a8396ddb3712e 100644 (file)
@@ -2788,8 +2788,13 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
        reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
 }
 
+static bool range_bounds_violation(struct bpf_reg_state *reg);
+
 static void reg_bounds_sync(struct bpf_reg_state *reg)
 {
+       /* If the input reg_state is invalid, we can exit early */
+       if (range_bounds_violation(reg))
+               return;
        /* We might have learned new bounds from the var_off. */
        __update_reg_bounds(reg);
        /* We might have learned something about the sign bit. */