mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	bpf: Set kptr_struct_meta for node param to list and rbtree insert funcs
In verifier.c, fixup_kfunc_call uses struct bpf_insn_aux_data's
kptr_struct_meta field to pass information about local kptr types to
various helpers and kfuncs at runtime. The recent bpf_refcount series
added a few functions to the set that need this information:
  * bpf_refcount_acquire
    * Needs to know where the refcount field is in order to increment
  * Graph collection insert kfuncs: bpf_rbtree_add, bpf_list_push_{front,back}
    * Were migrated to possibly fail by the bpf_refcount series. If
      insert fails, the input node is bpf_obj_drop'd. bpf_obj_drop needs
      the kptr_struct_meta in order to decr refcount and properly free
      special fields.
Unfortunately the verifier handling of collection insert kfuncs was not
modified to actually populate kptr_struct_meta. Accordingly, when the
node input to those kfuncs is passed to bpf_obj_drop, it is done so
without the information necessary to decr refcount.
This patch fixes the issue by populating kptr_struct_meta for those
kfuncs.
Fixes: d2dcc67df9 ("bpf: Migrate bpf_rbtree_add and bpf_list_push_{front,back} to possibly fail")
Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
Link: https://lore.kernel.org/r/20230602022647.1571784-3-davemarchevsky@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									d4ae3e587e
								
							
						
					
					
						commit
						2140a6e342
					
				
					 1 changed files with 3 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -10475,6 +10475,8 @@ __process_kf_arg_ptr_to_graph_node(struct bpf_verifier_env *env,
 | 
			
		|||
			node_off, btf_name_by_offset(reg->btf, t->name_off));
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	meta->arg_btf = reg->btf;
 | 
			
		||||
	meta->arg_btf_id = reg->btf_id;
 | 
			
		||||
 | 
			
		||||
	if (node_off != field->graph_root.node_offset) {
 | 
			
		||||
		verbose(env, "arg#1 offset=%d, but expected %s at offset=%d in struct %s\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -11044,6 +11046,7 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
 | 
			
		|||
	    meta.func_id == special_kfunc_list[KF_bpf_rbtree_add_impl]) {
 | 
			
		||||
		release_ref_obj_id = regs[BPF_REG_2].ref_obj_id;
 | 
			
		||||
		insn_aux->insert_off = regs[BPF_REG_2].off;
 | 
			
		||||
		insn_aux->kptr_struct_meta = btf_find_struct_meta(meta.arg_btf, meta.arg_btf_id);
 | 
			
		||||
		err = ref_convert_owning_non_owning(env, release_ref_obj_id);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			verbose(env, "kfunc %s#%d conversion of owning ref to non-owning failed\n",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue