From: sashiko-bot@kernel.org
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v2 18/35] bpf: Tell the passes over the graph where an added may_goto goes
Date: Thu, 05 Nov 2026 22:19:00 +0000 [thread overview]
Message-ID: <sashiko-outbox-200300@kernel.org> (raw)
In-Reply-To: <20261105204513.2230344-19-alexei.starovoitov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf: missing head guard target edge in update_insn() stack liveness
--
commit 4a8572cac3df2db5693520d517c638b94138c076
Author: Alexei Starovoitov <ast@kernel.org>
bpf: Tell the passes over the graph where an added may_goto goes
This commit runs bpf_flow_place_guards() earlier and teaches
bpf_compute_const_regs(), compute_subprog_args(), and
bpf_compute_live_registers() about the synthetic edge from a loop header to
bpf_head_guard_target() when a may_goto may be inserted at the loop header.
> diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c
> index 525c0faff1a66..6a2ee407412b8 100644
> --- a/kernel/bpf/liveness.c
> +++ b/kernel/bpf/liveness.c
[ ... ]
> @@ -2780,6 +2796,7 @@ int bpf_compute_live_registers(struct bpf_verifier_env *env)
> u32 new_out = 0;
> u32 new_in = 0;
> u32 use;
> + int t;
>
> succ = bpf_insn_successors(env, insn_idx);
> for (int s = 0; s < succ->cnt; ++s)
> @@ -2794,6 +2811,10 @@ int bpf_compute_live_registers(struct bpf_verifier_env *env)
> use |= state[insn_idx + insns[insn_idx].imm + 1].in &
> mask_widen(GENMASK(BPF_REG_5, BPF_REG_1));
> new_in = (new_out & ~live->def) | use;
> + /* may_goto that is added at the head of a loop goes there */
> + t = bpf_head_guard_target(env, insn_idx);
> + if (t >= 0)
> + new_in |= state[t].in;
> if (new_out != live->out || new_in != live->in) {
> live->in = new_in;
> live->out = new_out;
[Severity: High]
Should the stack-slot liveness pass in update_insn() also union
FM_LIVE_BEFORE of bpf_head_guard_target(env, insn_idx) into new_before, just
as bpf_compute_live_registers() does here for registers?
In kernel/bpf/liveness.c, bpf_compute_subprog_arg_access() ->
analyze_subprog() -> update_instance() -> update_insn() still computes
FM_LIVE_BEFORE using only the static CFG successors:
kernel/bpf/liveness.c:update_insn() {
...
for (s = 0; s < succ->cnt; ++s) {
unsigned long *succ_live;
succ_live = rel_mask(fm, relative_idx(instance, succ->items[s]), FM_LIVE_BEFORE);
for (w = 0; w < fm->words; w++)
new_after[w] |= succ_live[w];
}
may_read = rel_mask(fm, rel, FM_MAY_READ);
must_write = rel_mask(fm, rel, FM_MUST_WRITE);
live_before = rel_mask(fm, rel, FM_LIVE_BEFORE);
...
for (w = 0; w < fm->words; w++) {
unsigned long new_before = (new_after[w] & ~must_write[w]) | may_read[w];
...
}
When a loop has guard_at_header set, bpf_insert_loop_guards() places may_goto
in front of the loop header insn_idx, jumping directly to
t = bpf_head_guard_target(env, insn_idx) before insn_idx or the loop body
executes.
If a stack slot is read at or after t (so FM_LIVE_BEFORE is set at t) and is
overwritten (FM_MUST_WRITE) on every normal path through the loop to t (or by
insn_idx itself), update_insn() clears its bit via ~must_write[w] and marks
the slot dead (FM_LIVE_BEFORE == 0) before the loop header insn_idx.
When a verifier state arrives at insn_idx during the main pass,
flow_arrive() -> bpf_clean_verifier_state() -> clean_verifier_state() ->
__clean_func_state() sees bpf_stack_slot_alive() == false and marks the slot
as STACK_POISON (and resets spilled_ptr to NOT_INIT):
kernel/bpf/states.c:__clean_func_state() {
...
for (i = 0; i < bpf_stack_nr_slots(st); i++) {
bool lo_live = bpf_stack_slot_alive(env, frame, i * 2);
bool hi_live = bpf_stack_slot_alive(env, frame, i * 2 + 1);
if (!hi_live || !lo_live) {
...
if (!hi_live) {
...
bpf_mark_reg_not_init(env, spill);
}
for (j = start; j < end; j++)
bpf_stack_slot(st, i)->slot_type[j] = STACK_POISON;
}
}
}
When check_loop_guard() -> bpf_flow_guard_edge() then propagates that state
from insn_idx to t, the slot arrives at t as STACK_POISON while
FM_LIVE_BEFORE is true at t.
Wouldn't this cause valid stack reads after the loop exit to be rejected with
"slot poisoned by dead code elimination", or cause a spilled pointer erased
to STACK_POISON at the loop header to merge with a scalar/zero slot from a
normal loop exit into STACK_INVALID in join_slot()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261105204513.2230344-1-alexei.starovoitov@gmail.com?part=18
next prev parent reply other threads:[~2026-11-05 22:19 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 20:44 [PATCH bpf-next v2 00/35] bpf: A verifier that joins states Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 01/35] bpf: Add may_goto to the loops that the verifier marks Alexei Starovoitov
2026-11-05 21:14 ` sashiko-bot
2026-11-05 20:44 ` [PATCH bpf-next v2 02/35] bpf: Limit depth and time of recursive subprogs at run time Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 03/35] bpf: Add union and widening of the range of a register Alexei Starovoitov
2026-11-05 21:34 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 04/35] bpf: Add join of registers and stack slots Alexei Starovoitov
2026-11-05 21:16 ` sashiko-bot
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 05/35] bpf: Add join of verifier states Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 21:40 ` sashiko-bot
2026-11-05 20:44 ` [PATCH bpf-next v2 06/35] bpf: Tell which arguments of a call a join must leave alone Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 07/35] bpf: Add the data structures of the main pass over the control flow graph Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 08/35] bpf: Order the insns, find what stops a loop and where may_goto can go Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 09/35] bpf: Find the registers that hold a number or a pointer to arena Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 21:40 ` sashiko-bot
2026-11-05 20:44 ` [PATCH bpf-next v2 10/35] bpf: Find the registers and stack slots that later checks depend on Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 11/35] bpf: Add the sets of states at an insn and the entries of functions Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 12/35] bpf: Compare states of different iterations of a loop Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 13/35] bpf: Decide which states are not joined Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 14/35] bpf: Merge the state that arrives into the set at an insn Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 15/35] bpf: Move states along edges, into loops and subprogs and out of them Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 16/35] bpf: Make the state after a call from the caller's state and an exit state Alexei Starovoitov
2026-11-05 20:44 ` [PATCH bpf-next v2 17/35] bpf: Enter and leave loops in the main pass, build flow.c Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 18/35] bpf: Tell the passes over the graph where an added may_goto goes Alexei Starovoitov
2026-11-05 22:19 ` sashiko-bot [this message]
2026-11-05 20:44 ` [PATCH bpf-next v2 19/35] bpf: Verify programs as a fixpoint over the control flow graph Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 22:45 ` sashiko-bot
2026-11-05 20:44 ` [PATCH bpf-next v2 20/35] bpf: Keep the count of a loop when a register has no closed form Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:44 ` [PATCH bpf-next v2 21/35] bpf: Verify static subprogs on their own Alexei Starovoitov
2026-11-05 21:51 ` bot+bpf-ci
2026-11-05 22:45 ` sashiko-bot
2026-11-05 20:44 ` [PATCH bpf-next v2 22/35] bpf: Allow recursive subprogs Alexei Starovoitov
2026-11-05 21:51 ` bot+bpf-ci
2026-11-05 23:09 ` sashiko-bot
2026-11-05 20:45 ` [PATCH bpf-next v2 23/35] bpf: Remove is_state_visited(), bpf_compute_scc() and iter.depth Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 24/35] bpf: Remove precision tracking Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 25/35] bpf: Remove prune points, levels of state comparison and pop_stack() Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 26/35] bpf: Update comments about paths, pruning and explored states Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 27/35] bpf: Track a pointer to one of a set of functions Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 28/35] bpf: callx reads what the subprogs whose address is taken read Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 29/35] selftests/bpf: Adjust tests to log lines that are gone Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:45 ` [PATCH bpf-next v2 30/35] selftests/bpf: Adjust tests to new verdicts, messages and order Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:45 ` [PATCH bpf-next v2 31/35] selftests/bpf: Test states that are not joined Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:45 ` [PATCH bpf-next v2 32/35] selftests/bpf: Test static subprogs that are verified on their own Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 20:45 ` [PATCH bpf-next v2 33/35] selftests/bpf: Test loops that are counted, walked or widened Alexei Starovoitov
2026-11-05 20:45 ` [PATCH bpf-next v2 34/35] selftests/bpf: Test progs that run out of budget Alexei Starovoitov
2026-11-05 21:35 ` bot+bpf-ci
2026-11-05 23:19 ` sashiko-bot
2026-11-05 20:45 ` [PATCH bpf-next v2 35/35] selftests/bpf: Test callx of one of a set of functions Alexei Starovoitov
2026-11-05 23:17 ` sashiko-bot
2026-11-06 0:34 ` [PATCH bpf-next v2 00/35] bpf: A verifier that joins states Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-200300@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.