All of lore.kernel.org
 help / color / mirror / Atom feed
* [bpf-next:master 17/47] kernel/bpf/flow.c:2301 flow_merge() warn: missing unwind goto?
@ 2026-11-07 17:35 kernel test robot
  0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-11-07 17:35 UTC (permalink / raw)
  To: oe-kbuild; +Cc: lkp, Dan Carpenter

Unfiltered warning: this smatch report is sent as-is and has not been
reviewed for false positives, so please treat it with due skepticism.

BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
TO: Alexei Starovoitov <ast@kernel.org>

Hi Alexei,

First bad commit (maybe != root cause):

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
head:   2d0b457611c06304138754a05e0873cc18acfb7e
commit: a784eb58f12b1a20afa3412d04faa290b79c82c3 [17/47] bpf: Enter and leave loops in the main pass, build flow.c
:::::: branch date: 13 hours ago
:::::: commit date: 13 hours ago
config: i386-randconfig-2200-20261107 (https://download.01.org/0day-ci/archive/20261107/202611071829.06q8aOQ9-lkp@intel.com/config)
compiler: clang version 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)
smatch: v0.5.0-9187-g5189e3fb

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202611071829.06q8aOQ9-lkp@intel.com/

smatch warnings:
kernel/bpf/flow.c:2301 flow_merge() warn: missing unwind goto?

vim +2301 kernel/bpf/flow.c

