From: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
To: "Yonghong Song" <yonghong.song@linux.dev>, <bpf@vger.kernel.org>
Cc: "Andrii Nakryiko" <andrii@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eduard Zingerman" <eddyz87@gmail.com>, <kernel-team@fb.com>
Subject: Re: [PATCH bpf-next 08/20] bpf: Walk the exception unwind in the verifier
Date: Sat, 19 Sep 2026 04:57:24 +0000 [thread overview]
Message-ID: <DLJ0YT6G4EZK.22FEDYYMKS4E0@gmail.com> (raw)
In-Reply-To: <20260917055726.3930930-1-yonghong.song@linux.dev>
On Wed, Sep 16, 2026 at 10:57 PM Yonghong Song <yonghong.song@linux.dev> wrote:
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 9cbdb8339701..a3b34ded1392 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[...]
> +static int unwind_step(struct bpf_verifier_env *env, u32 callsite, int *insn_idx)
> +{
> + struct bpf_verifier_state *state = env->cur_state;
> +
> + state->unwinding = true;
> + for (;;) {
> + int pad = bpf_cleanup_pad_of_call(env, callsite);
> +
> + if (pad >= 0) {
> + unwind_enter_pad(env);
> + *insn_idx = pad;
> + return INSN_IDX_UPDATED;
> + }
> + if (!state->curframe)
> + return unwind_finish(env);
> + callsite = unwind_pop_frame(env);
> + }
> +}
robot voice:
mark_chain_precision() doesn't know about this edge. The jmp history
gets (bpf_throw in frame N+k) -> (pad in frame N), or (resume in N+1)
-> (pad in N), with no BPF_EXIT in between, and backtrack_insn() only
switches frames on E
XIT and pseudo calls. So bt->frame stays at N
while it walks the callee's insns backwards. If the callee wrote its
own r6 the request for the caller's r6 is cleared there, the caller's
def of r6 is never marked precise, and a later state with a different
r6 is pruned at the call site checkpoint even though the pad does
r10 + r6 with it. If the callee didn't touch r6 the walk reaches the
static call insn with r6 still set and hits
verifier_bug("static subprog unexpected regs"). For a throwing global
subprog it's verifier_bug_if(idx + 1 != subseq_idx) right away.
The unwind transition needs its own jmp history flag and
backtrack_insn() has to bt_subprog_enter() once per popped frame,
like it does for BPF_EXIT.
Pls add a test that does a variable offset stack access in a pad
with the offset coming from r6-r9 set before the throwing call.
> +static int process_cleanup_resume(struct bpf_verifier_env *env, int *insn_idx)
> +{
> + struct bpf_verifier_state *state = env->cur_
state;
> +
> + /* A pad entered by ordinary control flow. */
> + if (!state->unwinding) {
> + verbose(env,
> + "bpf_unwind_resume() at insn %d reached without an exception in flight\n",
> + *insn_idx);
> + return -EINVAL;
> + }
> + if (!state->curframe)
> + return unwind_finish(env);
> + return unwind_step(env, unwind_pop_frame(env), insn_idx);
> +}
unwinding is one bit for the whole state, so once a throw happened a
bpf_unwind_resume() is accepted in any frame, not only in the frame
whose pad the walker dispatched. The in_pad rule from patch 7 doesn't
close it: take subprog S that never throws, has its own record, and
whose pad is just "call bpf_unwind_resume" reachable by a plain branch
from S's entry. F's pad does "call S" and S branches into its pad.
Here the verifier pops S, finds no pad for the "call S" site, pops F
and finishes, so whatever follows "call S" in F's pad is never walked
in this state. On x86 S's resume is a bare ret, so at run time it
returns into F's pad right after "call S" and keeps executing it with
S's leftover registers. On arm64 br x23 ends F's pad early instead.
Remember the frame unwind_step() entered the pad in and reject
bpf_unwind_resume() when curframe doesn't match.
pw-bot: cr
next prev parent reply other threads:[~2026-09-19 4:57 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-17 5:56 [PATCH bpf-next 00/20] bpf: Run exception cleanup landing pads when bpf_throw() unwinds Yonghong Song
2026-09-17 5:56 ` [PATCH bpf-next 01/20] bpf: Accept the compiler's exception cleanup table at program load Yonghong Song
2026-09-17 5:56 ` [PATCH bpf-next 02/20] bpf: Add the bpf_unwind_resume() kfunc Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 03/20] bpf: Add lookups for exception cleanup resumes and landing pads Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 04/20] bpf: Mark the call sites an exception cleanup table covers Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 05/20] bpf: Make exception landing pads reachable in the CFG Yonghong Song
2026-09-17 6:22 ` sashiko-bot
2026-09-18 3:36 ` Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 06/20] bpf: Explore the landing pads no call site reaches Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 07/20] bpf: Refuse exception cleanup shapes bpf_throw() cannot dispatch Yonghong Song
2026-09-19 4:57 ` Alexei Starovoitov
2026-09-19 17:32 ` Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 08/20] bpf: Walk the exception unwind in the verifier Yonghong Song
2026-09-19 4:57 ` Alexei Starovoitov [this message]
2026-09-19 17:36 ` Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 09/20] bpf: Refuse a private stack for a program with an exception cleanup table Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 10/20] bpf: Dispatch exception cleanup pads from bpf_throw() Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 11/20] bpf, x86: Dispatch exception cleanup pads at run time Yonghong Song
2026-09-19 5:02 ` Alexei Starovoitov
2026-09-19 19:13 ` Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 12/20] bpf, arm64: " Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 13/20] libbpf: Resolve the compiler's _Unwind_Resume to the kernel's kfunc Yonghong Song
2026-09-17 6:08 ` sashiko-bot
2026-09-17 7:00 ` bot+bpf-ci
2026-09-18 3:40 ` Yonghong Song
2026-09-17 5:57 ` [PATCH bpf-next 14/20] libbpf: Add cleanup_info to bpf_prog_load_opts Yonghong Song
2026-09-17 5:58 ` [PATCH bpf-next 15/20] libbpf: Collect .bpf_cleanup records and pass them to the kernel Yonghong Song
2026-09-17 6:12 ` sashiko-bot
2026-09-18 3:44 ` Yonghong Song
2026-09-17 5:58 ` [PATCH bpf-next 16/20] libbpf: Carry the exception cleanup table through the light skeleton Yonghong Song
2026-09-17 6:18 ` sashiko-bot
2026-09-18 3:52 ` Yonghong Song
2026-09-17 5:58 ` [PATCH bpf-next 17/20] libbpf: Let the static linker carry .bpf_cleanup relocations Yonghong Song
2026-09-17 6:16 ` sashiko-bot
2026-09-18 3:58 ` Yonghong Song
2026-09-17 5:58 ` [PATCH bpf-next 18/20] selftests/bpf: Add an end-to-end .bpf_cleanup exception test Yonghong Song
2026-09-17 6:12 ` sashiko-bot
2026-09-17 5:58 ` [PATCH bpf-next 19/20] selftests/bpf: Cover the exception cleanup shapes the chain does not reach Yonghong Song
2026-09-17 6:16 ` sashiko-bot
2026-09-17 5:58 ` [PATCH bpf-next 20/20] 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=DLJ0YT6G4EZK.22FEDYYMKS4E0@gmail.com \
--to=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@fb.com \
--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