[PATCH bpf-next] bpf: Fix bpf_loop() depth check to use 32-bit max for nr_loops

From: Ömer Mete Kaya

Date: Sun Sep 27 2026 - 19:08:50 EST


bpf_loop() takes a u32 nr_loops argument. At runtime, nr_loops is
passed as a u32 via the BPF_CALL_4 signature:

BPF_CALL_4(bpf_loop, u32, nr_loops, ...)

However, the verifier compares callback_depth (u32) against
reg_umax(), which returns the 64-bit upper bound of R1. If the upper
32 bits of R1 are set, reg_umax() can be U64_MAX, causing the depth
check to remain ineffective and triggering excessive
push_callback_call() invocations until the complexity limit is hit.

Use reg_u32_max() instead, matching the 32-bit range actually used by
bpf_loop() and avoiding unnecessary state exploration when R1 has a
large 64-bit range.

Signed-off-by: Ömer Mete Kaya <omermetekaya0@xxxxxxxxx>
---
kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0eeb498db9d3..8d8923ad5094 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12184,7 +12184,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
err = mark_chain_precision(env, BPF_REG_1);
if (err)
return err;
- if (cur_func(env)->callback_depth < reg_umax(&regs[BPF_REG_1])) {
+ if (cur_func(env)->callback_depth < reg_u32_max(&regs[BPF_REG_1])) {
err = push_callback_call(env, insn, insn_idx, meta.subprogno,
set_loop_callback_state);
} else {
--
2.55.0