9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2260  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2261  /*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2262   * Put *@ps into @set, one of the sets of states at its insn. Returns
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2263   * 1 if it is within a state of the set. It is gone then.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2264   * 0 if it is in the set now, as it was or joined with states of the set.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2265   * @cycle: it came around a cycle, what grew is forgotten.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2266   */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2267  static int flow_merge(struct bpf_verifier_env *env, struct flow_set *set,
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2268  		      struct flow_state **ps, enum flow_cycle cycle)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2269  {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2270  	struct bpf_flow *flow = env->flow;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2271  	struct flow_state *s = *ps, *t, *tn;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2272  	int insn_idx = s->st.insn_idx, err;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2273  	u32 *nr_states = &flow->nr_states[insn_idx];
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2274  	bool places, widen_all, widen;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2275  	/* the set of the states that enter a loop is a stop on the way, see bpf_flow_deliver() */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2276  	bool log = (env->log.level & BPF_LOG_LEVEL2) && set == &flow->states[insn_idx];
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2277  	const char *what = NULL;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2278  	int prev = s->prev_insn_idx;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2279  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2280  again:
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2281  	if (signal_pending(current)) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2282  		err = -EAGAIN;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2283  		goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2284  	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2285  	if (need_resched())
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2286  		cond_resched();
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2287  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2288  	/* again after a join: an offset may not be a constant any more, a pointer may be gone */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2289  	flow_shape_ctx(&s->st, &s->shape);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2290  	places = *nr_states >= BPF_FLOW_MIN_SHAPES;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2291  	for (t = flow_next_related(env, set, s, NULL, places); t;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2292  	     t = flow_next_related(env, set, s, t, places)) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2293  		if (flow_cmp_pkt_range(t, s) > 0 || !flow_trips_near(&t->st, &s->st) ||
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2294  		    !flow_within(env, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2295  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2296  		if (env->log.level & BPF_LOG_LEVEL2)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2297  			verbose(env, "from %d to %d: within\n", prev, insn_idx);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2298  		err = flow_cycle_closed(env, &t->st, &s->st) ?:
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2299  		      flow_unite(flow, s->st.flow_entry, t->st.flow_entry);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2300  		flow_free_state(env, s);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07 @2301  		return err ?: 1;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2302  	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2303  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2304  	flow_sweep_trips(env, set, s);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2305  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2306  	widen_all = cycle == FLOW_CYCLE;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2307  	for (t = flow_next_related(env, set, s, NULL, places); t; t = tn) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2308  		tn = flow_next_related(env, set, s, t, places);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2309  		/*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2310  		 * Iterations that are kept apart have no join. Neither does a state take the place
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2311  		 * of a state of another iteration that it covers: that one is done with, or has its
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2312  		 * own way to go, see flow_cycle_closed().
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2313  		 * The shape is a hash, and what follows goes through the frames of both.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2314  		 */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2315  		if (flow_trips_behind(&t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2316  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2317  		widen = widen_all || (cycle == FLOW_CALLBACK_CYCLE &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2318  				      max(s->joins, t->joins) >= BPF_FLOW_CALLBACK_JOINS);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2319  		/*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2320  		 *	ret = 0; if (...) { denied++; ret = -EPERM; }
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2321  		 *	bpf_for(i, 0, n) { ... } return ret;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2322  		 * Two states enter the loop. What comes around it with 0 is for the state with 0.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2323  		 * Next to -EPERM it looks like a number that grew, and would be forgotten. The same
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2324  		 * for the header of a packet at pkt + 34 and at pkt + 54. No rule has to tell which
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2325  		 * numbers that holds for: a state knows where it comes from.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2326  		 * If it has no join with that state it is at the head on its own from now on.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2327  		 * The same for bpf_loop() in place of the loop.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2328  		 */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2329  		if (widen && flow_has_room(env, *nr_states) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2330  		    flow_entries_differ(&t->st, &s->st, cycle))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2331  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2332  		if (!widen && flow_has_room(env, *nr_states) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2333  		    flow_null_differs(flow, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2334  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2335  		if (!widen && flow_needed_consts_differ(flow, FLOW_NEED_ARG, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2336  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2337  		if (flow_callback_depth_differs(env, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2338  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2339  		/* what grows in a loop is not replaced with what is larger, it is forgotten */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2340  		if (!widen && flow_cmp_pkt_range(s, t) <= 0 && flow_within(env, &s->st, &t->st)) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2341  			err = flow_unite(flow, s->st.flow_entry, t->st.flow_entry);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2342  			if (err)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2343  				goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2344  			/*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2345  			 * What a callback comes back with and covers what is there grew, like
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2346  			 * what is joined with it. It counts, or nothing ends "*ctx += 1".
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2347  			 */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2348  			s->joins = max(s->joins, t->joins) + (cycle == FLOW_CALLBACK_CYCLE);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2349  			flow_unlink(env, t);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2350  			flow_free_state(env, t);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2351  			what = what ?: "joined";
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2352  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2353  		}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2354  		if (!widen && flow_cmp_pkt_range(s, t))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2355  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2356  		if (flow_has_room(env, *nr_states) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2357  		    (flow_unset_differs(&t->st, &s->st) ||
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2358  		     (!widen && flow_join_makes_up(flow, &t->st, &s->st))))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2359  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2360  		/*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2361  		 * Around a loop too:
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2362  		 *	u8 stack[10], depth = 0;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2363  		 *	loop {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2364  		 *		if (...) { if (depth >= 10) break; stack[depth++] = x; }
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2365  		 *		else { depth--; if (depth >= 10) break; x = stack[depth]; }
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2366  		 *	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2367  		 * depth is in a 32-bit register. A compiler tests 'depth & 255' and computes it
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2368  		 * anew for the index. What is found out about a copy says nothing about
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2369  		 * a range, and everything about a constant.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2370  		 */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2371  		if (flow_has_room(env, *nr_states) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2372  		    flow_needed_consts_differ(flow, FLOW_NEED_STACK_OFF, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2373  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2374  		if (!widen && flow_has_room(env, *nr_states) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2375  		    flow_needed_consts_differ(flow, FLOW_NEED_PTR_OFF, &t->st, &s->st))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2376  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2377  		err = bpf_states_join(env, &flow->tmp, &t->st, &s->st, widen);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2378  		if (err < 0)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2379  			goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2380  		if (err)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2381  			continue;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2382  		what = widen ? "widened" : "joined";
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2383  		err = flow_unite(flow, s->st.flow_entry, t->st.flow_entry);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2384  		if (err)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2385  			goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2386  		flow->tmp.flow_entry = t->st.flow_entry;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2387  		flow->tmp.last_insn_idx = s->prev_insn_idx;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2388  		s->joins = max(s->joins, t->joins) + 1;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2389  		bpf_free_verifier_state(&s->st, false);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2390  		s->st = flow->tmp;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2391  		memset(&flow->tmp, 0, sizeof(flow->tmp));
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2392  		flow_unlink(env, t);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2393  		flow_free_state(env, t);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2394  		/* the join may be within, or have a join with, what is left in the set */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2395  		goto again;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2396  	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2397  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2398  	if (*nr_states >= BPF_FLOW_MAX_STATES) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2399  		verbose(env, "more than %d states that cannot be joined at insn %d\n",
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2400  			BPF_FLOW_MAX_STATES, insn_idx);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2401  		err = -E2BIG;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2402  		goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2403  	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2404  	if (flow->live_states > BPF_FLOW_LIVE_PER_INSN * env->prog->len + BPF_FLOW_LIVE_BASE ||
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2405  	    env->total_states >
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2406  	    BPF_FLOW_TOTAL_PER_INSN * (u64)env->prog->len + BPF_FLOW_TOTAL_BASE) {
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2407  		verbose(env, "too many states for %d insns: %d, %d at a time\n",
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2408  			env->prog->len, env->total_states, flow->live_states);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2409  		err = -E2BIG;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2410  		goto err_free;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2411  	}
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2412  	/*
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2413  	 * The state is printed when its turn comes. That says enough about a state that
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2414  	 * is new, and about a state that goes on to the next insn.
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2415  	 */
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2416  	if (prev >= 0 && insn_idx == prev + 1 + bpf_is_ldimm64(&env->prog->insnsi[prev]) &&
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2417  	    what && !strcmp(what, "joined"))
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2418  		what = NULL;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2419  	if (log && what)
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2420  		verbose(env, "from %d to %d: %s\n", prev, insn_idx, what);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2421  	flow_link(env, set, s);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2422  	env->max_states_per_insn = max(env->max_states_per_insn, *nr_states);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2423  	return 0;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2424  
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2425  err_free:
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2426  	flow_free_state(env, s);
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2427  	return err;
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2428  }
9b56d2e47f3ad9 Alexei Starovoitov 2026-11-07  2429  

:::::: The code at line 2301 was first introduced by commit
:::::: 9b56d2e47f3ad9314cf263c419d7540fd0e2893f bpf: Merge the state that arrives into the set at an insn

:::::: TO: Alexei Starovoitov <ast@kernel.org>
:::::: CC: Alexei Starovoitov <ast@kernel.org>

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-07 17:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-07 17:35 [bpf-next:master 17/47] kernel/bpf/flow.c:2301 flow_merge() warn: missing unwind goto? kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.