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
next prev parent 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