mirror of
https://github.com/torvalds/linux.git
synced 2024-10-23 13:40:56 +00:00
bpf: Recognize '__map' suffix in kfunc arguments
Recognize 'void *p__map' kfunc argument as 'struct bpf_map *p__map'. It allows kfunc to have 'void *' argument for maps, since bpf progs will call them as: struct { __uint(type, BPF_MAP_TYPE_ARENA); ... } arena SEC(".maps"); bpf_kfunc_with_map(... &arena ...); Underneath libbpf will load CONST_PTR_TO_MAP into the register via ld_imm64 insn. If kfunc was defined with 'struct bpf_map *' it would pass the verifier as well, but bpf prog would need to type cast the argument (void *)&arena, which is not clean. Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/r/20240307031228.42896-3-alexei.starovoitov@gmail.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
parent
88d1d4a7ee
commit
8d94f1357c
|
@ -10752,6 +10752,11 @@ static bool is_kfunc_arg_ignore(const struct btf *btf, const struct btf_param *a
|
|||
return btf_param_match_suffix(btf, arg, "__ign");
|
||||
}
|
||||
|
||||
static bool is_kfunc_arg_map(const struct btf *btf, const struct btf_param *arg)
|
||||
{
|
||||
return btf_param_match_suffix(btf, arg, "__map");
|
||||
}
|
||||
|
||||
static bool is_kfunc_arg_alloc_obj(const struct btf *btf, const struct btf_param *arg)
|
||||
{
|
||||
return btf_param_match_suffix(btf, arg, "__alloc");
|
||||
|
@ -10921,6 +10926,7 @@ enum kfunc_ptr_arg_type {
|
|||
KF_ARG_PTR_TO_RB_NODE,
|
||||
KF_ARG_PTR_TO_NULL,
|
||||
KF_ARG_PTR_TO_CONST_STR,
|
||||
KF_ARG_PTR_TO_MAP,
|
||||
};
|
||||
|
||||
enum special_kfunc_type {
|
||||
|
@ -11074,6 +11080,9 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
|
|||
if (is_kfunc_arg_const_str(meta->btf, &args[argno]))
|
||||
return KF_ARG_PTR_TO_CONST_STR;
|
||||
|
||||
if (is_kfunc_arg_map(meta->btf, &args[argno]))
|
||||
return KF_ARG_PTR_TO_MAP;
|
||||
|
||||
if ((base_type(reg->type) == PTR_TO_BTF_ID || reg2btf_ids[base_type(reg->type)])) {
|
||||
if (!btf_type_is_struct(ref_t)) {
|
||||
verbose(env, "kernel function %s args#%d pointer type %s %s is not supported\n",
|
||||
|
@ -11674,6 +11683,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
|
|||
switch (kf_arg_type) {
|
||||
case KF_ARG_PTR_TO_NULL:
|
||||
continue;
|
||||
case KF_ARG_PTR_TO_MAP:
|
||||
case KF_ARG_PTR_TO_ALLOC_BTF_ID:
|
||||
case KF_ARG_PTR_TO_BTF_ID:
|
||||
if (!is_kfunc_trusted_args(meta) && !is_kfunc_rcu(meta))
|
||||
|
@ -11890,6 +11900,12 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
case KF_ARG_PTR_TO_MAP:
|
||||
/* If argument has '__map' suffix expect 'struct bpf_map *' */
|
||||
ref_id = *reg2btf_ids[CONST_PTR_TO_MAP];
|
||||
ref_t = btf_type_by_id(btf_vmlinux, ref_id);
|
||||
ref_tname = btf_name_by_offset(btf, ref_t->name_off);
|
||||
fallthrough;
|
||||
case KF_ARG_PTR_TO_BTF_ID:
|
||||
/* Only base_type is checked, further checks are done here */
|
||||
if ((base_type(reg->type) != PTR_TO_BTF_ID ||
|
||||
|
|
Loading…
Reference in New Issue
Block a user