Re: [PATCH v2 bpf-next 07/13] bpf: Add support for bpf_rb_root and bpf_rb_node in kfunc args

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Dec 17, 2022 at 12:25:00AM -0800, Dave Marchevsky wrote:
>  
> +static int
> +__process_kf_arg_ptr_to_graph_node(struct bpf_verifier_env *env,
> +				   struct bpf_reg_state *reg, u32 regno,
> +				   struct bpf_kfunc_call_arg_meta *meta,
> +				   enum btf_field_type head_field_type,
> +				   enum btf_field_type node_field_type,
> +				   struct btf_field **node_field)
> +{
> +	const char *node_type_name;
>  	const struct btf_type *et, *t;
>  	struct btf_field *field;
> -	u32 list_node_off;
> +	u32 node_off;
>  
> -	if (meta->btf != btf_vmlinux ||
> -	    (meta->func_id != special_kfunc_list[KF_bpf_list_push_front] &&
> -	     meta->func_id != special_kfunc_list[KF_bpf_list_push_back])) {
> -		verbose(env, "verifier internal error: bpf_list_node argument for unknown kfunc\n");
> +	if (meta->btf != btf_vmlinux) {
> +		verbose(env, "verifier internal error: unexpected btf mismatch in kfunc call\n");
>  		return -EFAULT;
>  	}
>  
> +	if (!check_kfunc_is_graph_node_api(env, node_field_type, meta->func_id))
> +		return -EFAULT;
> +
> +	node_type_name = btf_field_type_name(node_field_type);
>  	if (!tnum_is_const(reg->var_off)) {
>  		verbose(env,
> -			"R%d doesn't have constant offset. bpf_list_node has to be at the constant offset\n",
> -			regno);
> +			"R%d doesn't have constant offset. %s has to be at the constant offset\n",
> +			regno, node_type_name);
>  		return -EINVAL;
>  	}
>  
> -	list_node_off = reg->off + reg->var_off.value;
> -	field = reg_find_field_offset(reg, list_node_off, BPF_LIST_NODE);
> -	if (!field || field->offset != list_node_off) {
> -		verbose(env, "bpf_list_node not found at offset=%u\n", list_node_off);
> +	node_off = reg->off + reg->var_off.value;
> +	field = reg_find_field_offset(reg, node_off, node_field_type);
> +	if (!field || field->offset != node_off) {
> +		verbose(env, "%s not found at offset=%u\n", node_type_name, node_off);
>  		return -EINVAL;
>  	}
>  
> -	field = meta->arg_list_head.field;
> +	field = *node_field;
>  
>  	et = btf_type_by_id(field->graph_root.btf, field->graph_root.value_btf_id);
>  	t = btf_type_by_id(reg->btf, reg->btf_id);
>  	if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, 0, field->graph_root.btf,
>  				  field->graph_root.value_btf_id, true)) {
> -		verbose(env, "operation on bpf_list_head expects arg#1 bpf_list_node at offset=%d "
> +		verbose(env, "operation on %s expects arg#1 %s at offset=%d "
>  			"in struct %s, but arg is at offset=%d in struct %s\n",
> +			btf_field_type_name(head_field_type),
> +			btf_field_type_name(node_field_type),
>  			field->graph_root.node_offset,
>  			btf_name_by_offset(field->graph_root.btf, et->name_off),
> -			list_node_off, btf_name_by_offset(reg->btf, t->name_off));
> +			node_off, btf_name_by_offset(reg->btf, t->name_off));
>  		return -EINVAL;
>  	}
>  
> -	if (list_node_off != field->graph_root.node_offset) {
> -		verbose(env, "arg#1 offset=%d, but expected bpf_list_node at offset=%d in struct %s\n",
> -			list_node_off, field->graph_root.node_offset,
> +	if (node_off != field->graph_root.node_offset) {
> +		verbose(env, "arg#1 offset=%d, but expected %s at offset=%d in struct %s\n",
> +			node_off, btf_field_type_name(node_field_type),
> +			field->graph_root.node_offset,
>  			btf_name_by_offset(field->graph_root.btf, et->name_off));
>  		return -EINVAL;
>  	}
> @@ -8932,6 +9053,24 @@ static int process_kf_arg_ptr_to_list_node(struct bpf_verifier_env *env,
>  	return 0;
>  }

and with suggestion in patch 2 the single __process_kf_arg_ptr_to_graph_node helper
called as:

> +static int process_kf_arg_ptr_to_list_node(struct bpf_verifier_env *env,
> +					   struct bpf_reg_state *reg, u32 regno,
> +					   struct bpf_kfunc_call_arg_meta *meta)
> +{
> +	return __process_kf_arg_ptr_to_graph_node(env, reg, regno, meta,
> +						  BPF_LIST_HEAD, BPF_LIST_NODE,
> +						  &meta->arg_list_head.field);
> +}
> +
> +static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
> +					     struct bpf_reg_state *reg, u32 regno,
> +					     struct bpf_kfunc_call_arg_meta *meta)
> +{
> +	return __process_kf_arg_ptr_to_graph_node(env, reg, regno, meta,
> +						  BPF_RB_ROOT, BPF_RB_NODE,
> +						  &meta->arg_rbtree_root.field);
> +}

would convert the arg from owning to non-owning.



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux