From: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
To: "Yonghong Song" <yonghong.song@linux.dev>, <bpf@vger.kernel.org>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>, <kernel-team@fb.com>,
"Martin KaFai Lau" <martin.lau@kernel.org>
Subject: Re: [PATCH bpf-next v3 6/7] bpf,x86: Fix exception unwinding with outgoing stack arguments
Date: Sat, 16 May 2026 17:59:02 -0700 [thread overview]
Message-ID: <DIKJM7FYGJ9K.2H5U2EPKDENME@gmail.com> (raw)
In-Reply-To: <20260515225106.824804-1-yonghong.song@linux.dev>
On Fri May 15, 2026 at 3:51 PM PDT, Yonghong Song wrote:
> When a main program with exception_boundary has outgoing stack
> arguments (e.g. from calling subprogs with >5 args), bpf_throw() fails
> to correctly restore callee-saved registers, causing a kernel crash.
>
> The x86 JIT allocates the outgoing stack arg area below the
> callee-saved registers via 'sub rsp, outgoing_rsp' in the prologue.
> When bpf_throw() unwinds, it captures the main program's sp (which
> includes this outgoing area) and passes it to the exception callback.
> The callback gets rsp and rbp, followed by pop_callee_regs, but rsp
> points into the outgoing arg area rather than the callee-saved
> registers, so the pops restore garbage values. Returning to the
> kernel with corrupted callee-saved registers causes a crash.
>
> Fix this by passing the main program's outgoing_rsp as the 4th
> argument to the exception callback. The callback adjusts rsp with
> 'add rsp, rcx' before popping callee-saved registers, correctly
> skipping the outgoing arg area. When outgoing_rsp is 0 (the common
> case), this is a no-op.
>
> Fixes: 324c3ca6eed6 ("bpf,x86: Implement JIT support for stack arguments")
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
> arch/x86/net/bpf_jit_comp.c | 9 ++++++++-
> include/linux/bpf.h | 3 ++-
> kernel/bpf/fixups.c | 1 +
> kernel/bpf/helpers.c | 2 +-
> 4 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index ceefefb4da21..f4fdceedaad7 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -557,10 +557,15 @@ static void emit_prologue(u8 **pprog, u8 *ip, u32 stack_depth, bool ebpf_from_cb
> /* Keep the same instruction layout. */
> emit_nops(&prog, 3); /* nop3 */
> }
> - /* Exception callback receives FP as third parameter */
> + /*
> + * Exception callback receives:
> + * rsi = main program's SP, rdx = main program's FP,
> + * rcx = main program's outgoing stack arg area size
> + */
> if (is_exception_cb) {
> EMIT3(0x48, 0x89, 0xF4); /* mov rsp, rsi */
> EMIT3(0x48, 0x89, 0xD5); /* mov rbp, rdx */
> + EMIT3(0x48, 0x01, 0xCC); /* add rsp, rcx */
Maybe let's do it on C side like:
bpf_exception_cb(cookie, ctx.sp + ctx.aux->stack_arg_adjust, ctx.bp, 0);
Avoids the need to use 'rcx'.
> /* The main frame must have exception_boundary as true, so we
> * first restore those callee-saved regs from stack, before
> * reusing the stack frame.
> @@ -1789,6 +1794,8 @@ static int do_jit(struct bpf_verifier_env *env, struct bpf_prog *bpf_prog, int *
> * Arg 6 goes into r9 register, not on stack.
> */
> outgoing_rsp = out_stack_arg_cnt > 1 ? (out_stack_arg_cnt - 1) * 8 : 0;
> + if (bpf_prog->aux->exception_boundary)
> + bpf_prog->aux->stack_arg_adjust = outgoing_rsp;
> emit_sub_rsp(&prog, outgoing_rsp);
>
> if (arena_vm_start)
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 242f9597d9ab..2a1616c769a9 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1735,7 +1735,8 @@ struct bpf_prog_aux {
> int cgroup_atype; /* enum cgroup_bpf_attach_type */
> struct bpf_map *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE];
> char name[BPF_OBJ_NAME_LEN];
> - u64 (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp, u64, u64);
> + u64 (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp, u64 stack_arg_adjust, u64);
no need to change this.
> + u16 stack_arg_adjust;
this one is still needed, but maybe let's call it stack_arg_sp_adjust?
Looking at arch/arm64/net/bpf_jit_comp.c:590
it doesn't use SP, so should it fine.
and arm64 seems to work already?
and the field x86 specific? not sure about other archs.
next prev parent reply other threads:[~2026-05-17 0:59 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-15 22:50 [PATCH bpf-next v3 0/7] bpf: Follow-up fixes for stack argument support Yonghong Song
2026-05-15 22:50 ` [PATCH bpf-next v3 1/7] bpf: Validate outgoing stack args when btf_prepare_func_args fails Yonghong Song
2026-05-15 22:50 ` [PATCH bpf-next v3 2/7] selftests/bpf: Add test for stack arg read without caller write Yonghong Song
2026-05-15 22:50 ` [PATCH bpf-next v3 3/7] selftests/bpf: Log arg_track_join for stack arg slots in liveness analysis Yonghong Song
2026-05-15 22:50 ` [PATCH bpf-next v3 4/7] bpf: Fix arg_track_join log to use sa prefix for stack arg slots Yonghong Song
2026-05-15 22:51 ` [PATCH bpf-next v3 5/7] bpf: Clean up redundant stack arg checks for non-JITed programs Yonghong Song
2026-05-15 22:51 ` [PATCH bpf-next v3 6/7] bpf,x86: Fix exception unwinding with outgoing stack arguments Yonghong Song
2026-05-16 3:51 ` Kumar Kartikeya Dwivedi
2026-05-17 0:54 ` Yonghong Song
2026-05-17 0:59 ` Alexei Starovoitov [this message]
2026-05-17 4:55 ` Yonghong Song
2026-05-15 22:51 ` [PATCH bpf-next v3 7/7] selftests/bpf: Add exception tests with " Yonghong Song
2026-05-16 3:53 ` Kumar Kartikeya Dwivedi
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=DIKJM7FYGJ9K.2H5U2EPKDENME@gmail.com \
--to=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=martin.lau@kernel.org \
--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 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.