From: Yonghong Song <yonghong.song@linux.dev>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>, 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 10:36:35 -0700 [thread overview]
Message-ID: <1387e30f-8793-4c92-b726-22c0ac0f3d2c@linux.dev> (raw)
In-Reply-To: <DLJ0YT6G4EZK.22FEDYYMKS4E0@gmail.com>
On 9/18/26 9:57 PM, Alexei Starovoitov wrote:
> 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.
Yes, this is a real issue for backtracking. The problem is stated in
the above curframe doesn't match for frames after unwind_step(), mostly
due to backtracking from landing pad insn to bpf_throw. Will fix.
>
> pw-bot: cr
next prev parent reply other threads:[~2026-09-19 17:36 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
2026-09-19 17:36 ` Yonghong Song [this message]
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=1387e30f-8793-4c92-b726-22c0ac0f3d2c@linux.dev \
--to=yonghong.song@linux.dev \
--cc=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 \
/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.