verifier_global_ptr_args.c already covers passing an untrusted pointer to a __arg_trusted argument, which is rejected by the register type match. It does not cover the bare PTR_TO_BTF_ID flavor that the type match also accepts.
Add a rejection case that walks task_struct->last_wakee out of a trusted current task and passes the result to a __arg_trusted subprogram parameter. The field has no __rcu tag and is not in BTF_TYPE_SAFE_RCU(task_struct), so the load yields a bare PTR_TO_BTF_ID. Also pass task_struct->real_parent to a trusted-and-nullable subprogram as a positive test. The field is __rcu and on BTF_TYPE_SAFE_RCU(task_struct), so it yields PTR_TO_BTF_ID | MEM_RCU and must remain accepted. Signed-off-by: Yiyang Chen <[email protected]> --- .../selftests/bpf/progs/verifier_global_ptr_args.c | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c b/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c index dcc2dd46751a4..6176b2223a0fb 100644 --- a/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c +++ b/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c @@ -289,6 +289,40 @@ __weak int subprog_void_untrusted(void *p __arg_untrusted) return *(int *)p; } +__weak int subprog_trusted_bare(struct task_struct *task __arg_trusted) +{ + return task->pid; +} + +SEC("tp_btf/task_newtask") +__failure +__msg("R1 must be referenced, trusted, or RCU protected") +__msg("Caller passes invalid args into func#{{.*}} ('subprog_trusted_bare')") +int bare_to_trusted(void *ctx) +{ + struct task_struct *cur = bpf_get_current_task_btf(); + struct task_struct *wakee; + + if (!cur) + return 0; + wakee = cur->last_wakee; + if (!wakee) + return 0; + return subprog_trusted_bare(wakee); +} + +/* real_parent yields an RCU-protected pointer, which is a valid argument. */ +SEC("tp_btf/task_newtask") +__success +int memrcu_to_trusted(void *ctx) +{ + struct task_struct *cur = bpf_get_current_task_btf(); + + if (!cur) + return 0; + return subprog_trusted_task_nullable(cur->real_parent); +} + __weak int subprog_char_untrusted(char *p __arg_untrusted) { return *(int *)p; -- 2.43.0

