All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yonghong Song" <yonghong.song@linux.dev>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 3/5] bpf, x86: Place trampoline arguments by the x86-64 calling convention
Date: Fri, 09 Oct 2026 07:08:23 +0000	[thread overview]
Message-ID: <sashiko-outbox-164976@kernel.org> (raw)
In-Reply-To: <20261009064221.1240081-1-yonghong.song@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] bpf, x86: stack arguments offset mismatch and misalignment with BPF_TRAMP_F_TAIL_CALL_CTX
- [Medium] bpf: info leak of uninitialized kernel stack memory due to missing garbage cleanup
--

commit ffb54c9ff7ace6fffcfc471ab2c2927e34131e44
Author: Yonghong Song <yonghong.song@linux.dev>

bpf, x86: Place trampoline arguments by the x86-64 calling convention

This commit updates the BPF trampoline to place on-stack arguments
according to the x86-64 calling convention. It introduces a backfill
mechanism using bpf_jit_place_args() to handle arguments like __int128
that may span stack slots and create alignment holes.

> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 083fcd6cf15b7..0fc7715e569b5 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
[ ... ]
> @@ -3472,8 +3479,35 @@ static void save_args(const struct btf_func_model *m, u8 **prog,
>  		 *
>  		 * the arg1-5,arg7 will be passed by regs, and arg6 will
>  		 * by stack.
> +		 *
> +		 * An argument aligned to 16 bytes, an __int128 or a struct
> +		 * holding one, also starts at an even stack slot, which can
> +		 * leave a hole before it. bpf_jit_place_args() worked out
> +		 * where each eightbyte is.
>  		 */
> -		if (nr_regs + arg_regs > 6) {
> +		for (j = 0; j < arg_regs; j++, slot++, bargs_off -= 8) {
> +			u8 pos = pos_of_slot[slot];
> +			u32 src;
> +
> +			if (!x86_arg_on_stack(pos)) {
[ ... ]
> +			/* copy function arguments from origin stack frame
> +			 * into current stack frame.
[ ... ]
> +			 *
> +			 * The area for the origin call mirrors the incoming
> +			 * one, hole and all; only the bpf program takes the
> +			 * arguments packed.
>  			 */
> -			for (j = 0; j < arg_regs; j++) {
> -				emit_ldx(prog, BPF_DW, BPF_REG_0, BPF_REG_FP,
> -					 nr_stack_slots * 8 + stack_args_off);
> -				if (arena_arg)
> -					emit_arena_arg_conv(prog, BPF_REG_0, nullable,
> -							    (u32)arena_base);
> -				emit_stx(prog, BPF_DW, BPF_REG_FP, BPF_REG_0,
> -					 -stack_size);
> -
> -				if (!nr_stack_slots)
> -					first_off = stack_size;
> -				stack_size -= 8;
> -				nr_stack_slots++;
> -			}
> +			off = x86_arg_stack_off(pos);
> +			doff = for_call_origin ? stack_size - off : bargs_off;
> +			emit_ldx(prog, BPF_DW, BPF_REG_0, BPF_REG_FP,
> +				 stack_args_off + off);
> +			if (arena_arg)
> +				emit_arena_arg_conv(prog, BPF_REG_0, nullable,
> +						    (u32)arena_base);
> +			emit_stx(prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -doff);
> +
> +			if (!nr_stack_slots)
> +				first_off = doff;
> +			nr_stack_slots++;
>  		}
>  	}
>  
>  	clean_stack_garbage(m, prog, nr_stack_slots, first_off);
>  }

[Severity: Medium]
Does this code leak uninitialized kernel stack memory?

The x86-64 ABI allocates 8-byte stack slots for arguments, but compilers
frequently use 32-bit instructions to place 32-bit arguments, leaving the upper
4 bytes of the slot uninitialized.

Since clean_stack_garbage() explicitly returns early when nr_stack_slots != 1,
copying the full 64 bits with emit_ldx(..., BPF_DW, ...) captures this
uninitialized kernel memory into the BPF context. Can this leak kernel stack
memory to privileged BPF users if there are multiple stack arguments?

[ ... ]
> @@ -4011,8 +4014,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
>  	}
>  
>  	if (flags & BPF_TRAMP_F_CALL_ORIG) {
> -		restore_regs(m, &prog, regs_off);
> -		save_args(m, &prog, arg_stack_off, true, flags, 0);
> +		restore_regs(&prog, pos_of_slot, nr_regs, regs_off);
> +		save_args(m, &prog, pos_of_slot, arg_stack_off, true, flags, 0);
>  
>  		if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) {
>  			/* Before calling the original function, load the

[Severity: High]
Are stack arguments misaligned here if BPF_TRAMP_F_TAIL_CALL_CTX is active?

When __arch_prepare_bpf_trampoline() executes, it checks for
BPF_TRAMP_F_TAIL_CALL_CTX and emits a push rax instruction (pushing 8 bytes)
after sub rsp, stack_size, which permanently shifts RSP down by 8 bytes.

However, the updated save_args() calculates the stack argument offsets based on
the original stack_size (doff = stack_size - off) without accounting for this
extra 8-byte shift.

Because the push rax is unpopped before call orig_call, the original function
will read its first stack argument from [RSP + 8]. Due to the 8-byte shift,
this points to the tail call counter pointer instead of the actual first stack
argument, corrupting all on-stack arguments.

Additionally, doesn't this 8-byte shift break the required 16-byte stack
alignment on function entry for x86-64?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261009064206.1238047-1-yonghong.song@linux.dev?part=3

  reply	other threads:[~2026-10-09  7:08 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-09  6:42 [PATCH bpf-next 0/5] bpf: Follow up by-value struct and __int128 argument support Yonghong Song
2026-10-09  6:42 ` [PATCH bpf-next 1/5] selftests/bpf: Test by-value __int128 kfunc arguments at an odd slot Yonghong Song
2026-10-09  7:48   ` bot+bpf-ci
2026-10-09 17:04     ` Yonghong Song
2026-10-09  6:42 ` [PATCH bpf-next 2/5] bpf: Keep the BPF calling convention for a trampoline on a BPF function Yonghong Song
2026-10-09  7:26   ` bot+bpf-ci
2026-10-09 17:20     ` Yonghong Song
2026-10-10 15:00   ` Alexei Starovoitov
2026-10-12  6:03     ` Yonghong Song
2026-10-09  6:42 ` [PATCH bpf-next 3/5] bpf, x86: Place trampoline arguments by the x86-64 calling convention Yonghong Song
2026-10-09  7:08   ` sashiko-bot [this message]
2026-10-09 17:38     ` Yonghong Song
2026-10-09  6:42 ` [PATCH bpf-next 4/5] selftests/bpf: Test trampoline args around a 16-byte aligned stack arg Yonghong Song
2026-10-09  6:51   ` sashiko-bot
2026-10-09 18:12     ` Yonghong Song
2026-10-09  6:42 ` [PATCH bpf-next 5/5] selftests/bpf: Test trampoline args of a BPF function at an odd slot Yonghong Song
2026-10-09  7:48   ` bot+bpf-ci
2026-10-09 18:17     ` 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=sashiko-outbox-164976@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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.