Skip to content

Commit a24d6f9

Browse files
puranjaymohanAlexei Starovoitov
authored andcommitted
bpf: Relax maybe_widen_reg() constraints
The maybe_widen_reg() function widens imprecise scalar registers to unknown when their values differ between the cached and current states. Previously, it used regs_exact() which also compared register IDs via check_ids(), requiring registers to have matching IDs (or mapped IDs) to be considered exact. For scalar widening purposes, what matters is whether the value tracking (bounds, tnum, var_off) is the same, not whether the IDs match. Two scalars with identical value constraints but different IDs represent the same abstract value and don't need to be widened. Introduce scalars_exact_for_widen() that only compares the value-tracking portion of bpf_reg_state (fields before 'id'). This allows the verifier to preserve more scalar value information during state merging when IDs differ but actual tracked values are identical, reducing unnecessary widening and potentially improving verification precision. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Link: https://lore.kernel.org/r/20260203165102.2302462-4-puranjay@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent b2a0aa3 commit a24d6f9

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

kernel/bpf/verifier.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8995,15 +8995,24 @@ static bool regs_exact(const struct bpf_reg_state *rold,
89958995
const struct bpf_reg_state *rcur,
89968996
struct bpf_idmap *idmap);
89978997

8998+
/*
8999+
* Check if scalar registers are exact for the purpose of not widening.
9000+
* More lenient than regs_exact()
9001+
*/
9002+
static bool scalars_exact_for_widen(const struct bpf_reg_state *rold,
9003+
const struct bpf_reg_state *rcur)
9004+
{
9005+
return !memcmp(rold, rcur, offsetof(struct bpf_reg_state, id));
9006+
}
9007+
89989008
static void maybe_widen_reg(struct bpf_verifier_env *env,
8999-
struct bpf_reg_state *rold, struct bpf_reg_state *rcur,
9000-
struct bpf_idmap *idmap)
9009+
struct bpf_reg_state *rold, struct bpf_reg_state *rcur)
90019010
{
90029011
if (rold->type != SCALAR_VALUE)
90039012
return;
90049013
if (rold->type != rcur->type)
90059014
return;
9006-
if (rold->precise || rcur->precise || regs_exact(rold, rcur, idmap))
9015+
if (rold->precise || rcur->precise || scalars_exact_for_widen(rold, rcur))
90079016
return;
90089017
__mark_reg_unknown(env, rcur);
90099018
}
@@ -9015,16 +9024,14 @@ static int widen_imprecise_scalars(struct bpf_verifier_env *env,
90159024
struct bpf_func_state *fold, *fcur;
90169025
int i, fr, num_slots;
90179026

9018-
reset_idmap_scratch(env);
90199027
for (fr = old->curframe; fr >= 0; fr--) {
90209028
fold = old->frame[fr];
90219029
fcur = cur->frame[fr];
90229030

90239031
for (i = 0; i < MAX_BPF_REG; i++)
90249032
maybe_widen_reg(env,
90259033
&fold->regs[i],
9026-
&fcur->regs[i],
9027-
&env->idmap_scratch);
9034+
&fcur->regs[i]);
90289035

90299036
num_slots = min(fold->allocated_stack / BPF_REG_SIZE,
90309037
fcur->allocated_stack / BPF_REG_SIZE);
@@ -9035,8 +9042,7 @@ static int widen_imprecise_scalars(struct bpf_verifier_env *env,
90359042

90369043
maybe_widen_reg(env,
90379044
&fold->stack[i].spilled_ptr,
9038-
&fcur->stack[i].spilled_ptr,
9039-
&env->idmap_scratch);
9045+
&fcur->stack[i].spilled_ptr);
90409046
}
90419047
}
90429048
return 0;

0 commit comments

Comments
 (0)