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 or MEM_RCU flavors, both of which the type match accepts.
Add two cases. The first 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. The second passes task_struct->real_parent, which is __rcu and on BTF_TYPE_SAFE_RCU(task_struct), so the load yields PTR_TO_BTF_ID | MEM_RCU. Both calls are expected to be rejected with "must be referenced or trusted". Signed-off-by: Yiyang Chen <[email protected]> --- .../selftests/bpf/progs/verifier_global_ptr_args.c | 40 ++++++++++++++++++++++ 1 file changed, 40 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 03507eeae3cb3..ec042f91bcf20 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,46 @@ __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 or trusted") +__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 is __rcu and on BTF_TYPE_SAFE_RCU(task_struct), so the load + * yields PTR_TO_BTF_ID | MEM_RCU. That is neither referenced nor trusted and + * must not satisfy __arg_trusted. + */ +SEC("tp_btf/task_newtask") +__failure +__msg("R1 must be referenced or trusted") +__msg("Caller passes invalid args into func#{{.*}} ('subprog_trusted_task_nullable')") +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

