A global subprogram parameter tagged __arg_trusted is specified to accept only the PTR_TRUSTED flavor of PTR_TO_BTF_ID, but the call-site check in btf_check_func_arg_match() also accepts a bare PTR_TO_BTF_ID and an MEM_RCU one.
check_reg_type() resolves the accepted set from the base argument type alone and compares only MEM_RDONLY and PTR_MAYBE_NULL, so the PTR_TRUSTED bit of arg_type is never consulted. btf_ptr_types lists bare PTR_TO_BTF_ID and PTR_TO_BTF_ID | MEM_RCU alongside the trusted flavor, and nothing else on the subprogram call path requires the register to be referenced or trusted. The callee is then validated with PTR_TRUSTED set on the register while the caller passed a pointer that is neither referenced nor trusted. bpf_may_fault_on_deref() is false for PTR_TRUSTED, so the dereference becomes a raw load instead of a BPF_PROBE_MEM probe and the callee can pass the pointer on to a kfunc that would have rejected it at the original call site. Reject a PTR_TO_BTF_ID that is neither referenced nor trusted when the argument is marked PTR_TRUSTED. A referenced register is accepted, as in is_trusted_reg(). PTR_MAYBE_NULL is not counted as unsafe when __arg_nullable declares it, so trusted-and-nullable arguments keep working. The kfunc path is unchanged. Changes in v2: - Retarget the fix to btf_check_func_arg_match(), where the subprogram argument check lives in this tree, instead of check_func_arg(). - Run the check after check_reg_type() and check_func_arg_reg_off() so type and offset diagnostics keep their wording. v1: https://lore.kernel.org/bpf/20261005-a3-arg-trusted-v4-v1-0-50ee0268f...@mails.tsinghua.edu.cn/ Yiyang Chen (2): bpf: Require referenced or trusted pointer for __arg_trusted arg selftests/bpf: Cover non-trusted pointer to __arg_trusted subprog arg kernel/bpf/verifier.c | 24 +++++++++++++ .../selftests/bpf/progs/verifier_global_ptr_args.c | 40 ++++++++++++++++++++++ 2 files changed, 64 insertions(+) base-commit: ff47652a4b66c067c765a7ad464d930b5a9367cc -- 2.34.0

