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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox