diff options
| author | 2026-09-21 15:00:59 -0700 | |
|---|---|---|
| committer | 2026-09-21 15:01:00 -0700 | |
| commit | 0b6e06f9501aacaa3aa555de510eef81371ded95 (patch) | |
| tree | 8ee174c370ab79043a293db4a325e7d7416c15c4 | |
| parent | bpf: Check params size before reading reserved fields (diff) | |
| parent | selftests/bpf: Reject iterator destruction through fp+0 (diff) | |
Merge branch 'bpf-reject-non-negative-stack-object-offsets'
Xu Yunxiang says:
====================
bpf: Reject non-negative stack object offsets
Reject non-negative offsets before converting a stack object address to a
stack slot index. Add a regression test for iterator destruction through
fp+0.
Changes in v2:
- Split the kernel change and selftest as requested by Andrii.
- Rebase onto bpf/master at a11212910cf09b2fe8db9afa41ef60c4f81879c5.
- Keep the original code and test changes unchanged and retain Sun Jian's
Reviewed-by on both parts.
v1: https://lore.kernel.org/bpf/20260911084314.3481637-1-xyx2021@mail.ustc.edu.cn/
Split request: https://lore.kernel.org/bpf/CAEf4BzbYzt-Riekpc-A=MfQft9ZELwSDSE8kkQO1ZOyR3O_FAg@mail.gmail.com/
Validation on this exact candidate with a matching bpf_testmod:
- W=1 verifier, full kernel/modules, changed BPF objects and test_progs
builds passed.
- iters: 1/97 passed; 0 skipped.
- dynptr: 2/132 passed; 0 skipped.
- irq: 1/33 passed; 0 skipped.
- res_spin_lock: 3/14 passed; 1 skipped.
- file_reader: 1/8 passed; 0 skipped.
- kmem_cache_iter: 1/3 passed; 0 skipped.
- dmabuf_iter: 1/4 passed; 0 skipped.
No selected test failed. The VM ran with panic_on_warn and panic_on_oops;
no kernel WARN, Oops or panic was found.
res_spin_lock_stress skips because the VM has no hardware PMU.
Annotated verifier tests check load outcomes and diagnostics. The full
unfiltered suite, sanitizer configurations and architecture matrix were
not run.
Please queue this fix for stable after it reaches the BPF tree.
====================
Link: https://patch.msgid.link/20260920210423.345636-1-xyx2021@mail.ustc.edu.cn
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
| -rw-r--r-- | kernel/bpf/verifier.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/progs/iters_state_safety.c | 22 |
2 files changed, 23 insertions, 1 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 02be326f235c..dd8bb179d39e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -567,7 +567,7 @@ static int stack_slot_obj_get_spi(struct bpf_verifier_env *env, struct bpf_reg_s } off = reg->var_off.value; - if (off % BPF_REG_SIZE) { + if (off >= 0 || off % BPF_REG_SIZE) { verbose(env, "cannot pass in %s at an offset=%d\n", obj_kind, off); return -EINVAL; } diff --git a/tools/testing/selftests/bpf/progs/iters_state_safety.c b/tools/testing/selftests/bpf/progs/iters_state_safety.c index 646026430e9b..e5bb9fe6d5e5 100644 --- a/tools/testing/selftests/bpf/progs/iters_state_safety.c +++ b/tools/testing/selftests/bpf/progs/iters_state_safety.c @@ -52,6 +52,28 @@ int create_and_destroy(void *ctx) return 0; } +/* fp+0 is not a stack slot. bpf_get_spi(0) used to alias spi 0 (fp-8). */ +SEC("?raw_tp") +__failure __msg("cannot pass in iter at an offset=0") +int destroy_fp0_fail(void *ctx) +{ + struct bpf_iter_num iter; + + asm volatile ("r1 = %[iter];" + "r2 = 0;" + "r3 = 1000;" + "call %[bpf_iter_num_new];" + /* r10 is fp+0, one byte above the top of the BPF stack */ + "r1 = r10;" + "call %[bpf_iter_num_destroy];" + : + : __imm_ptr(iter), ITER_HELPERS + : __clobber_common + ); + + return 0; +} + SEC("?raw_tp") __failure __msg("Unreleased reference id=1") int create_and_forget_to_destroy_fail(void *ctx) |
