Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: return PTR_TO_BTF_ID | PTR_TRUSTED from BPF kfuncs by default

Teach the BPF verifier to treat pointers to struct types returned from
BPF kfuncs as implicitly trusted (PTR_TO_BTF_ID | PTR_TRUSTED) by
default. Returning untrusted pointers to struct types from BPF kfuncs
should be considered an exception only, and certainly not the norm.

Update existing selftests to reflect the change in register type
printing (e.g. `ptr_` becoming `trusted_ptr_` in verifier error
messages).

Link: https://lore.kernel.org/bpf/aV4nbCaMfIoM0awM@google.com/
Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260113083949.2502978-1-mattbobrowski@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Matt Bobrowski and committed by
Alexei Starovoitov
f8ade234 b9da1739

+34 -22
+29 -17
kernel/bpf/verifier.c
··· 14212 14212 if (is_kfunc_rcu_protected(&meta)) 14213 14213 regs[BPF_REG_0].type |= MEM_RCU; 14214 14214 } else { 14215 - mark_reg_known_zero(env, regs, BPF_REG_0); 14216 - regs[BPF_REG_0].btf = desc_btf; 14217 - regs[BPF_REG_0].type = PTR_TO_BTF_ID; 14218 - regs[BPF_REG_0].btf_id = ptr_type_id; 14215 + enum bpf_reg_type type = PTR_TO_BTF_ID; 14219 14216 14220 14217 if (meta.func_id == special_kfunc_list[KF_bpf_get_kmem_cache]) 14221 - regs[BPF_REG_0].type |= PTR_UNTRUSTED; 14222 - else if (is_kfunc_rcu_protected(&meta)) 14223 - regs[BPF_REG_0].type |= MEM_RCU; 14224 - 14225 - if (is_iter_next_kfunc(&meta)) { 14226 - struct bpf_reg_state *cur_iter; 14227 - 14228 - cur_iter = get_iter_from_state(env->cur_state, &meta); 14229 - 14230 - if (cur_iter->type & MEM_RCU) /* KF_RCU_PROTECTED */ 14231 - regs[BPF_REG_0].type |= MEM_RCU; 14232 - else 14233 - regs[BPF_REG_0].type |= PTR_TRUSTED; 14218 + type |= PTR_UNTRUSTED; 14219 + else if (is_kfunc_rcu_protected(&meta) || 14220 + (is_iter_next_kfunc(&meta) && 14221 + (get_iter_from_state(env->cur_state, &meta) 14222 + ->type & MEM_RCU))) { 14223 + /* 14224 + * If the iterator's constructor (the _new 14225 + * function e.g., bpf_iter_task_new) has been 14226 + * annotated with BPF kfunc flag 14227 + * KF_RCU_PROTECTED and was called within a RCU 14228 + * read-side critical section, also propagate 14229 + * the MEM_RCU flag to the pointer returned from 14230 + * the iterator's next function (e.g., 14231 + * bpf_iter_task_next). 14232 + */ 14233 + type |= MEM_RCU; 14234 + } else { 14235 + /* 14236 + * Any PTR_TO_BTF_ID that is returned from a BPF 14237 + * kfunc should by default be treated as 14238 + * implicitly trusted. 14239 + */ 14240 + type |= PTR_TRUSTED; 14234 14241 } 14242 + 14243 + mark_reg_known_zero(env, regs, BPF_REG_0); 14244 + regs[BPF_REG_0].btf = desc_btf; 14245 + regs[BPF_REG_0].type = type; 14246 + regs[BPF_REG_0].btf_id = ptr_type_id; 14235 14247 } 14236 14248 14237 14249 if (is_kfunc_ret_null(&meta)) {
+2 -2
tools/testing/selftests/bpf/progs/map_kptr_fail.c
··· 272 272 273 273 SEC("?tc") 274 274 __failure 275 - __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member") 275 + __msg("invalid kptr access, R2 type=trusted_ptr_prog_test_ref_kfunc expected=ptr_prog_test_member") 276 276 int reject_bad_type_xchg(struct __sk_buff *ctx) 277 277 { 278 278 struct prog_test_ref_kfunc *ref_ptr; ··· 291 291 } 292 292 293 293 SEC("?tc") 294 - __failure __msg("invalid kptr access, R2 type=ptr_prog_test_ref_kfunc") 294 + __failure __msg("invalid kptr access, R2 type=trusted_ptr_prog_test_ref_kfunc") 295 295 int reject_member_of_ref_xchg(struct __sk_buff *ctx) 296 296 { 297 297 struct prog_test_ref_kfunc *ref_ptr;
+1 -1
tools/testing/selftests/bpf/progs/struct_ops_kptr_return_fail__wrong_type.c
··· 12 12 * reject programs returning a referenced kptr of the wrong type. 13 13 */ 14 14 SEC("struct_ops/test_return_ref_kptr") 15 - __failure __msg("At program exit the register R0 is not a known value (ptr_or_null_)") 15 + __failure __msg("At program exit the register R0 is not a known value (trusted_ptr_or_null_)") 16 16 struct task_struct *BPF_PROG(kptr_return_fail__wrong_type, int dummy, 17 17 struct task_struct *task, struct cgroup *cgrp) 18 18 {
+1 -1
tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c
··· 72 72 73 73 SEC("?tp_btf/task_newtask") 74 74 __failure __log_level(2) 75 - __msg("R1 type=ptr_or_null_ expected=ptr_, trusted_ptr_, rcu_ptr_") 75 + __msg("R1 type=trusted_ptr_or_null_ expected=ptr_, trusted_ptr_, rcu_ptr_") 76 76 __msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')") 77 77 int trusted_task_arg_nonnull_fail2(void *ctx) 78 78 {
+1 -1
tools/testing/selftests/bpf/verifier/calls.c
··· 220 220 }, 221 221 .result_unpriv = REJECT, 222 222 .result = REJECT, 223 - .errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed", 223 + .errstr = "variable trusted_ptr_ access var_off=(0x0; 0x7) disallowed", 224 224 }, 225 225 { 226 226 "calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",