All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Eduard Zingerman" <eddyz87@gmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v3 35/51] bpf: avoid widening registers that hinder exact stack-slot tracking
Date: Fri, 09 Oct 2026 12:08:17 +0000	[thread overview]
Message-ID: <sashiko-outbox-165481@kernel.org> (raw)
In-Reply-To: <20261009-scev-minimal-rebase-v3-35-bcba9bc53ac9@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] bpf: call_params_mask clobbers callee-saved registers for kfuncs with >5 args
- [Medium] bpf: bpf_needs_fixed_stack_off ignores module kfuncs and stack dynptrs
--

commit c21aed6872d1b94060c148c7501830216020d7e4
Author: Eduard Zingerman <eddyz87@gmail.com>

bpf: avoid widening registers that hinder exact stack-slot tracking

This commit adds logic to avoid widening registers used by stack-accessing
instructions during SCEV-based loop analysis. This prevents replacing
constant-offset stack accesses with varying-offset accesses, preserving
verifier precision for spills, fills, and calls requiring fixed stack
offsets.

> diff --git a/kernel/bpf/scev.c b/kernel/bpf/scev.c
> index 05dd8e439609b..adad32d8cb124 100644
> --- a/kernel/bpf/scev.c
> +++ b/kernel/bpf/scev.c
[ ... ]
> @@ -1100,6 +1100,70 @@ static void reset_scevs_at_indirect_writes(struct bpf_verifier_env *env, struct
[ ... ]
> +/* Mask of argument registers (R1..R5) a call at 'idx' passes by register. */
> +static u16 call_params_mask(struct bpf_verifier_env *env, int idx)
> +{
> +	struct bpf_insn *insn = &env->prog->insnsi[idx];
> +	struct bpf_call_summary cs;
> +	int n = bpf_get_call_summary(env, insn, &cs) ? cs.arg_slot_cnt : MAX_BPF_FUNC_REG_ARGS;
> +
> +	return n ? GENMASK(BPF_REG_1 + n - 1, BPF_REG_1) : 0;
> +}

[Severity: Medium]
Does this code overflow the bitmask into callee-saved registers when a
kfunc takes arguments on the stack?

bpf_get_call_summary() returns the total number of arguments in
cs.arg_slot_cnt, which can exceed 5 (MAX_BPF_FUNC_REG_ARGS) for kfuncs
that accept stack arguments.

Since GENMASK(BPF_REG_1 + n - 1, BPF_REG_1) does not cap 'n', an 'n'
greater than 5 will set bits for callee-saved registers (R6-R10).

If one of these unrelated registers happens to hold a stack pointer,
collect_store_base_regs() might erroneously record it as a base register
for the call. This could falsely prevent SCEV from widening unrelated
loops, causing the verifier to unnecessarily unroll the loop and
potentially hit complexity limits.

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a597a8c189723..2f190abe34489 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -14257,6 +14257,55 @@ static bool kfunc_spin_allowed(struct bpf_verifier_env *env, s32 func_id, s16 of
[ ... ]
> +bool bpf_needs_fixed_stack_off(struct bpf_verifier_env *env, int insn_idx)
> +{
> +	const struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
[ ... ]
> +	/* Both initialized and uninitialized stack dynptrs need a fixed offset. */
> +	for (i = 0; i < ARRAY_SIZE(fn->arg_type); i++)
> +		if (arg_type_is_dynptr(fn->arg_type[i]))
> +			return true;

[Severity: Medium]
Does this loop miss dynptrs that are passed on the stack?

Because fn->arg_type is strictly bounded to 5 elements, this iteration
will skip checking a dynptr if it is passed as a 6th argument (or later)
on the stack.

If missed, collect_store_base_regs() fails to record the base registers,
allowing the SCEV pass to widen the stack pointer and turn its constant
offset into a variable range. The verifier will then reject the dynptr
call because it strictly enforces a constant offset.

> +
> +	/* vmlinux kfuncs only */
> +	if (!bpf_pseudo_kfunc_call(insn) || insn->off != 0)
> +		return false;

[Severity: Medium]
Will this check skip BPF module iterators?

By returning false if insn->off != 0, this explicitly ignores any kfuncs
exposed by BPF modules. Modules can provide their own iterators (like
bpf_iter_testmod_seq_new with KF_ITER_NEW).

Similar to the dynptr issue above, skipping these iterators means the
base registers won't be recorded. This causes the stack pointer to be
widened and leads to valid programs utilizing module iterators being
falsely rejected by the verifier.

> +	btf_id = insn->imm;
> +
> +	flags = btf_kfunc_flags(btf_vmlinux, btf_id, env->prog);
> +	if (flags && (*flags & (KF_ITER_NEW | KF_ITER_NEXT | KF_ITER_DESTROY)))
> +		return true;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-scev-minimal-rebase-v3-0-bcba9bc53ac9@gmail.com?part=35

  parent reply	other threads:[~2026-10-09 12:08 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-09 10:47 [PATCH bpf-next v3 00/51] bpf: use scalar evolution to widen bounded loops Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 01/51] bpf: represent stack access effects with arg_access_info Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 02/51] bpf: describe helper stack accesses " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 03/51] bpf: describe kfunc " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 04/51] bpf: track may_write flags in liveness Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 05/51] bpf: summarize may write stack slots in insn_aux_data Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 06/51] bpf: summarize live " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 07/51] bpf: summarize regs that may hold a frame pointer " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 08/51] bpf: record write effects for atomic operations in liveness.c Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 09/51] bpf: fix arg_track_xfer() for atomic stack spills and fills Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 10/51] bpf: derive global subprog stack liveness from BTF signatures Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 18:49     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 11/51] bpf: compute parameters liveness in bpf_compute_live_registers() Eduard Zingerman
