[PATCH bpf v2 2/2] selftests/bpf: Cover non-trusted pointer to __arg_trusted subprog arg
From: Yiyang Chen
Date: Mon Oct 05 2026 - 14:33:59 EST
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 <chenyy23@xxxxxxxxxxxxxxxxxxxxx>
---
.../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 dcc2dd46751a4..6765fd4b4a239 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