Skip to content

Commit a8b96f6

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: set 'changed' status if propagate_precision() did any updates
Add an out parameter to `propagate_precision()` to record whether any new precision bits were set during its execution. Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 8e1acf4 commit a8b96f6

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

kernel/bpf/verifier.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4678,21 +4678,24 @@ static void mark_all_scalars_imprecise(struct bpf_verifier_env *env, struct bpf_
46784678
* finalized states which help in short circuiting more future states.
46794679
*/
46804680
static int __mark_chain_precision(struct bpf_verifier_env *env,
4681-
struct bpf_verifier_state *starting_state, int regno)
4681+
struct bpf_verifier_state *starting_state,
4682+
int regno,
4683+
bool *changed)
46824684
{
46834685
struct bpf_verifier_state *st = starting_state;
46844686
struct backtrack_state *bt = &env->bt;
46854687
int first_idx = st->first_insn_idx;
46864688
int last_idx = starting_state->insn_idx;
46874689
int subseq_idx = -1;
46884690
struct bpf_func_state *func;
4691+
bool tmp, skip_first = true;
46894692
struct bpf_reg_state *reg;
4690-
bool skip_first = true;
46914693
int i, fr, err;
46924694

46934695
if (!env->bpf_capable)
46944696
return 0;
46954697

4698+
changed = changed ?: &tmp;
46964699
/* set frame number from which we are starting to backtrack */
46974700
bt_init(bt, starting_state->curframe);
46984701

@@ -4738,8 +4741,10 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
47384741
for_each_set_bit(i, mask, 32) {
47394742
reg = &st->frame[0]->regs[i];
47404743
bt_clear_reg(bt, i);
4741-
if (reg->type == SCALAR_VALUE)
4744+
if (reg->type == SCALAR_VALUE) {
47424745
reg->precise = true;
4746+
*changed = true;
4747+
}
47434748
}
47444749
return 0;
47454750
}
@@ -4798,10 +4803,12 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
47984803
bt_clear_frame_reg(bt, fr, i);
47994804
continue;
48004805
}
4801-
if (reg->precise)
4806+
if (reg->precise) {
48024807
bt_clear_frame_reg(bt, fr, i);
4803-
else
4808+
} else {
48044809
reg->precise = true;
4810+
*changed = true;
4811+
}
48054812
}
48064813

48074814
bitmap_from_u64(mask, bt_frame_stack_mask(bt, fr));
@@ -4816,10 +4823,12 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
48164823
continue;
48174824
}
48184825
reg = &func->stack[i].spilled_ptr;
4819-
if (reg->precise)
4826+
if (reg->precise) {
48204827
bt_clear_frame_slot(bt, fr, i);
4821-
else
4828+
} else {
48224829
reg->precise = true;
4830+
*changed = true;
4831+
}
48234832
}
48244833
if (env->log.level & BPF_LOG_LEVEL2) {
48254834
fmt_reg_mask(env->tmp_str_buf, TMP_STR_BUF_LEN,
@@ -4855,7 +4864,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
48554864

48564865
int mark_chain_precision(struct bpf_verifier_env *env, int regno)
48574866
{
4858-
return __mark_chain_precision(env, env->cur_state, regno);
4867+
return __mark_chain_precision(env, env->cur_state, regno, NULL);
48594868
}
48604869

48614870
/* mark_chain_precision_batch() assumes that env->bt is set in the caller to
@@ -4864,7 +4873,7 @@ int mark_chain_precision(struct bpf_verifier_env *env, int regno)
48644873
static int mark_chain_precision_batch(struct bpf_verifier_env *env,
48654874
struct bpf_verifier_state *starting_state)
48664875
{
4867-
return __mark_chain_precision(env, starting_state, -1);
4876+
return __mark_chain_precision(env, starting_state, -1, NULL);
48684877
}
48694878

48704879
static bool is_spillable_regtype(enum bpf_reg_type type)
@@ -18893,7 +18902,9 @@ static int propagate_liveness(struct bpf_verifier_env *env,
1889318902
* propagate them into the current state
1889418903
*/
1889518904
static int propagate_precision(struct bpf_verifier_env *env,
18896-
const struct bpf_verifier_state *old)
18905+
const struct bpf_verifier_state *old,
18906+
struct bpf_verifier_state *cur,
18907+
bool *changed)
1889718908
{
1889818909
struct bpf_reg_state *state_reg;
1889918910
struct bpf_func_state *state;
@@ -18941,7 +18952,7 @@ static int propagate_precision(struct bpf_verifier_env *env,
1894118952
verbose(env, "\n");
1894218953
}
1894318954

18944-
err = mark_chain_precision_batch(env, env->cur_state);
18955+
err = __mark_chain_precision(env, cur, -1, changed);
1894518956
if (err < 0)
1894618957
return err;
1894718958

@@ -19264,7 +19275,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
1926419275
*/
1926519276
if (is_jmp_point(env, env->insn_idx))
1926619277
err = err ? : push_jmp_history(env, cur, 0, 0);
19267-
err = err ? : propagate_precision(env, &sl->state);
19278+
err = err ? : propagate_precision(env, &sl->state, cur, NULL);
1926819279
if (err)
1926919280
return err;
1927019281
return 1;

0 commit comments

Comments
 (0)