2026-10-09 11:26   ` sashiko-bot
2026-10-09 18:46     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 12/51] bpf: add tnum_alignment() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 13/51] bpf: add cnum{32,64}_union() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 14/51] bpf: add cnum64_intersect_linear() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 15/51] bpf: expose bpf_rev_opcode() and bpf_flip_opcode() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 16/51] bpf: expose bpf_grow_stack_state() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 17/51] bpf: expose bpf_verbose_snum() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 18/51] bpf: allow subrange relations for PTR_TO_STACK in regsafe() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 19/51] bpf: representation for intervals with steps Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 18:55     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 20/51] bpf: varying offset access support for PTR_TO_BTF_ID pointers Eduard Zingerman
2026-10-09 11:41   ` sashiko-bot
2026-10-09 19:43     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 21/51] bpf: save DFS postorder numbers for program instructions Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 22/51] bpf: move the live-register and SCC printout to a standalone function Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 23/51] bpf: compute immediate dominators Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 24/51] bpf: compute loop hierarchy Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 25/51] bpf: add bpf_set_reg_range() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 26/51] bpf: add bpf_mark_reg_known_scalar() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 27/51] bpf: add bpf_reg_union() and bpf_reg_union_compatible() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 28/51] bpf: add bpf_split_cur_state() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 29/51] bpf: add bpf_same_memory_origin() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 30/51] bpf: add bpf_spill_size() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 31/51] bpf: record basic-block ends in insn_aux_data Eduard Zingerman
2026-10-09 11:45   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 32/51] bpf: allow precision backtracking between overlapping checkpoints Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 33/51] bpf: compute scalar evolution expressions for loops Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 34/51] bpf: use SCEV to widen bounded loops Eduard Zingerman
2026-10-09 12:08   ` bot+bpf-ci
2026-10-10  1:25   ` kernel test robot
2026-10-10 14:55     ` Alexei Starovoitov
2026-10-10 20:02       ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 35/51] bpf: avoid widening registers that hinder exact stack-slot tracking Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 12:08   ` sashiko-bot [this message]
2026-10-09 10:47 ` [PATCH bpf-next v3 36/51] bpf: bpf_func_state size optimization Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 37/51] selftests/bpf: __msg_next tag for matching messages on consecutive lines Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 38/51] selftests/bpf: bound UNIX socket path loops by sun_path size Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 39/51] selftests/bpf: test for stack-pointer subrange pruning Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 40/51] selftests/bpf: tests for may_write stack-liveness tracking Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 41/51] selftests/bpf: tests for may_def marks of atomic RMW operations Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 42/51] selftests/bpf: tests for stack pointer spills/fills through atomics Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 43/51] selftests/bpf: tests for map special cases in bpf_helper_stack_access_bytes() Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 44/51] selftests/bpf: tests for BTF-based global subprog stack liveness Eduard Zingerman
2026-10-09 11:45   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 45/51] selftests/bpf: test for register liveness of subprogram arguments Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 46/51] selftests/bpf: tests for register base/step arithmetic Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 47/51] selftests/bpf: tests for register base/step state pruning Eduard Zingerman
2026-10-09 12:22   ` sashiko-bot
2026-10-09 10:48 ` [PATCH bpf-next v3 48/51] selftests/bpf: tests for varying offset access to PTR_TO_BTF_ID Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 49/51] selftests/bpf: tests for loop hierarchy computation Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 50/51] selftests/bpf: tests for immediate dominator computation Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 51/51] selftests/bpf: tests for SCEV analysis and loop widening Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 20:40 ` [PATCH bpf-next v3 00/51] bpf: use scalar evolution to widen bounded loops patchwork-bot+netdevbpf

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-165481@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=eddyz87@gmail.com \
    --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.