On Fri, Nov 3, 2023 at 2:46 PM Song Liu <song@xxxxxxxxxx> wrote: > > Similar to ARG_PTR_TO_CONST_STR for BPF helpers, KF_ARG_PTR_TO_CONST_STR > specifies kfunc args that point to const strings. Annotation "__str" is > used to specify kfunc arg of type KF_ARG_PTR_TO_CONST_STR. Also, add > documentation for the "__str" annotation. > > bpf_get_file_xattr() will be the first kfunc that uses this type. > > Signed-off-by: Song Liu <song@xxxxxxxxxx> > --- > Documentation/bpf/kfuncs.rst | 24 ++++++++++++++++++++++++ > kernel/bpf/verifier.c | 19 +++++++++++++++++++ > 2 files changed, 43 insertions(+) > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst > index 0d2647fb358d..bfe065f7e23c 100644 > --- a/Documentation/bpf/kfuncs.rst > +++ b/Documentation/bpf/kfuncs.rst > @@ -137,6 +137,30 @@ Either way, the returned buffer is either NULL, or of size buffer_szk. Without t > annotation, the verifier will reject the program if a null pointer is passed in with > a nonzero size. > > +2.2.5 __str Annotation > +---------------------------- > +This annotation is used to indicate that the argument is a constant string. > + > +An example is given below:: > + > + __bpf_kfunc bpf_get_file_xattr(..., const char *name__str, ...) > + { > + ... > + } > + > +In this case, ``bpf_get_file_xattr()`` can be called as:: > + > + bpf_get_file_xattr(..., "xattr_name", ...); > + > +Or:: > + > + const char name[] = "xattr_name"; /* This need to be global */ > + int BPF_PROG(...) > + { > + ... > + bpf_get_file_xattr(..., name, ...); > + ... > + } > > .. _BPF_kfunc_nodef: > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index fefe3eafccb9..6d382f20674d 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -10803,6 +10803,11 @@ static bool is_kfunc_arg_nullable(const struct btf *btf, const struct btf_param > return __kfunc_param_match_suffix(btf, arg, "__nullable"); > } > > +static bool is_kfunc_arg_const_str(const struct btf *btf, const struct btf_param *arg) > +{ > + return __kfunc_param_match_suffix(btf, arg, "__str"); > +} > + > static bool is_kfunc_arg_scalar_with_name(const struct btf *btf, > const struct btf_param *arg, > const char *name) > @@ -10946,6 +10951,7 @@ enum kfunc_ptr_arg_type { > KF_ARG_PTR_TO_RB_ROOT, > KF_ARG_PTR_TO_RB_NODE, > KF_ARG_PTR_TO_NULL, > + KF_ARG_PTR_TO_CONST_STR, > }; > > enum special_kfunc_type { > @@ -11090,6 +11096,9 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env, > if (is_kfunc_arg_rbtree_node(meta->btf, &args[argno])) > return KF_ARG_PTR_TO_RB_NODE; > > + if (is_kfunc_arg_const_str(meta->btf, &args[argno])) > + return KF_ARG_PTR_TO_CONST_STR; > + > 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", > @@ -11713,6 +11722,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ > case KF_ARG_PTR_TO_MEM_SIZE: > case KF_ARG_PTR_TO_CALLBACK: > case KF_ARG_PTR_TO_REFCOUNTED_KPTR: > + case KF_ARG_PTR_TO_CONST_STR: > /* Trusted by default */ > break; > default: > @@ -11984,6 +11994,15 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ > meta->arg_btf = reg->btf; > meta->arg_btf_id = reg->btf_id; > break; > + case KF_ARG_PTR_TO_CONST_STR: > + if (reg->type != PTR_TO_MAP_VALUE) { > + verbose(env, "arg#%d doesn't point to a const string\n", i); > + return -EINVAL; > + } > + ret = check_reg_const_str(env, reg, regno); > + if (ret) > + return ret; > + break; > } > } > > -- > 2.34.1 >