@@ -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 */
46804680static 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
48564865int 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)
48644873static 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
48704879static 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 */
1889518904static 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