BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yonghong Song" <yonghong.song@linux.dev>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v12 07/25] bpf: Refuse a callback that can unwind
Date: Sat, 17 Oct 2026 03:19:29 +0000	[thread overview]
Message-ID: <sashiko-outbox-175238@kernel.org> (raw)
In-Reply-To: <20261017025206.1920523-1-yonghong.song@linux.dev>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf: missing might_unwind propagation to callback in bpf_check_cfg()
--

commit 1785732c5b5ae17b86f08f6a94449da36fb9c958
Author: Yonghong Song <yonghong.song@linux.dev>

bpf: Refuse a callback that can unwind

This commit adds bpf_exc_check_callback() and calls it in
push_callback_call() to reject callback subprograms that have
might_unwind set.

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index fce2baa6272d1..fcf0d0fe0f2ff 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -11191,6 +11191,10 @@ static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *ins
>  	 * callbacks
>  	 */
>  	env->subprog_info[subprog].is_cb = true;
> +	err = bpf_exc_check_callback(env, subprog);
> +	if (err)
> +		return err;
> +
>  	if (bpf_pseudo_kfunc_call(insn) &&
>  	    !is_callback_calling_kfunc(insn->imm)) {
>  		verifier_bug(env, "kfunc %s#%d not marked as callback-calling",

[Severity: High]
Can a callback subprogram that transitively calls bpf_unwind() bypass
bpf_exc_check_callback() with env->subprog_info[subprog].might_unwind
still false?

In bpf_check_cfg(), direct calls (BPF_PSEUDO_CALL), function address
loads (BPF_PSEUDO_FUNC), and read-only map function pointer loads
(insn_func_ptrs()) are explored in a single DFS sharing
env->cfg.insn_state[]:

kernel/bpf/cfg.c:merge_callee_effects() {
	caller = bpf_find_containing_subprog(env, t);
	callee = bpf_find_containing_subprog(env, w);
	caller->changes_pkt_data |= callee->changes_pkt_data;
	caller->might_sleep |= callee->might_sleep;
	caller->might_throw |= callee->might_throw;
	caller->might_unwind |= callee->might_unwind;
}

merge_callee_effects() relies on callee w already being EXPLORED when
returning to caller t. However, if subprogram H has a conditional branch
whose fallthrough loads a read-only map containing the address of
callback cb via insn_func_ptrs() (or loads cb via BPF_PSEUDO_FUNC when H
is explored from a cleanup pad before main's fallthrough) and whose jump
target calls bpf_unwind(), while cb calls H via BPF_PSEUDO_CALL:

1. bpf_check_cfg() enters H (marking insn_state[w_H] = DISCOVERED) and
   explores H's fallthrough first, before visiting H's bpf_unwind()
   branch, so H->might_unwind is still false.

2. H's fallthrough visits cb via visit_func_ptrs_insn() or
   visit_func_call_insn().

3. When cb visits its BPF_PSEUDO_CALL to H, merge_callee_effects() sees
   H->might_unwind == false, and push_insn() sees
   (insn_state[w_H] & 0xF0) == DISCOVERED and returns DONE_EXPLORING.
   Thus cb finishes CFG exploration with cb->might_unwind == false
   before H explores its bpf_unwind() branch and sets
   H->might_unwind = true.

4. At the end of bpf_check_cfg(), mark_callx_might_unwind() checks
   addr_taken_subprog_might_unwind():

kernel/bpf/cfg.c:mark_callx_might_unwind() {
	if (!addr_taken_subprog_might_unwind(env))
		return;
    ...
}

   Because the address-taken subprogram cb still has might_unwind == false,
   addr_taken_subprog_might_unwind() returns false and skips the
   fixed-point propagation loop.

5. Neither sort_subprogs_topo() nor check_max_stack_depth() rejects the
   program because insn_func_ptrs() edges are not call edges and async
   BPF_PSEUDO_FUNC callbacks are skipped in stack depth checks.

When push_callback_call() then calls bpf_exc_check_callback(env, cb),
env->subprog_info[cb].might_unwind is false, allowing the unwinding
callback to pass verification and cause a verifier/runtime control-flow
mismatch or jump to a zero epilogue_ip when bpf_unwind() is invoked at
runtime.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261017025129.1914859-1-yonghong.song@linux.dev?part=7

  reply	other threads:[~2026-10-17  3:19 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-17  2:51 [PATCH bpf-next v12 00/25] bpf: Run exception cleanup landing pads when bpf_unwind() unwinds Yonghong Song
2026-10-17  2:51 ` [PATCH bpf-next v12 01/25] bpf: Accept the compiler's exception cleanup table at program load Yonghong Song
2026-10-17  2:51 ` [PATCH bpf-next v12 02/25] bpf: Add the bpf_unwind() and bpf_unwind_resume() kfuncs Yonghong Song
2026-10-17  2:51 ` [PATCH bpf-next v12 03/25] bpf: Keep a call site's landing pad in insn_aux_data, add lookups Yonghong Song
2026-10-17  2:51 ` [PATCH bpf-next v12 04/25] bpf: Mark covered call sites and check a program can take a table Yonghong Song
2026-10-17  2:51 ` [PATCH bpf-next v12 05/25] bpf: Make exception landing pads reachable in the CFG Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 06/25] bpf: Verify an unwind through landing pads and epilogues Yonghong Song
2026-10-17  3:27   ` sashiko-bot
2026-10-17  5:20     ` Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 07/25] bpf: Refuse a callback that can unwind Yonghong Song
2026-10-17  3:19   ` sashiko-bot [this message]
2026-10-17  5:23     ` Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 08/25] bpf: Refuse a landing pad that does not resume Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 09/25] bpf: Do not use a private stack for a program that can unwind Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 10/25] bpf: Prepare JITed programs for dispatching cleanup pads Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 11/25] bpf: Keep an epilogue for each subprog an unwind can pass through Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 12/25] bpf: Allow a subprog to end with a call that does not return Yonghong Song
2026-10-17  3:35   ` bot+bpf-ci
2026-10-17  5:38     ` Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 13/25] bpf: Dispatch cleanup pads by rewriting return addresses Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 14/25] bpf: Refuse a trampoline that calls a subprog that can unwind Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 15/25] bpf, x86: Dispatch exception cleanup pads at run time Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 16/25] bpf, arm64: " Yonghong Song
2026-10-17  2:52 ` [PATCH bpf-next v12 17/25] libbpf: Resolve the compiler's _Unwind_Resume to the kernel's kfunc Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 18/25] libbpf: Add cleanup_info to bpf_prog_load_opts Yonghong Song
2026-10-17  2:57   ` sashiko-bot
2026-10-17  2:53 ` [PATCH bpf-next v12 19/25] libbpf: Collect .bpf_cleanup records and pass them to the kernel Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 20/25] libbpf: Carry the exception cleanup table through the light skeleton Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 21/25] libbpf: Let the static linker carry .bpf_cleanup relocations Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 22/25] selftests/bpf: Add end-to-end and negative .bpf_cleanup exception tests Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 23/25] selftests/bpf: Add __set_global() and __ret_global() test tags Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 24/25] selftests/bpf: Cover more accepted .bpf_cleanup exception shapes Yonghong Song
2026-10-17  2:53 ` [PATCH bpf-next v12 25/25] selftests/bpf: Load an exception cleanup program from a light skeleton Yonghong Song

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-175238@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=yonghong.song@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox