Skip to content

Commit 8d94f13

Browse files
Alexei StarovoitovMartin KaFai Lau
authored andcommitted
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 <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin KaFai Lau <[email protected]>
1 parent 88d1d4a commit 8d94f13

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

kernel/bpf/verifier.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10752,6 +10752,11 @@ static bool is_kfunc_arg_ignore(const struct btf *btf, const struct btf_param *a
1075210752
return btf_param_match_suffix(btf, arg, "__ign");
1075310753
}
1075410754

10755+
static bool is_kfunc_arg_map(const struct btf *btf, const struct btf_param *arg)
10756+
{
10757+
return btf_param_match_suffix(btf, arg, "__map");
10758+
}
10759+
1075510760
static bool is_kfunc_arg_alloc_obj(const struct btf *btf, const struct btf_param *arg)
1075610761
{
1075710762
return btf_param_match_suffix(btf, arg, "__alloc");
@@ -10921,6 +10926,7 @@ enum kfunc_ptr_arg_type {
1092110926
KF_ARG_PTR_TO_RB_NODE,
1092210927
KF_ARG_PTR_TO_NULL,
1092310928
KF_ARG_PTR_TO_CONST_STR,
10929+
KF_ARG_PTR_TO_MAP,
1092410930
};
1092510931

1092610932
enum special_kfunc_type {
@@ -11074,6 +11080,9 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
1107411080
if (is_kfunc_arg_const_str(meta->btf, &args[argno]))
1107511081
return KF_ARG_PTR_TO_CONST_STR;
1107611082

11083+
if (is_kfunc_arg_map(meta->btf, &args[argno]))
11084+
return KF_ARG_PTR_TO_MAP;
11085+
1107711086
if ((base_type(reg->type) == PTR_TO_BTF_ID || reg2btf_ids[base_type(reg->type)])) {
1107811087
if (!btf_type_is_struct(ref_t)) {
1107911088
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_
1167411683
switch (kf_arg_type) {
1167511684
case KF_ARG_PTR_TO_NULL:
1167611685
continue;
11686+
case KF_ARG_PTR_TO_MAP:
1167711687
case KF_ARG_PTR_TO_ALLOC_BTF_ID:
1167811688
case KF_ARG_PTR_TO_BTF_ID:
1167911689
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_
1189011900
if (ret < 0)
1189111901
return ret;
1189211902
break;
11903+
case KF_ARG_PTR_TO_MAP:
11904+
/* If argument has '__map' suffix expect 'struct bpf_map *' */
11905+
ref_id = *reg2btf_ids[CONST_PTR_TO_MAP];
11906+
ref_t = btf_type_by_id(btf_vmlinux, ref_id);
11907+
ref_tname = btf_name_by_offset(btf, ref_t->name_off);
11908+
fallthrough;
1189311909
case KF_ARG_PTR_TO_BTF_ID:
1189411910
/* Only base_type is checked, further checks are done here */
1189511911
if ((base_type(reg->type) != PTR_TO_BTF_ID ||

0 commit comments

Comments
 (0)