BPF List
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: sashiko-reviews@lists.linux.dev, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v12 07/25] bpf: Refuse a callback that can unwind
Date: Fri, 16 Oct 2026 22:23:58 -0700	[thread overview]
Message-ID: <05918478-1564-4e6f-874a-1a3c4c084097@linux.dev> (raw)
In-Reply-To: <sashiko-outbox-175238@kernel.org>



On 10/16/26 8:19 PM, sashiko-bot@kernel.org wrote:
> 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.

The previous patch 6 indeed has a bug and this may cause
addr_taken_subprog_might)unwind() return false and this will cause
issues. Fixing patch 6 issue should fix the issue.

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


  reply	other threads:[~2026-10-17  5:24 UTC|newest]

Thread overview: 37+ 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
2026-10-17  5:23     ` Yonghong Song [this message]
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
2026-10-17 17:18 ` [PATCH bpf-next v12 00/25] bpf: Run exception cleanup landing pads when bpf_unwind() unwinds Alexei Starovoitov
2026-10-17 18:26   ` Alexei Starovoitov
2026-10-17 20:03   ` Kumar Kartikeya Dwivedi
2026-10-17 21:41     ` 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=05918478-1564-4e6f-874a-1a3c4c084097@linux.dev \
    --to=yonghong.song@linux.dev \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox