@@ -4678,21 +4678,24 @@ static void mark_all_scalars_imprecise(struct bpf_verifier_env *env, struct bpf_
4678
4678
* finalized states which help in short circuiting more future states.
4679
4679
*/
4680
4680
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)
4682
4684
{
4683
4685
struct bpf_verifier_state *st = starting_state;
4684
4686
struct backtrack_state *bt = &env->bt;
4685
4687
int first_idx = st->first_insn_idx;
4686
4688
int last_idx = starting_state->insn_idx;
4687
4689
int subseq_idx = -1;
4688
4690
struct bpf_func_state *func;
4691
+ bool tmp, skip_first = true;
4689
4692
struct bpf_reg_state *reg;
4690
- bool skip_first = true;
4691
4693
int i, fr, err;
4692
4694
4693
4695
if (!env->bpf_capable)
4694
4696
return 0;
4695
4697
4698
+ changed = changed ?: &tmp;
4696
4699
/* set frame number from which we are starting to backtrack */
4697
4700
bt_init(bt, starting_state->curframe);
4698
4701
@@ -4738,8 +4741,10 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
4738
4741
for_each_set_bit(i, mask, 32) {
4739
4742
reg = &st->frame[0]->regs[i];
4740
4743
bt_clear_reg(bt, i);
4741
- if (reg->type == SCALAR_VALUE)
4744
+ if (reg->type == SCALAR_VALUE) {
4742
4745
reg->precise = true;
4746
+ *changed = true;
4747
+ }
4743
4748
}
4744
4749
return 0;
4745
4750
}
@@ -4798,10 +4803,12 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
4798
4803
bt_clear_frame_reg(bt, fr, i);
4799
4804
continue;
4800
4805
}
4801
- if (reg->precise)
4806
+ if (reg->precise) {
4802
4807
bt_clear_frame_reg(bt, fr, i);
4803
- else
4808
+ } else {
4804
4809
reg->precise = true;
4810
+ *changed = true;
4811
+ }
4805
4812
}
4806
4813
4807
4814
bitmap_from_u64(mask, bt_frame_stack_mask(bt, fr));
@@ -4816,10 +4823,12 @@ static int __mark_chain_precision(struct bpf_verifier_env *env,
4816
4823
continue;
4817
4824
}
4818
4825
reg = &func->stack[i].spilled_ptr;
4819
- if (reg->precise)
4826
+ if (reg->precise) {
4820
4827
bt_clear_frame_slot(bt, fr, i);
4821
- else
4828
+ } else {
4822
4829
reg->precise = true;
4830
+ *changed = true;
4831
+ }
4823
4832
}
4824
4833
if (env->log.level & BPF_LOG_LEVEL2) {
4825
4834
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,
4855
4864
4856
4865
int mark_chain_precision(struct bpf_verifier_env *env, int regno)
4857
4866
{
4858
- return __mark_chain_precision(env, env->cur_state, regno);
4867
+ return __mark_chain_precision(env, env->cur_state, regno, NULL );
4859
4868
}
4860
4869
4861
4870
/* 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)
4864
4873
static int mark_chain_precision_batch(struct bpf_verifier_env *env,
4865
4874
struct bpf_verifier_state *starting_state)
4866
4875
{
4867
- return __mark_chain_precision(env, starting_state, -1);
4876
+ return __mark_chain_precision(env, starting_state, -1, NULL );
4868
4877
}
4869
4878
4870
4879
static bool is_spillable_regtype(enum bpf_reg_type type)
@@ -18893,7 +18902,9 @@ static int propagate_liveness(struct bpf_verifier_env *env,
18893
18902
* propagate them into the current state
18894
18903
*/
18895
18904
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)
18897
18908
{
18898
18909
struct bpf_reg_state *state_reg;
18899
18910
struct bpf_func_state *state;
@@ -18941,7 +18952,7 @@ static int propagate_precision(struct bpf_verifier_env *env,
18941
18952
verbose(env, "\n");
18942
18953
}
18943
18954
18944
- err = mark_chain_precision_batch (env, env->cur_state );
18955
+ err = __mark_chain_precision (env, cur, -1, changed );
18945
18956
if (err < 0)
18946
18957
return err;
18947
18958
@@ -19264,7 +19275,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
19264
19275
*/
19265
19276
if (is_jmp_point(env, env->insn_idx))
19266
19277
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 );
19268
19279
if (err)
19269
19280
return err;
19270
19281
return 1;
0 commit comments