Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Introduce KF_ARG_PTR_TO_CONST_STR

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@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://lore.kernel.org/bpf/20231107045725.2278852-4-song@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Song Liu and committed by
Alexei Starovoitov
045edee1 0b519407

+43
+24
Documentation/bpf/kfuncs.rst
··· 135 135 annotation, the verifier will reject the program if a null pointer is passed in with 136 136 a nonzero size. 137 137 138 + 2.2.5 __str Annotation 139 + ---------------------------- 140 + This annotation is used to indicate that the argument is a constant string. 141 + 142 + An example is given below:: 143 + 144 + __bpf_kfunc bpf_get_file_xattr(..., const char *name__str, ...) 145 + { 146 + ... 147 + } 148 + 149 + In this case, ``bpf_get_file_xattr()`` can be called as:: 150 + 151 + bpf_get_file_xattr(..., "xattr_name", ...); 152 + 153 + Or:: 154 + 155 + const char name[] = "xattr_name"; /* This need to be global */ 156 + int BPF_PROG(...) 157 + { 158 + ... 159 + bpf_get_file_xattr(..., name, ...); 160 + ... 161 + } 138 162 139 163 .. _BPF_kfunc_nodef: 140 164
+19
kernel/bpf/verifier.c
··· 10810 10810 return __kfunc_param_match_suffix(btf, arg, "__nullable"); 10811 10811 } 10812 10812 10813 + static bool is_kfunc_arg_const_str(const struct btf *btf, const struct btf_param *arg) 10814 + { 10815 + return __kfunc_param_match_suffix(btf, arg, "__str"); 10816 + } 10817 + 10813 10818 static bool is_kfunc_arg_scalar_with_name(const struct btf *btf, 10814 10819 const struct btf_param *arg, 10815 10820 const char *name) ··· 10958 10953 KF_ARG_PTR_TO_RB_ROOT, 10959 10954 KF_ARG_PTR_TO_RB_NODE, 10960 10955 KF_ARG_PTR_TO_NULL, 10956 + KF_ARG_PTR_TO_CONST_STR, 10961 10957 }; 10962 10958 10963 10959 enum special_kfunc_type { ··· 11108 11102 11109 11103 if (is_kfunc_arg_rbtree_node(meta->btf, &args[argno])) 11110 11104 return KF_ARG_PTR_TO_RB_NODE; 11105 + 11106 + if (is_kfunc_arg_const_str(meta->btf, &args[argno])) 11107 + return KF_ARG_PTR_TO_CONST_STR; 11111 11108 11112 11109 if ((base_type(reg->type) == PTR_TO_BTF_ID || reg2btf_ids[base_type(reg->type)])) { 11113 11110 if (!btf_type_is_struct(ref_t)) { ··· 11743 11734 case KF_ARG_PTR_TO_MEM_SIZE: 11744 11735 case KF_ARG_PTR_TO_CALLBACK: 11745 11736 case KF_ARG_PTR_TO_REFCOUNTED_KPTR: 11737 + case KF_ARG_PTR_TO_CONST_STR: 11746 11738 /* Trusted by default */ 11747 11739 break; 11748 11740 default: ··· 12014 12004 12015 12005 meta->arg_btf = reg->btf; 12016 12006 meta->arg_btf_id = reg->btf_id; 12007 + break; 12008 + case KF_ARG_PTR_TO_CONST_STR: 12009 + if (reg->type != PTR_TO_MAP_VALUE) { 12010 + verbose(env, "arg#%d doesn't point to a const string\n", i); 12011 + return -EINVAL; 12012 + } 12013 + ret = check_reg_const_str(env, reg, regno); 12014 + if (ret) 12015 + return ret; 12017 12016 break; 12018 12017 } 12019 12018 }