* [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.