Re: [PATCH bpf-next v2 2/2] selftests/bpf: Test RCU iterator state pruning

[email protected]
Newsgroups org.kernel.vger.linux-kselftest,org.kernel.vger.bpf,org.kernel.vger.linux-kernel
Message-ID <3ac6ad5d1acfbf15bc536519ba1fc748ea85ece109397bbb50e56cdffb9ce726@mail.kernel.org>
> selftests/bpf: Test RCU iterator state pruning
>
> 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 <[email protected]>

This isn't a bug, but could the changelog mention why BPF_F_TEST_STATE_FREQ
is needed and that both arms deliberately converge with the same RCU lock
depth, so a future reader knows what keeps this test meaningful?

> diff --git a/tools/testing/selftests/bpf/progs/iters_task_failure.c b/tools/testing/selftests/bpf/progs/iters_task_failure.c
> index fe3663dedbe1..566a1d3dffea 100644
> --- a/tools/testing/selftests/bpf/progs/iters_task_failure.c
> +++ b/tools/testing/selftests/bpf/progs/iters_task_failure.c
> @@ -61,6 +61,52 @@ 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;
> +
> +	asm volatile (
> +		"call %[bpf_rcu_read_lock];"
> +		"r1 = %[it];"
> +		"r2 = 0;"
> +		"r3 = 0;" /* BPF_TASK_ITER_ALL_PROCS */
> +		"call %[bpf_iter_task_new];"
> +
> +		"call %[bpf_get_prandom_u32];"
> +		"if w0 == 0 goto unprotected_%=;"
> +
> +		/* Keep the outer RCU lock active on the straight-line path. */
> +		"call %[bpf_rcu_read_lock];"
> +		"call %[bpf_rcu_read_unlock];"

This isn't a bug, but would it help to say what the nested lock/unlock
pair is for here - e.g. that it scratches the caller-saved registers so
the only state difference at merge_ is the iterator's MEM_RCU vs
PTR_UNTRUSTED type?

> +		"goto merge_%=;"
> +
> +	"unprotected_%=:"
> +		/* Create an unprotected gap on the taken path. */
> +		"call %[bpf_rcu_read_unlock];"
> +		"call %[bpf_rcu_read_lock];"
> +
> +	"merge_%=: r1 = %[it];"
> +		"call %[bpf_iter_task_next];"
> +		"r1 = %[it];"
> +		"call %[bpf_iter_task_destroy];"
> +		"call %[bpf_rcu_read_unlock];"
> +		:
> +		: __imm_ptr(it),
> +		  __imm(bpf_get_prandom_u32),
> +		  __imm(bpf_iter_task_new),
> +		  __imm(bpf_iter_task_next),
> +		  __imm(bpf_iter_task_destroy),
> +		  __imm(bpf_rcu_read_lock),
> +		  __imm(bpf_rcu_read_unlock)
> +		: __clobber_common
> +	);
> +
> +	return 0;
> +}
> +


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31457825387
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.