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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bpf: __bpf_dynptr_data* and __str annotation'

Song Liu says:

====================
This set contains the first 3 patches of set [1]. Currently, [1] is waiting
for [3] to be merged to bpf-next tree. So send these 3 patches first to
unblock other works, such as [2]. This set is verified with new version of
[1] in CI run [4].

Changes since v12 of [1]:
1. Reuse bpf_dynptr_slice() in __bpf_dynptr_data(). (Andrii)
2. Add Acked-by from Vadim Fedorenko.

[1] https://lore.kernel.org/bpf/20231104001313.3538201-1-song@kernel.org/
[2] https://lore.kernel.org/bpf/20231031134900.1432945-1-vadfed@meta.com/
[3] https://lore.kernel.org/bpf/20231031215625.2343848-1-davemarchevsky@fb.com/
[4] https://github.com/kernel-patches/bpf/actions/runs/6779945063/job/18427926114
====================

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
b0d1c729 9b75dbeb

+121 -40
+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
+2
include/linux/bpf.h
··· 1222 1222 1223 1223 int bpf_dynptr_check_size(u32 size); 1224 1224 u32 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr); 1225 + const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len); 1226 + void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u32 len); 1225 1227 1226 1228 #ifdef CONFIG_BPF_JIT 1227 1229 int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
+19
kernel/bpf/helpers.c
··· 2618 2618 } 2619 2619 2620 2620 late_initcall(kfunc_init); 2621 + 2622 + /* Get a pointer to dynptr data up to len bytes for read only access. If 2623 + * the dynptr doesn't have continuous data up to len bytes, return NULL. 2624 + */ 2625 + const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len) 2626 + { 2627 + return bpf_dynptr_slice(ptr, 0, NULL, len); 2628 + } 2629 + 2630 + /* Get a pointer to dynptr data up to len bytes for read write access. If 2631 + * the dynptr doesn't have continuous data up to len bytes, or the dynptr 2632 + * is read only, return NULL. 2633 + */ 2634 + void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u32 len) 2635 + { 2636 + if (__bpf_dynptr_is_rdonly(ptr)) 2637 + return NULL; 2638 + return (void *)__bpf_dynptr_data(ptr, len); 2639 + }
+68 -36
kernel/bpf/verifier.c
··· 8725 8725 return state->stack[spi].spilled_ptr.dynptr.type; 8726 8726 } 8727 8727 8728 + static int check_reg_const_str(struct bpf_verifier_env *env, 8729 + struct bpf_reg_state *reg, u32 regno) 8730 + { 8731 + struct bpf_map *map = reg->map_ptr; 8732 + int err; 8733 + int map_off; 8734 + u64 map_addr; 8735 + char *str_ptr; 8736 + 8737 + if (reg->type != PTR_TO_MAP_VALUE) 8738 + return -EINVAL; 8739 + 8740 + if (!bpf_map_is_rdonly(map)) { 8741 + verbose(env, "R%d does not point to a readonly map'\n", regno); 8742 + return -EACCES; 8743 + } 8744 + 8745 + if (!tnum_is_const(reg->var_off)) { 8746 + verbose(env, "R%d is not a constant address'\n", regno); 8747 + return -EACCES; 8748 + } 8749 + 8750 + if (!map->ops->map_direct_value_addr) { 8751 + verbose(env, "no direct value access support for this map type\n"); 8752 + return -EACCES; 8753 + } 8754 + 8755 + err = check_map_access(env, regno, reg->off, 8756 + map->value_size - reg->off, false, 8757 + ACCESS_HELPER); 8758 + if (err) 8759 + return err; 8760 + 8761 + map_off = reg->off + reg->var_off.value; 8762 + err = map->ops->map_direct_value_addr(map, &map_addr, map_off); 8763 + if (err) { 8764 + verbose(env, "direct value access on string failed\n"); 8765 + return err; 8766 + } 8767 + 8768 + str_ptr = (char *)(long)(map_addr); 8769 + if (!strnchr(str_ptr + map_off, map->value_size - map_off, 0)) { 8770 + verbose(env, "string is not zero-terminated\n"); 8771 + return -EINVAL; 8772 + } 8773 + return 0; 8774 + } 8775 + 8728 8776 static int check_func_arg(struct bpf_verifier_env *env, u32 arg, 8729 8777 struct bpf_call_arg_meta *meta, 8730 8778 const struct bpf_func_proto *fn, ··· 9017 8969 } 9018 8970 case ARG_PTR_TO_CONST_STR: 9019 8971 { 9020 - struct bpf_map *map = reg->map_ptr; 9021 - int map_off; 9022 - u64 map_addr; 9023 - char *str_ptr; 9024 - 9025 - if (!bpf_map_is_rdonly(map)) { 9026 - verbose(env, "R%d does not point to a readonly map'\n", regno); 9027 - return -EACCES; 9028 - } 9029 - 9030 - if (!tnum_is_const(reg->var_off)) { 9031 - verbose(env, "R%d is not a constant address'\n", regno); 9032 - return -EACCES; 9033 - } 9034 - 9035 - if (!map->ops->map_direct_value_addr) { 9036 - verbose(env, "no direct value access support for this map type\n"); 9037 - return -EACCES; 9038 - } 9039 - 9040 - err = check_map_access(env, regno, reg->off, 9041 - map->value_size - reg->off, false, 9042 - ACCESS_HELPER); 8972 + err = check_reg_const_str(env, reg, regno); 9043 8973 if (err) 9044 8974 return err; 9045 - 9046 - map_off = reg->off + reg->var_off.value; 9047 - err = map->ops->map_direct_value_addr(map, &map_addr, map_off); 9048 - if (err) { 9049 - verbose(env, "direct value access on string failed\n"); 9050 - return err; 9051 - } 9052 - 9053 - str_ptr = (char *)(long)(map_addr); 9054 - if (!strnchr(str_ptr + map_off, map->value_size - map_off, 0)) { 9055 - verbose(env, "string is not zero-terminated\n"); 9056 - return -EINVAL; 9057 - } 9058 8975 break; 9059 8976 } 9060 8977 case ARG_PTR_TO_KPTR: ··· 10810 10797 return __kfunc_param_match_suffix(btf, arg, "__nullable"); 10811 10798 } 10812 10799 10800 + static bool is_kfunc_arg_const_str(const struct btf *btf, const struct btf_param *arg) 10801 + { 10802 + return __kfunc_param_match_suffix(btf, arg, "__str"); 10803 + } 10804 + 10813 10805 static bool is_kfunc_arg_scalar_with_name(const struct btf *btf, 10814 10806 const struct btf_param *arg, 10815 10807 const char *name) ··· 10958 10940 KF_ARG_PTR_TO_RB_ROOT, 10959 10941 KF_ARG_PTR_TO_RB_NODE, 10960 10942 KF_ARG_PTR_TO_NULL, 10943 + KF_ARG_PTR_TO_CONST_STR, 10961 10944 }; 10962 10945 10963 10946 enum special_kfunc_type { ··· 11108 11089 11109 11090 if (is_kfunc_arg_rbtree_node(meta->btf, &args[argno])) 11110 11091 return KF_ARG_PTR_TO_RB_NODE; 11092 + 11093 + if (is_kfunc_arg_const_str(meta->btf, &args[argno])) 11094 + return KF_ARG_PTR_TO_CONST_STR; 11111 11095 11112 11096 if ((base_type(reg->type) == PTR_TO_BTF_ID || reg2btf_ids[base_type(reg->type)])) { 11113 11097 if (!btf_type_is_struct(ref_t)) { ··· 11743 11721 case KF_ARG_PTR_TO_MEM_SIZE: 11744 11722 case KF_ARG_PTR_TO_CALLBACK: 11745 11723 case KF_ARG_PTR_TO_REFCOUNTED_KPTR: 11724 + case KF_ARG_PTR_TO_CONST_STR: 11746 11725 /* Trusted by default */ 11747 11726 break; 11748 11727 default: ··· 12014 11991 12015 11992 meta->arg_btf = reg->btf; 12016 11993 meta->arg_btf_id = reg->btf_id; 11994 + break; 11995 + case KF_ARG_PTR_TO_CONST_STR: 11996 + if (reg->type != PTR_TO_MAP_VALUE) { 11997 + verbose(env, "arg#%d doesn't point to a const string\n", i); 11998 + return -EINVAL; 11999 + } 12000 + ret = check_reg_const_str(env, reg, regno); 12001 + if (ret) 12002 + return ret; 12017 12003 break; 12018 12004 } 12019 12005 }
+8 -4
kernel/trace/bpf_trace.c
··· 1376 1376 struct bpf_dynptr_kern *sig_ptr, 1377 1377 struct bpf_key *trusted_keyring) 1378 1378 { 1379 + const void *data, *sig; 1380 + u32 data_len, sig_len; 1379 1381 int ret; 1380 1382 1381 1383 if (trusted_keyring->has_ref) { ··· 1394 1392 return ret; 1395 1393 } 1396 1394 1397 - return verify_pkcs7_signature(data_ptr->data, 1398 - __bpf_dynptr_size(data_ptr), 1399 - sig_ptr->data, 1400 - __bpf_dynptr_size(sig_ptr), 1395 + data_len = __bpf_dynptr_size(data_ptr); 1396 + data = __bpf_dynptr_data(data_ptr, data_len); 1397 + sig_len = __bpf_dynptr_size(sig_ptr); 1398 + sig = __bpf_dynptr_data(sig_ptr, sig_len); 1399 + 1400 + return verify_pkcs7_signature(data, data_len, sig, sig_len, 1401 1401 trusted_keyring->key, 1402 1402 VERIFYING_UNSPECIFIED_SIGNATURE, NULL, 1403 1403 NULL);