mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	bpf: check bpf_dummy_struct_ops program params for test runs
When doing BPF_PROG_TEST_RUN for bpf_dummy_struct_ops programs, reject execution when NULL is passed for non-nullable params. For programs with non-nullable params verifier assumes that such params are never NULL and thus might optimize out NULL checks. Suggested-by: Kui-Feng Lee <sinquersw@gmail.com> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20240424012821.595216-5-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									f612210d45
								
							
						
					
					
						commit
						980ca8ceea
					
				
					 1 changed files with 50 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -79,6 +79,51 @@ static int dummy_ops_call_op(void *image, struct bpf_dummy_ops_test_args *args)
 | 
			
		|||
		    args->args[3], args->args[4]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct bpf_ctx_arg_aux *find_ctx_arg_info(struct bpf_prog_aux *aux, int offset)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < aux->ctx_arg_info_size; i++)
 | 
			
		||||
		if (aux->ctx_arg_info[i].offset == offset)
 | 
			
		||||
			return &aux->ctx_arg_info[i];
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* There is only one check at the moment:
 | 
			
		||||
 * - zero should not be passed for pointer parameters not marked as nullable.
 | 
			
		||||
 */
 | 
			
		||||
static int check_test_run_args(struct bpf_prog *prog, struct bpf_dummy_ops_test_args *args)
 | 
			
		||||
{
 | 
			
		||||
	const struct btf_type *func_proto = prog->aux->attach_func_proto;
 | 
			
		||||
 | 
			
		||||
	for (u32 arg_no = 0; arg_no < btf_type_vlen(func_proto) ; ++arg_no) {
 | 
			
		||||
		const struct btf_param *param = &btf_params(func_proto)[arg_no];
 | 
			
		||||
		const struct bpf_ctx_arg_aux *info;
 | 
			
		||||
		const struct btf_type *t;
 | 
			
		||||
		int offset;
 | 
			
		||||
 | 
			
		||||
		if (args->args[arg_no] != 0)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Program is validated already, so there is no need
 | 
			
		||||
		 * to check if t is NULL.
 | 
			
		||||
		 */
 | 
			
		||||
		t = btf_type_skip_modifiers(bpf_dummy_ops_btf, param->type, NULL);
 | 
			
		||||
		if (!btf_type_is_ptr(t))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		offset = btf_ctx_arg_offset(bpf_dummy_ops_btf, func_proto, arg_no);
 | 
			
		||||
		info = find_ctx_arg_info(prog->aux, offset);
 | 
			
		||||
		if (info && (info->reg_type & PTR_MAYBE_NULL))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern const struct bpf_link_ops bpf_struct_ops_link_lops;
 | 
			
		||||
 | 
			
		||||
int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +132,7 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
 | 
			
		|||
	const struct bpf_struct_ops *st_ops = &bpf_bpf_dummy_ops;
 | 
			
		||||
	const struct btf_type *func_proto;
 | 
			
		||||
	struct bpf_dummy_ops_test_args *args;
 | 
			
		||||
	struct bpf_tramp_links *tlinks;
 | 
			
		||||
	struct bpf_tramp_links *tlinks = NULL;
 | 
			
		||||
	struct bpf_tramp_link *link = NULL;
 | 
			
		||||
	void *image = NULL;
 | 
			
		||||
	unsigned int op_idx;
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +154,10 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
 | 
			
		|||
	if (IS_ERR(args))
 | 
			
		||||
		return PTR_ERR(args);
 | 
			
		||||
 | 
			
		||||
	err = check_test_run_args(prog, args);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL);
 | 
			
		||||
	if (!tlinks) {
 | 
			
		||||
		err = -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue