* [PATCH bpf v1 0/2] Fix bpf_loop syzbot report
@ 2026-09-05 1:47 Kumar Kartikeya Dwivedi
2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-09-05 1:47 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Needs Eduard's ack. Fix for the report in
https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com.
Kumar Kartikeya Dwivedi (2):
bpf: Reject non-scalar bpf_loop iteration counts
selftests/bpf: Test pointer bpf_loop iteration count rejection
include/linux/bpf.h | 1 +
kernel/bpf/bpf_iter.c | 2 +-
kernel/bpf/verifier.c | 1 +
.../bpf/progs/verifier_iterating_callbacks.c | 17 +++++++++++++++++
4 files changed, 20 insertions(+), 1 deletion(-)
base-commit: b75a000f2ac15f4778ddd6d9298d60b24ad776fa
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts 2026-09-05 1:47 [PATCH bpf v1 0/2] Fix bpf_loop syzbot report Kumar Kartikeya Dwivedi @ 2026-09-05 1:47 ` Kumar Kartikeya Dwivedi 2026-09-05 1:57 ` sashiko-bot 2026-09-06 3:46 ` Eduard Zingerman 2026-09-05 1:47 ` [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection Kumar Kartikeya Dwivedi 2026-09-06 4:10 ` [PATCH bpf v1 0/2] Fix bpf_loop syzbot report patchwork-bot+netdevbpf 2 siblings, 2 replies; 8+ messages in thread From: Kumar Kartikeya Dwivedi @ 2026-09-05 1:47 UTC (permalink / raw) To: bpf Cc: syzbot+7b47f87674e9a1569110, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team bpf_loop() declares its nr_loops argument as ARG_ANYTHING. Privileged programs may pass pointer values to such arguments, so check_func_arg() lets a pointer-valued R1 reach the helper-specific checks. Since commit bb124da69c47 ("bpf: keep track of max number of bpf_loop callback iterations"), the verifier marks R1 precise and reads its upper bound to limit callback simulation. Precision backtracking only accepts scalar registers, so passing a pointer instead triggers the "backtracking misuse" verifier warning. Kernels with panic_on_warn enabled subsequently panic. Introduce ARG_SCALAR for helper arguments that only accept scalar values and use it for bpf_loop() nr_loops. Generic helper argument validation then rejects pointers before loop inlining and precision processing. Fixes: bb124da69c47 ("bpf: keep track of max number of bpf_loop callback iterations") Reported-by: syzbot+7b47f87674e9a1569110@syzkaller.appspotmail.com Closes: https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com/ Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> --- include/linux/bpf.h | 1 + kernel/bpf/bpf_iter.c | 2 +- kernel/bpf/verifier.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index b7dbf3d9b5c0..e57af902560c 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -894,6 +894,7 @@ enum bpf_arg_type { ARG_PTR_TO_CTX, /* pointer to context */ ARG_ANYTHING, /* any (initialized) argument is ok */ + ARG_SCALAR, /* scalar argument */ ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */ ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */ ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */ diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c index 14a5fdfa0421..b40eb404adab 100644 --- a/kernel/bpf/bpf_iter.c +++ b/kernel/bpf/bpf_iter.c @@ -754,7 +754,7 @@ const struct bpf_func_proto bpf_loop_proto = { .func = bpf_loop, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_ANYTHING, + .arg1_type = ARG_SCALAR, .arg2_type = ARG_PTR_TO_FUNC, .arg3_type = ARG_PTR_TO_STACK_OR_NULL, .arg4_type = ARG_ANYTHING, diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1c3039f3fc32..4638a2f85d0f 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8211,6 +8211,7 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = { [ARG_MEM_SIZE] = &scalar_types, [ARG_MEM_SIZE_OR_ZERO] = &scalar_types, [ARG_CONST_ALLOC_SIZE_OR_ZERO] = &scalar_types, + [ARG_SCALAR] = &scalar_types, [ARG_CONST_MAP_PTR] = &const_map_ptr_types, [ARG_PTR_TO_CTX] = &context_types, [ARG_PTR_TO_SOCK_COMMON] = &sock_types, -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts 2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi @ 2026-09-05 1:57 ` sashiko-bot 2026-09-05 5:56 ` Kumar Kartikeya Dwivedi 2026-09-06 3:46 ` Eduard Zingerman 1 sibling, 1 reply; 8+ messages in thread From: sashiko-bot @ 2026-09-05 1:57 UTC (permalink / raw) To: Kumar Kartikeya Dwivedi; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [High] Missing negative bounds checks for enum array indices in memcg BPF kfuncs (bpf_mem_cgroup_memory_events and bpf_mem_cgroup_vm_events). -- commit 3f8d69cede626ae022617ccb30f54b8f41f90edd Author: Kumar Kartikeya Dwivedi <memxor@gmail.com> bpf: Reject non-scalar bpf_loop iteration counts This commit fixes a verifier warning and subsequent panic triggered when pointer values are passed to the bpf_loop() nr_loops argument. It introduces ARG_SCALAR to ensure generic helper argument validation rejects pointers before loop inlining and precision processing. Link: https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com/ > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > index 3a7eb2185c354..591dfab3e706c 100644 > --- a/include/linux/bpf.h > +++ b/include/linux/bpf.h > @@ -894,6 +894,7 @@ enum bpf_arg_type { > > ARG_PTR_TO_CTX, /* pointer to context */ > ARG_ANYTHING, /* any (initialized) argument is ok */ > + ARG_SCALAR, /* scalar argument */ [Severity: High] This isn't a bug introduced by this patch, but while reviewing the addition of ARG_SCALAR and how the verifier handles scalar arguments, a pre-existing missing bounds check was noticed in the memory cgroup kfuncs. Could negative enum values passed by untrusted BPF programs cause an out-of-bounds read in the memcg BPF kfuncs? Looking at mm/bpf_memcontrol.c:bpf_mem_cgroup_memory_events(): if (unlikely(event >= MEMCG_NR_MEMORY_EVENTS)) return (unsigned long)-1; return atomic_long_read(&memcg->memory_events[event]); And similarly in mm/bpf_memcontrol.c:bpf_mem_cgroup_vm_events(), which exposes validation logic from mm/memcontrol.c:memcg_vm_event_item_valid(): if (idx >= NR_VM_EVENT_ITEMS) return false; return !BAD_STAT_IDX(memcg_events_index(idx)); Because the BPF verifier enforces scalar types but does not validate enum ranges, a BPF program can pass a negative integer as the event parameter. The bounds checks use signed comparisons without a lower bound (< 0) check, so negative values will bypass the validation (e.g., -1 >= 4 evaluates to false). Can this lead to an out-of-bounds array access on kernel memory when the negative value is used as an index into memcg->memory_events? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260905014735.1452988-1-memxor@gmail.com?part=1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts 2026-09-05 1:57 ` sashiko-bot @ 2026-09-05 5:56 ` Kumar Kartikeya Dwivedi 0 siblings, 0 replies; 8+ messages in thread From: Kumar Kartikeya Dwivedi @ 2026-09-05 5:56 UTC (permalink / raw) To: sashiko-reviews; +Cc: bpf On Sat Sep 5, 2026 at 3:57 AM CEST, sashiko-bot wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > > Pre-existing issues: > - [High] Missing negative bounds checks for enum array indices in memcg BPF kfuncs (bpf_mem_cgroup_memory_events and bpf_mem_cgroup_vm_events). > -- > > commit 3f8d69cede626ae022617ccb30f54b8f41f90edd > Author: Kumar Kartikeya Dwivedi <memxor@gmail.com> > > bpf: Reject non-scalar bpf_loop iteration counts > > This commit fixes a verifier warning and subsequent panic triggered when > pointer values are passed to the bpf_loop() nr_loops argument. It > introduces ARG_SCALAR to ensure generic helper argument validation > rejects pointers before loop inlining and precision processing. > > Link: https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com/ > >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h >> index 3a7eb2185c354..591dfab3e706c 100644 >> --- a/include/linux/bpf.h >> +++ b/include/linux/bpf.h >> @@ -894,6 +894,7 @@ enum bpf_arg_type { >> >> ARG_PTR_TO_CTX, /* pointer to context */ >> ARG_ANYTHING, /* any (initialized) argument is ok */ >> + ARG_SCALAR, /* scalar argument */ > > [Severity: High] > This isn't a bug introduced by this patch, but while reviewing the addition > of ARG_SCALAR and how the verifier handles scalar arguments, a pre-existing > missing bounds check was noticed in the memory cgroup kfuncs. > > Could negative enum values passed by untrusted BPF programs cause an > out-of-bounds read in the memcg BPF kfuncs? > > Looking at mm/bpf_memcontrol.c:bpf_mem_cgroup_memory_events(): > > if (unlikely(event >= MEMCG_NR_MEMORY_EVENTS)) > return (unsigned long)-1; > > return atomic_long_read(&memcg->memory_events[event]); > > And similarly in mm/bpf_memcontrol.c:bpf_mem_cgroup_vm_events(), which > exposes validation logic from mm/memcontrol.c:memcg_vm_event_item_valid(): > > if (idx >= NR_VM_EVENT_ITEMS) > return false; > > return !BAD_STAT_IDX(memcg_events_index(idx)); > > Because the BPF verifier enforces scalar types but does not validate enum > ranges, a BPF program can pass a negative integer as the event parameter. > The bounds checks use signed comparisons without a lower bound (< 0) check, > so negative values will bypass the validation (e.g., -1 >= 4 evaluates to > false). > My understanding is that since enum values are non-neggative, the enum type is treated unsigned by default. But I think it might make sense to just cast explicitly since Sashiko keeps repeating this concern and it is probably clearer for a reader (I forgot enum values would be unsigned when all enum constants are non-negative myself). > Can this lead to an out-of-bounds array access on kernel memory when the > negative value is used as an index into memcg->memory_events? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts 2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi 2026-09-05 1:57 ` sashiko-bot @ 2026-09-06 3:46 ` Eduard Zingerman 1 sibling, 0 replies; 8+ messages in thread From: Eduard Zingerman @ 2026-09-06 3:46 UTC (permalink / raw) To: Kumar Kartikeya Dwivedi, bpf Cc: syzbot+7b47f87674e9a1569110, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Emil Tsalapatis, kkd, kernel-team On Sat, 2026-09-05 at 03:47 +0200, Kumar Kartikeya Dwivedi wrote: > bpf_loop() declares its nr_loops argument as ARG_ANYTHING. Privileged > programs may pass pointer values to such arguments, so check_func_arg() > lets a pointer-valued R1 reach the helper-specific checks. > > Since commit bb124da69c47 ("bpf: keep track of max number of bpf_loop > callback iterations"), the verifier marks R1 precise and reads its upper > bound to limit callback simulation. Precision backtracking only accepts > scalar registers, so passing a pointer instead triggers the "backtracking > misuse" verifier warning. Kernels with panic_on_warn enabled subsequently > panic. > > Introduce ARG_SCALAR for helper arguments that only accept scalar values > and use it for bpf_loop() nr_loops. Generic helper argument validation then > rejects pointers before loop inlining and precision processing. > > Fixes: bb124da69c47 ("bpf: keep track of max number of bpf_loop callback iterations") > Reported-by: syzbot+7b47f87674e9a1569110@syzkaller.appspotmail.com > Closes: https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com/ > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> > --- Acked-by: Eduard Zingerman <eddyz87@gmail.com> Looks like there are no other instances of this bug. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection 2026-09-05 1:47 [PATCH bpf v1 0/2] Fix bpf_loop syzbot report Kumar Kartikeya Dwivedi 2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi @ 2026-09-05 1:47 ` Kumar Kartikeya Dwivedi 2026-09-06 3:45 ` Eduard Zingerman 2026-09-06 4:10 ` [PATCH bpf v1 0/2] Fix bpf_loop syzbot report patchwork-bot+netdevbpf 2 siblings, 1 reply; 8+ messages in thread From: Kumar Kartikeya Dwivedi @ 2026-09-05 1:47 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team Add a verifier test that leaves the raw tracepoint context pointer in R1 when calling bpf_loop(). This is the smallest trigger for the incorrect precision backtracking: it reuses an existing callback and needs no maps or userspace setup. Expect an ordinary scalar-type rejection. Without the verifier fix, the test instead reaches precision backtracking and reports an internal "backtracking misuse" error. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> --- .../bpf/progs/verifier_iterating_callbacks.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c b/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c index 75dd922e4e9f..1fbcc5228306 100644 --- a/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c +++ b/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c @@ -168,6 +168,23 @@ static int iter_limit_cb(__u32 idx, struct num_context *ctx) return 0; } +SEC("?raw_tp") +__failure __msg("R1 type=ctx expected=scalar") +__naked void bpf_loop_reject_pointer(void) +{ + asm volatile ( + "r2 = %[iter_limit_cb];" + "r3 = 0;" + "r4 = 0;" + "call %[bpf_loop];" + "exit;" + : + : __imm_ptr(iter_limit_cb), + __imm(bpf_loop) + : __clobber_common + ); +} + SEC("?raw_tp") __success int bpf_loop_iter_limit_ok(void *unused) -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection 2026-09-05 1:47 ` [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection Kumar Kartikeya Dwivedi @ 2026-09-06 3:45 ` Eduard Zingerman 0 siblings, 0 replies; 8+ messages in thread From: Eduard Zingerman @ 2026-09-06 3:45 UTC (permalink / raw) To: Kumar Kartikeya Dwivedi, bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Emil Tsalapatis, kkd, kernel-team On Sat, 2026-09-05 at 03:47 +0200, Kumar Kartikeya Dwivedi wrote: > Add a verifier test that leaves the raw tracepoint context pointer in R1 > when calling bpf_loop(). This is the smallest trigger for the incorrect > precision backtracking: it reuses an existing callback and needs no maps or > userspace setup. > > Expect an ordinary scalar-type rejection. Without the verifier fix, the > test instead reaches precision backtracking and reports an internal > "backtracking misuse" error. > > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> > --- Acked-by: Eduard Zingerman <eddyz87@gmail.com> ... > @@ -168,6 +168,23 @@ static int iter_limit_cb(__u32 idx, struct num_context *ctx) > return 0; > } > > +SEC("?raw_tp") > +__failure __msg("R1 type=ctx expected=scalar") I switched to matching new and shiny error messages (: ... ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf v1 0/2] Fix bpf_loop syzbot report 2026-09-05 1:47 [PATCH bpf v1 0/2] Fix bpf_loop syzbot report Kumar Kartikeya Dwivedi 2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi 2026-09-05 1:47 ` [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection Kumar Kartikeya Dwivedi @ 2026-09-06 4:10 ` patchwork-bot+netdevbpf 2 siblings, 0 replies; 8+ messages in thread From: patchwork-bot+netdevbpf @ 2026-09-06 4:10 UTC (permalink / raw) To: Kumar Kartikeya Dwivedi Cc: bpf, ast, andrii, daniel, eddyz87, emil, kkd, kernel-team Hello: This series was applied to bpf/bpf.git (master) by Eduard Zingerman <eddyz87@gmail.com>: On Sat, 5 Sep 2026 03:47:32 +0200 you wrote: > Needs Eduard's ack. Fix for the report in > https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com. > > Kumar Kartikeya Dwivedi (2): > bpf: Reject non-scalar bpf_loop iteration counts > selftests/bpf: Test pointer bpf_loop iteration count rejection > > [...] Here is the summary with links: - [bpf,v1,1/2] bpf: Reject non-scalar bpf_loop iteration counts https://git.kernel.org/bpf/bpf/c/c3fd8e5fd100 - [bpf,v1,2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection https://git.kernel.org/bpf/bpf/c/bde8901ea142 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-06 4:11 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-05 1:47 [PATCH bpf v1 0/2] Fix bpf_loop syzbot report Kumar Kartikeya Dwivedi 2026-09-05 1:47 ` [PATCH bpf v1 1/2] bpf: Reject non-scalar bpf_loop iteration counts Kumar Kartikeya Dwivedi 2026-09-05 1:57 ` sashiko-bot 2026-09-05 5:56 ` Kumar Kartikeya Dwivedi 2026-09-06 3:46 ` Eduard Zingerman 2026-09-05 1:47 ` [PATCH bpf v1 2/2] selftests/bpf: Test pointer bpf_loop iteration count rejection Kumar Kartikeya Dwivedi 2026-09-06 3:45 ` Eduard Zingerman 2026-09-06 4:10 ` [PATCH bpf v1 0/2] Fix bpf_loop syzbot report patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox