Add a path where RCU protection reaches zero and then starts again. The iterator is untrusted after this gap and must be rejected. Signed-off-by: Ning Ding --- .../selftests/bpf/progs/iters_task_failure.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/iters_task_failure.c b/tools/testing/selftests/bpf/progs/iters_task_failure.c index fe3663dedbe14..bac394ae77f44 100644 --- a/tools/testing/selftests/bpf/progs/iters_task_failure.c +++ b/tools/testing/selftests/bpf/progs/iters_task_failure.c @@ -61,6 +61,33 @@ int BPF_PROG(iter_tasks_lock_and_unlock) return 0; } +SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") +__failure __msg("expected an RCU CS when using bpf_iter_task_next") +__flag(BPF_F_TEST_STATE_FREQ) +int BPF_PROG(iter_tasks_rcu_state_pruning) +{ + struct bpf_iter_task it; + + bpf_rcu_read_lock(); + bpf_iter_task_new(&it, NULL, BPF_TASK_ITER_ALL_PROCS); + + if (likely(bpf_get_prandom_u32())) { + /* Keep the outer RCU lock active. */ + bpf_rcu_read_lock(); + bpf_rcu_read_unlock(); + } else { + /* Create an unprotected gap. */ + bpf_rcu_read_unlock(); + bpf_rcu_read_lock(); + } + + bpf_iter_task_next(&it); + bpf_iter_task_destroy(&it); + bpf_rcu_read_unlock(); + + return 0; +} + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") __failure __msg("expected an RCU CS when using bpf_iter_css_next") int BPF_PROG(iter_css_lock_and_unlock) -- 2.43.0