bpf: starting_state parameter for __mark_chain_precision()

Allow `mark_chain_precision()` to run from an arbitrary starting state
by replacing direct references to `env->cur_state` with a parameter.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250611200836.4135542-4-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
pull/1309/head
Eduard Zingerman 2025-06-11 13:08:29 -07:00 committed by Alexei Starovoitov
parent 13f843c017
commit 9a2a0d7924
1 changed files with 13 additions and 11 deletions

View File

@ -4677,12 +4677,13 @@ static void mark_all_scalars_imprecise(struct bpf_verifier_env *env, struct bpf_
* mark_all_scalars_imprecise() to hopefully get more permissive and generic * mark_all_scalars_imprecise() to hopefully get more permissive and generic
* finalized states which help in short circuiting more future states. * finalized states which help in short circuiting more future states.
*/ */
static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) static int __mark_chain_precision(struct bpf_verifier_env *env,
struct bpf_verifier_state *starting_state, int regno)
{ {
struct bpf_verifier_state *st = starting_state;
struct backtrack_state *bt = &env->bt; struct backtrack_state *bt = &env->bt;
struct bpf_verifier_state *st = env->cur_state;
int first_idx = st->first_insn_idx; int first_idx = st->first_insn_idx;
int last_idx = env->insn_idx; int last_idx = starting_state->insn_idx;
int subseq_idx = -1; int subseq_idx = -1;
struct bpf_func_state *func; struct bpf_func_state *func;
struct bpf_reg_state *reg; struct bpf_reg_state *reg;
@ -4693,7 +4694,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
return 0; return 0;
/* set frame number from which we are starting to backtrack */ /* set frame number from which we are starting to backtrack */
bt_init(bt, env->cur_state->curframe); bt_init(bt, starting_state->curframe);
/* Do sanity checks against current state of register and/or stack /* Do sanity checks against current state of register and/or stack
* slot, but don't set precise flag in current state, as precision * slot, but don't set precise flag in current state, as precision
@ -4757,7 +4758,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
err = backtrack_insn(env, i, subseq_idx, hist, bt); err = backtrack_insn(env, i, subseq_idx, hist, bt);
} }
if (err == -ENOTSUPP) { if (err == -ENOTSUPP) {
mark_all_scalars_precise(env, env->cur_state); mark_all_scalars_precise(env, starting_state);
bt_reset(bt); bt_reset(bt);
return 0; return 0;
} else if (err) { } else if (err) {
@ -4845,7 +4846,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
* fallback to marking all precise * fallback to marking all precise
*/ */
if (!bt_empty(bt)) { if (!bt_empty(bt)) {
mark_all_scalars_precise(env, env->cur_state); mark_all_scalars_precise(env, starting_state);
bt_reset(bt); bt_reset(bt);
} }
@ -4854,15 +4855,16 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
int mark_chain_precision(struct bpf_verifier_env *env, int regno) int mark_chain_precision(struct bpf_verifier_env *env, int regno)
{ {
return __mark_chain_precision(env, regno); return __mark_chain_precision(env, env->cur_state, regno);
} }
/* mark_chain_precision_batch() assumes that env->bt is set in the caller to /* mark_chain_precision_batch() assumes that env->bt is set in the caller to
* desired reg and stack masks across all relevant frames * desired reg and stack masks across all relevant frames
*/ */
static int mark_chain_precision_batch(struct bpf_verifier_env *env) static int mark_chain_precision_batch(struct bpf_verifier_env *env,
struct bpf_verifier_state *starting_state)
{ {
return __mark_chain_precision(env, -1); return __mark_chain_precision(env, starting_state, -1);
} }
static bool is_spillable_regtype(enum bpf_reg_type type) static bool is_spillable_regtype(enum bpf_reg_type type)
@ -9515,7 +9517,7 @@ static int get_constant_map_key(struct bpf_verifier_env *env,
* to prevent pruning on it. * to prevent pruning on it.
*/ */
bt_set_frame_slot(&env->bt, key->frameno, spi); bt_set_frame_slot(&env->bt, key->frameno, spi);
err = mark_chain_precision_batch(env); err = mark_chain_precision_batch(env, env->cur_state);
if (err < 0) if (err < 0)
return err; return err;
@ -18939,7 +18941,7 @@ static int propagate_precision(struct bpf_verifier_env *env,
verbose(env, "\n"); verbose(env, "\n");
} }
err = mark_chain_precision_batch(env); err = mark_chain_precision_batch(env, env->cur_state);
if (err < 0) if (err < 0)
return err; return err;