From: sashiko-bot@kernel.org
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Subject: Re: [PATCH v4 bpf-next 2/6] bpf, x86: Support unwind_goto and unwind_exit
Date: Tue, 20 Oct 2026 18:56:05 +0000 [thread overview]
Message-ID: <sashiko-outbox-179498@kernel.org> (raw)
In-Reply-To: <20261020181320.1284798-3-alexei.starovoitov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf, x86: emit_unwind_ret_addr() in exception_cb unwinds caller frame
--
commit c3cf97c5b42c930ee82a85d0896d91eed8f4f5f6
Author: Alexei Starovoitov <ast@kernel.org>
bpf, x86: Support unwind_goto and unwind_exit
This commit adds x86 JIT support for the BPF unwind_goto and unwind_exit
instructions using exception table entries and return address fixups.
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 72a2a0a89e033..d3ab36281144d 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
[ ... ]
> +static u64 bpf_unwind_target(u64 ret_addr)
> +{
> + const struct exception_table_entry *e = search_bpf_extables(ret_addr - 1);
> +
> + /*
> + * The verifier made sure that unwind_goto follows a call in a prog. When
> + * the kernel called an async or an exception callback, it's exit.
> + */
> + return e ? ret_addr + e->fixup : ret_addr;
> +}
> +
> +/* unwind_exit: fix the return address of this frame. r0 and r2 are returned. */
> +static int emit_unwind_ret_addr(u8 **pprog, u8 *ip)
> +{
> + u8 *prog = *pprog, *start = prog;
> +
> + EMIT2(0x50, 0x56); /* push rax; push rsi */
> + EMIT4(0x48, 0x8B, 0x7D, 0x08); /* mov rdi, [rbp + 8] */
> + ip += prog - start;
> + ip += x86_call_depth_emit_accounting(&prog, bpf_unwind_target, ip);
> + if (emit_call(&prog, bpf_unwind_target, ip))
> + return -EINVAL;
> + EMIT4(0x48, 0x89, 0x45, 0x08); /* mov [rbp + 8], rax */
> + EMIT2(0x5E, 0x58); /* pop rsi; pop rax */
> + *pprog = prog;
> + return 0;
> +}
[ ... ]
> @@ -3774,13 +3865,16 @@ static int do_jit(struct bpf_verifier_env *env, struct bpf_prog *bpf_prog, int *
> break;
>
> case BPF_JMP | BPF_EXIT:
> + if (src_reg == BPF_UNWIND_EXIT && bpf_prog_can_unwind(bpf_prog) &&
> + emit_unwind_ret_addr(&prog, ip))
> + return -EINVAL;
[Severity: High]
Can emitting emit_unwind_ret_addr() inside an exception callback subprogram
cause unwind_exit to unwind the exception boundary's caller frame into an
unverified landing pad?
In include/linux/filter.h, bpf_prog_can_unwind() returns true for any
subprogram:
include/linux/filter.h:bpf_prog_can_unwind() {
return bpf_is_subprog(prog) || prog->type == BPF_PROG_TYPE_EXT;
}
Because an exception callback is a subprogram (bpf_prog->aux->func_idx != 0
with bpf_prog->aux->exception_cb set), bpf_prog_can_unwind(bpf_prog) is true
in do_jit(), while the verifier treats BPF_UNWIND_EXIT in an exception
callback as a normal frame-0 exit in process_bpf_exit_full() and ignores the
exception callback when setting prog->aux->can_unwind in check_unwind_insns().
The comment in bpf_unwind_target() assumes that when the kernel invokes an
exception callback, the return address at [rbp + 8] belongs to the kernel
caller and will not match any BPF extable entry. However, in
arch/x86/net/bpf_jit_comp.c, emit_prologue() resets rbp to the third argument
(ctx.bp of the exception boundary frame found by bpf_stack_walker()):
arch/x86/net/bpf_jit_comp.c:emit_prologue() {
if (is_exception_cb) {
EMIT3(0x48, 0x89, 0xF4); /* mov rsp, rsi */
EMIT3(0x48, 0x89, 0xD5); /* mov rbp, rdx */
...
EMIT3(0x48, 0x89, 0xEC); /* mov rsp, rbp */
}
As a result, [rbp + 8] inside the exception callback is the return address of
the exception boundary frame (func[0]), not bpf_throw().
If the exception boundary frame was entered via a tail call from a subprogram
that was called before an unwind_goto instruction, or if an extension program
(BPF_PROG_TYPE_EXT) with can_unwind == false on func[0] replaces a global
subprogram followed by an unwind_goto instruction and then calls bpf_throw(),
[rbp + 8] points to the instruction after the subprogram call in the caller.
When the exception callback executes BPF_UNWIND_EXIT, bpf_unwind_target()
finds the caller's unwind_goto extable entry and redirects [rbp + 8] to the
landing pad with register and stack state that the verifier never checked for
that path.
Should bpf_prog_can_unwind() (or the check in do_jit()) exclude
prog->aux->exception_cb?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261020181320.1284798-1-alexei.starovoitov@gmail.com?part=2
next prev parent reply other threads:[~2026-10-20 18:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 18:13 [PATCH v4 bpf-next 0/6] bpf: Unwinding with unwind_goto and unwind_exit Alexei Starovoitov
2026-10-20 18:13 ` [PATCH v4 bpf-next 1/6] bpf: Add unwind_goto and unwind_exit insns Alexei Starovoitov
2026-10-20 18:57 ` sashiko-bot
2026-10-20 18:13 ` [PATCH v4 bpf-next 2/6] bpf, x86: Support unwind_goto and unwind_exit Alexei Starovoitov
2026-10-20 18:55 ` bot+bpf-ci
2026-10-20 18:56 ` sashiko-bot [this message]
2026-10-20 18:13 ` [PATCH v4 bpf-next 3/6] bpf, arm64: " Alexei Starovoitov
2026-10-20 18:55 ` bot+bpf-ci
2026-10-20 18:13 ` [PATCH v4 bpf-next 4/6] selftests/bpf: Add tests for " Alexei Starovoitov
2026-10-20 18:13 ` [PATCH v4 bpf-next 5/6] selftests/bpf: Add a C++ prog with exceptions Alexei Starovoitov
2026-10-20 18:13 ` [PATCH v4 bpf-next 6/6] selftests/bpf: Test unwinding from R0:R2 subprog 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=sashiko-outbox-179498@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alexei.starovoitov@gmail.com \
--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