From: Alexei Starovoitov The state of an open-coded iterator has a counter, iter.depth. The verifier increments it at each bpf_iter_*_next() that returns an element. The counter had one user: the check for infinite loops in is_state_visited(). That check rejected a prog when a path came back to an insn in an identical state. In a loop with an iterator this is not an error, because the iterator stops the loop. A different depth told the check that this is a new iteration. "bpf: Remove is_state_visited()" removed the check. The comparison of states and the join of states ignore depth. Remove it. The verifier log does not print "depth=" for an iterator. Signed-off-by: Alexei Starovoitov --- include/linux/bpf_verifier.h | 4 +--- kernel/bpf/join.c | 1 - kernel/bpf/log.c | 5 ++--- kernel/bpf/states.c | 7 ------- kernel/bpf/verifier.c | 3 --- 5 files changed, 3 insertions(+), 17 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index d02f6938c2e1..f46963591e18 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -104,9 +104,7 @@ struct bpf_reg_state { */ struct btf *btf; u32 btf_id; - /* packing following two fields to fit iter state into 16 bytes */ - enum bpf_iter_state state:2; - int depth:30; + enum bpf_iter_state state; } iter; /* For irq stack slots */ diff --git a/kernel/bpf/join.c b/kernel/bpf/join.c index dde40dc4ff4f..477fe159811b 100644 --- a/kernel/bpf/join.c +++ b/kernel/bpf/join.c @@ -346,7 +346,6 @@ static bool join_special_slot(struct bpf_join_state *js, const struct bpf_stack_ return false; break; case STACK_ITER: - /* iter.depth is not a part of the state, see stacksafe() */ if (ra->type != rb->type || ra->iter.btf != rb->iter.btf || ra->iter.btf_id != rb->iter.btf_id || ra->iter.state != rb->iter.state) return false; diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index 1c7a13bfee87..0013ab01e72d 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -767,11 +767,10 @@ void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_verifie if (!reg->id) continue; - verbose(env, " fp%d=iter_%s(id=%d,state=%s,depth=%u)", + verbose(env, " fp%d=iter_%s(id=%d,state=%s)", (-i - 1) * BPF_REG_SIZE, iter_type_str(reg->iter.btf, reg->iter.btf_id), - reg->id, iter_state_str(reg->iter.state), - reg->iter.depth); + reg->id, iter_state_str(reg->iter.state)); break; case STACK_MISC: case STACK_ZERO: diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c index 5487987b2441..91c3a23b6e12 100644 --- a/kernel/bpf/states.c +++ b/kernel/bpf/states.c @@ -501,17 +501,10 @@ static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, case STACK_ITER: old_reg = &old_slot->spilled_ptr; cur_reg = &cur_slot->spilled_ptr; - /* iter.depth is not compared between states as it - * doesn't matter for correctness and would otherwise - * prevent convergence; we maintain it only to prevent - * infinite loop check triggering, see - * iter_active_depths_differ() - */ if (old_reg->type != cur_reg->type || old_reg->iter.btf != cur_reg->iter.btf || old_reg->iter.btf_id != cur_reg->iter.btf_id || old_reg->iter.state != cur_reg->iter.state || - /* ignore {old_reg,cur_reg}->iter.depth, see above */ !check_ids(old_reg->id, cur_reg->id, idmap)) return false; break; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 2e46287deb08..17a9d1bf5318 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1053,7 +1053,6 @@ static int mark_stack_slots_iter(struct bpf_verifier_env *env, st->iter.btf = btf; st->iter.btf_id = btf_id; st->iter.state = BPF_ITER_STATE_ACTIVE; - st->iter.depth = 0; for (j = 0; j < BPF_REG_SIZE; j++) slot->slot_type[j] = STACK_ITER; @@ -8703,13 +8702,11 @@ static int process_iter_next_call(struct bpf_verifier_env *env, int insn_idx, queued_iter = get_iter_from_state(queued_st, meta); queued_iter->iter.state = BPF_ITER_STATE_ACTIVE; - queued_iter->iter.depth++; queued_fr = queued_st->frame[queued_st->curframe]; mark_ptr_not_null_reg(&queued_fr->regs[BPF_REG_0]); } - /* switch to DRAINED state, but keep the depth unchanged */ /* mark current iter state as drained and assume returned NULL */ cur_iter->iter.state = BPF_ITER_STATE_DRAINED; __mark_reg_const_zero(env, &cur_fr->regs[BPF_REG_0]); -- 2.55.0