All of lore.kernel.org
 help / color / mirror / Atom feed
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

  parent reply	other threads:[~2026-10-20 18:56 UTC|newest]

Thread overview: 13+ 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 20:04     ` Alexei Starovoitov
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
2026-10-20 21:00 ` [PATCH v4 bpf-next 0/6] bpf: Unwinding with unwind_goto and unwind_exit patchwork-bot+netdevbpf

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 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.