* [PATCH bpf 0/2] bpf: Keep fastcall stack slots for helper stack reads
@ 2026-06-24 8:39 Nuoqi Gui
2026-06-24 8:39 ` [PATCH bpf 1/2] bpf: Keep fastcall spills " Nuoqi Gui
2026-06-24 8:39 ` [PATCH bpf 2/2] selftests/bpf: Cover fastcall " Nuoqi Gui
0 siblings, 2 replies; 8+ messages in thread
From: Nuoqi Gui @ 2026-06-24 8:39 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: John Fastabend, Martin KaFai Lau, Shuah Khan, bpf,
linux-kselftest, linux-kernel, Nuoqi Gui
Fastcall spill/fill elision is guarded by a stack contract: stack slots in
the pattern may only be accessed by the pattern itself. Direct stack loads
and stores enforce that contract, but helper and kfunc memory arguments can
read from PTR_TO_STACK through check_stack_range_initialized() without
disabling the post-verification elision.
Make helper/kfunc stack memory checks enforce the fastcall contract after
resolving the range. Add a verifier selftest for a read-only helper access
through bpf_csum_diff().
Fixes: 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls")
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
---
Nuoqi Gui (2):
bpf: Keep fastcall spills for helper stack reads
selftests/bpf: Cover fastcall helper stack reads
kernel/bpf/verifier.c | 4 +++
.../selftests/bpf/progs/verifier_bpf_fastcall.c | 32 ++++++++++++++++++++++
2 files changed, 36 insertions(+)
---
base-commit: 76f62d237538b456354a44e796a541cde03c6e28
change-id: 20260624-f01-12-fastcall-helper-stack-read-6d4dc1ffb513
Best regards,
--
Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH bpf 1/2] bpf: Keep fastcall spills for helper stack reads 2026-06-24 8:39 [PATCH bpf 0/2] bpf: Keep fastcall stack slots for helper stack reads Nuoqi Gui @ 2026-06-24 8:39 ` Nuoqi Gui 2026-06-25 18:32 ` Eduard Zingerman 2026-06-24 8:39 ` [PATCH bpf 2/2] selftests/bpf: Cover fastcall " Nuoqi Gui 1 sibling, 1 reply; 8+ messages in thread From: Nuoqi Gui @ 2026-06-24 8:39 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi Cc: John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel, Nuoqi Gui The fastcall spill/fill rewrite is only sound while the stack slots used by the pattern are not accessed outside the pattern. Direct stack loads and stores already call check_fastcall_stack_contract() to enforce this. Helper and kfunc memory-argument checks can validate PTR_TO_STACK reads through check_stack_range_initialized() without applying the same contract. When such a read overlaps a fastcall spill slot, bpf_remove_fastcall_spills_fills() can still remove the spill/fill pair. It can then shrink the subprogram stack depth even though a helper or kfunc reads that stack address. Apply check_fastcall_stack_contract() from check_stack_range_initialized() after the concrete stack range is known. Zero-sized accesses do not read or write memory, so leave the fastcall optimization unchanged for those. Fixes: 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls") Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> --- kernel/bpf/verifier.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ff9b1f68ceca4..d77332eeab359 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6873,6 +6873,10 @@ static int check_stack_range_initialized( max_off = reg->smax_value + off; } + if (access_size) + check_fastcall_stack_contract(env, state, env->insn_idx, + min_off); + if (meta && meta->raw_mode) { /* Ensure we won't be overwriting dynptrs when simulating byte * by byte access in check_helper_call using meta.access_size. -- 2.34.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf 1/2] bpf: Keep fastcall spills for helper stack reads 2026-06-24 8:39 ` [PATCH bpf 1/2] bpf: Keep fastcall spills " Nuoqi Gui @ 2026-06-25 18:32 ` Eduard Zingerman 2026-06-28 13:46 ` Nuoqi Gui 0 siblings, 1 reply; 8+ messages in thread From: Eduard Zingerman @ 2026-06-25 18:32 UTC (permalink / raw) To: Nuoqi Gui, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi Cc: John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel On Wed, 2026-06-24 at 16:39 +0800, Nuoqi Gui wrote: > The fastcall spill/fill rewrite is only sound while the stack slots used by > the pattern are not accessed outside the pattern. Direct stack loads and > stores already call check_fastcall_stack_contract() to enforce this. > > Helper and kfunc memory-argument checks can validate PTR_TO_STACK reads > through check_stack_range_initialized() without applying the same contract. > When such a read overlaps a fastcall spill slot, > bpf_remove_fastcall_spills_fills() can still remove the spill/fill pair. > It can then shrink the subprogram stack depth even though a helper or kfunc > reads that stack address. > > Apply check_fastcall_stack_contract() from check_stack_range_initialized() > after the concrete stack range is known. Zero-sized accesses do not read or > write memory, so leave the fastcall optimization unchanged for those. > > Fixes: 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls") > Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> > --- > kernel/bpf/verifier.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index ff9b1f68ceca4..d77332eeab359 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -6873,6 +6873,10 @@ static int check_stack_range_initialized( > max_off = reg->smax_value + off; > } > > + if (access_size) > + check_fastcall_stack_contract(env, state, env->insn_idx, > + min_off); > + Thank you for finding this bug. I think that placing the check_fastcall_stack_contract() call here makes the same call unnecessary in the check_stack_read_var_off(), as it calls to check_stack_range_initialized() with zero_size_allowed==false. > if (meta && meta->raw_mode) { > /* Ensure we won't be overwriting dynptrs when simulating byte > * by byte access in check_helper_call using meta.access_size. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Re: [PATCH bpf 1/2] bpf: Keep fastcall spills for helper stack reads 2026-06-25 18:32 ` Eduard Zingerman @ 2026-06-28 13:46 ` Nuoqi Gui 0 siblings, 0 replies; 8+ messages in thread From: Nuoqi Gui @ 2026-06-28 13:46 UTC (permalink / raw) To: Eduard Zingerman Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi, John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel > -----Original Messages----- > From: "Eduard Zingerman" <eddyz87@gmail.com> > Send time:Friday, 26/06/2026 02:32:32 > To: "Nuoqi Gui" <gnq25@mails.tsinghua.edu.cn>, "Alexei Starovoitov" <ast@kernel.org>, "Daniel Borkmann" <daniel@iogearbox.net>, "Andrii Nakryiko" <andrii@kernel.org>, "Kumar Kartikeya Dwivedi" <memxor@gmail.com> > Cc: "John Fastabend" <john.fastabend@gmail.com>, "Martin KaFai Lau" <martin.lau@linux.dev>, "Shuah Khan" <shuah@kernel.org>, bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org > Subject: Re: [PATCH bpf 1/2] bpf: Keep fastcall spills for helper stack reads > > On Wed, 2026-06-24 at 16:39 +0800, Nuoqi Gui wrote: > > The fastcall spill/fill rewrite is only sound while the stack slots used by > > the pattern are not accessed outside the pattern. Direct stack loads and > > stores already call check_fastcall_stack_contract() to enforce this. > > > > Helper and kfunc memory-argument checks can validate PTR_TO_STACK reads > > through check_stack_range_initialized() without applying the same contract. > > When such a read overlaps a fastcall spill slot, > > bpf_remove_fastcall_spills_fills() can still remove the spill/fill pair. > > It can then shrink the subprogram stack depth even though a helper or kfunc > > reads that stack address. > > > > Apply check_fastcall_stack_contract() from check_stack_range_initialized() > > after the concrete stack range is known. Zero-sized accesses do not read or > > write memory, so leave the fastcall optimization unchanged for those. > > > > Fixes: 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls") > > Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> > > --- > > kernel/bpf/verifier.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > > index ff9b1f68ceca4..d77332eeab359 100644 > > --- a/kernel/bpf/verifier.c > > +++ b/kernel/bpf/verifier.c > > @@ -6873,6 +6873,10 @@ static int check_stack_range_initialized( > > max_off = reg->smax_value + off; > > } > > > > + if (access_size) > > + check_fastcall_stack_contract(env, state, env->insn_idx, > > + min_off); > > + > > Thank you for finding this bug. > I think that placing the check_fastcall_stack_contract() call here > makes the same call unnecessary in the check_stack_read_var_off(), > as it calls to check_stack_range_initialized() with zero_size_allowed==false. > > > if (meta && meta->raw_mode) { > > /* Ensure we won't be overwriting dynptrs when simulating byte > > * by byte access in check_helper_call using meta.access_size. Thanks. I'll remove the redundant call from check_stack_read_var_off() in v2. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf 2/2] selftests/bpf: Cover fastcall helper stack reads 2026-06-24 8:39 [PATCH bpf 0/2] bpf: Keep fastcall stack slots for helper stack reads Nuoqi Gui 2026-06-24 8:39 ` [PATCH bpf 1/2] bpf: Keep fastcall spills " Nuoqi Gui @ 2026-06-24 8:39 ` Nuoqi Gui 2026-06-24 10:01 ` bot+bpf-ci 2026-06-25 18:35 ` Eduard Zingerman 1 sibling, 2 replies; 8+ messages in thread From: Nuoqi Gui @ 2026-06-24 8:39 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi Cc: John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel, Nuoqi Gui Add verifier_bpf_fastcall test where a spill/fill pair initializes a stack slot. bpf_csum_diff() later reads it through ARG_PTR_TO_MEM | MEM_RDONLY. The translated program must keep the spill and fill materialized. Otherwise the helper reads stack bytes that no longer match the verifier model. Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> --- .../selftests/bpf/progs/verifier_bpf_fastcall.c | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c index fb4fa465d67c6..aab92e69673d2 100644 --- a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c +++ b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c @@ -500,6 +500,38 @@ __naked void bad_helper_write(void) : __clobber_all); } +SEC("tc") +__arch_x86_64 +__xlated("1: *(u64 *)(r10 -8) = r1") +__xlated("...") +__xlated("3: r0 = &(void __percpu *)(r0)") +__xlated("...") +__xlated("5: r1 = *(u64 *)(r10 -8)") +__success +__naked void bad_helper_read(void) +{ + asm volatile ( + "r1 = 1;" + /* bpf_fastcall pattern with stack offset -8 */ + "*(u64 *)(r10 - 8) = r1;" + "call %[bpf_get_smp_processor_id];" + "r1 = *(u64 *)(r10 - 8);" + /* bpf_csum_diff() reads fp[-8], so keep the spill materialized */ + "r1 = r10;" + "r1 += -8;" + "r2 = 8;" + "r3 = 0;" + "r4 = 0;" + "r5 = 0;" + "call %[bpf_csum_diff];" + "r0 = 0;" + "exit;" + : + : __imm(bpf_get_smp_processor_id), + __imm(bpf_csum_diff) + : __clobber_all); +} + SEC("raw_tp") __arch_x86_64 /* main, not patched */ -- 2.34.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf 2/2] selftests/bpf: Cover fastcall helper stack reads 2026-06-24 8:39 ` [PATCH bpf 2/2] selftests/bpf: Cover fastcall " Nuoqi Gui @ 2026-06-24 10:01 ` bot+bpf-ci 2026-06-25 18:35 ` Eduard Zingerman 1 sibling, 0 replies; 8+ messages in thread From: bot+bpf-ci @ 2026-06-24 10:01 UTC (permalink / raw) To: gnq25, ast, daniel, andrii, eddyz87, memxor Cc: john.fastabend, martin.lau, shuah, bpf, linux-kselftest, linux-kernel, gnq25, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 1033 bytes --] > selftests/bpf: Cover fastcall helper stack reads > > Add verifier_bpf_fastcall test where a spill/fill pair initializes a stack > slot. bpf_csum_diff() later reads it through ARG_PTR_TO_MEM | MEM_RDONLY. > > The translated program must keep the spill and fill materialized. Otherwise > the helper reads stack bytes that no longer match the verifier model. > > Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> This test covers a fastcall spill/fill removal bug that the bpf_fastcall spill/fill removal mechanism introduced in commit 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls"). Should this commit carry a Fixes: tag pointing at that commit? Fixes: 5b5f51bff1b66 ("bpf: no_caller_saved_registers attribute for helper calls") --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/28089002726 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf 2/2] selftests/bpf: Cover fastcall helper stack reads 2026-06-24 8:39 ` [PATCH bpf 2/2] selftests/bpf: Cover fastcall " Nuoqi Gui 2026-06-24 10:01 ` bot+bpf-ci @ 2026-06-25 18:35 ` Eduard Zingerman 2026-06-28 13:47 ` Nuoqi Gui 1 sibling, 1 reply; 8+ messages in thread From: Eduard Zingerman @ 2026-06-25 18:35 UTC (permalink / raw) To: Nuoqi Gui, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi Cc: John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel On Wed, 2026-06-24 at 16:39 +0800, Nuoqi Gui wrote: > Add verifier_bpf_fastcall test where a spill/fill pair initializes a stack > slot. bpf_csum_diff() later reads it through ARG_PTR_TO_MEM | MEM_RDONLY. > > The translated program must keep the spill and fill materialized. Otherwise > the helper reads stack bytes that no longer match the verifier model. > > Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> > --- Could you please add a kfunc based test case as well? [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Re: [PATCH bpf 2/2] selftests/bpf: Cover fastcall helper stack reads 2026-06-25 18:35 ` Eduard Zingerman @ 2026-06-28 13:47 ` Nuoqi Gui 0 siblings, 0 replies; 8+ messages in thread From: Nuoqi Gui @ 2026-06-28 13:47 UTC (permalink / raw) To: Eduard Zingerman Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi, John Fastabend, Martin KaFai Lau, Shuah Khan, bpf, linux-kselftest, linux-kernel > -----Original Messages----- > From: "Eduard Zingerman" <eddyz87@gmail.com> > Send time:Friday, 26/06/2026 02:35:39 > To: "Nuoqi Gui" <gnq25@mails.tsinghua.edu.cn>, "Alexei Starovoitov" <ast@kernel.org>, "Daniel Borkmann" <daniel@iogearbox.net>, "Andrii Nakryiko" <andrii@kernel.org>, "Kumar Kartikeya Dwivedi" <memxor@gmail.com> > Cc: "John Fastabend" <john.fastabend@gmail.com>, "Martin KaFai Lau" <martin.lau@linux.dev>, "Shuah Khan" <shuah@kernel.org>, bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org > Subject: Re: [PATCH bpf 2/2] selftests/bpf: Cover fastcall helper stack reads > > On Wed, 2026-06-24 at 16:39 +0800, Nuoqi Gui wrote: > > Add verifier_bpf_fastcall test where a spill/fill pair initializes a stack > > slot. bpf_csum_diff() later reads it through ARG_PTR_TO_MEM | MEM_RDONLY. > > > > The translated program must keep the spill and fill materialized. Otherwise > > the helper reads stack bytes that no longer match the verifier model. > > > > Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> > > --- > > Could you please add a kfunc based test case as well? > > [...] Sure, I'll add a kfunc-based verifier test as well. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-28 13:47 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-06-24 8:39 [PATCH bpf 0/2] bpf: Keep fastcall stack slots for helper stack reads Nuoqi Gui 2026-06-24 8:39 ` [PATCH bpf 1/2] bpf: Keep fastcall spills " Nuoqi Gui 2026-06-25 18:32 ` Eduard Zingerman 2026-06-28 13:46 ` Nuoqi Gui 2026-06-24 8:39 ` [PATCH bpf 2/2] selftests/bpf: Cover fastcall " Nuoqi Gui 2026-06-24 10:01 ` bot+bpf-ci 2026-06-25 18:35 ` Eduard Zingerman 2026-06-28 13:47 ` Nuoqi Gui
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome