Add a verifier test that obtains a task VMA snapshot, destroys its iterator, and then attempts to read the snapshot. The verifier must reject the stale access. Also verify that an RCU-protected task pointer remains usable after destroying its task iterator. That iterator's empty destructor must not shorten the surrounding RCU protection. The existing iter_next_trusted test continues to cover a trusted-kfunc use while the VMA iterator is live. Assisted-by: LLM Signed-off-by: Xu Yunxiang --- .../selftests/bpf/progs/iters_testmod.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/iters_testmod.c b/tools/testing/selftests/bpf/progs/iters_testmod.c index 76012dbbdb413..b8c8a3b24582f 100644 --- a/tools/testing/selftests/bpf/progs/iters_testmod.c +++ b/tools/testing/selftests/bpf/progs/iters_testmod.c @@ -28,6 +28,27 @@ int iter_next_trusted(const void *ctx) return 0; } +SEC("raw_tp/sys_enter") +__failure __msg("invalid mem access 'scalar'") +int iter_next_trusted_after_destroy(const void *ctx) +{ + struct task_struct *cur_task = bpf_get_current_task_btf(); + struct bpf_iter_task_vma vma_it; + struct vm_area_struct *vma_ptr; + + bpf_iter_task_vma_new(&vma_it, cur_task, 0); + + vma_ptr = bpf_iter_task_vma_next(&vma_it); + if (!vma_ptr) + goto out; + + bpf_iter_task_vma_destroy(&vma_it); + return vma_ptr->vm_start; +out: + bpf_iter_task_vma_destroy(&vma_it); + return 0; +} + SEC("raw_tp/sys_enter") __failure __msg("Possibly NULL pointer passed to trusted R1") int iter_next_trusted_or_null(const void *ctx) @@ -66,6 +87,28 @@ int iter_next_rcu(const void *ctx) return 0; } +SEC("raw_tp/sys_enter") +__success +int iter_next_rcu_after_destroy(const void *ctx) +{ + struct task_struct *cur_task = bpf_get_current_task_btf(); + struct bpf_iter_task task_it; + struct task_struct *task_ptr; + + bpf_iter_task_new(&task_it, cur_task, 0); + + task_ptr = bpf_iter_task_next(&task_it); + if (!task_ptr) + goto out; + + bpf_iter_task_destroy(&task_it); + bpf_kfunc_rcu_task_test(task_ptr); + return 0; +out: + bpf_iter_task_destroy(&task_it); + return 0; +} + SEC("raw_tp/sys_enter") __failure __msg("Possibly NULL pointer passed to trusted R1") int iter_next_rcu_or_null(const void *ctx) -- 2.43.0