Adding support to define sorted set of BTF ID values. Following defines sorted set of BTF ID values: BTF_SET_START(btf_allowlist_d_path) BTF_ID(func, vfs_truncate) BTF_ID(func, vfs_fallocate) BTF_ID(func, dentry_open) BTF_ID(func, vfs_getattr) BTF_ID(func, filp_close) BTF_SET_END(btf_allowlist_d_path) It defines following 'struct btf_id_set' variable to access values and count: struct btf_id_set btf_allowlist_d_path; Adding 'allowed' callback to struct bpf_func_proto, to allow verifier the check on allowed callers. Adding btf_id_set_contains function, which will be used by allowed callbacks to verify the caller's BTF ID value is within allowed set. Also removing extra '\' in __BTF_ID_LIST macro. Added BTF_SET_START_GLOBAL macro for global sets.
Unified · Split
| @@ -317,6 +317,7 @@ struct bpf_func_proto { · 316 unmodified lines | ||
| 317 | 317 | * for this argument. |
| 318 | 318 | */ |
| 319 | 319 | int *ret_btf_id; /* return value btf_id */ |
| 320 | + bool (*allowed)(const struct bpf_prog *prog); | |
| 320 | 321 | }; |
| 321 | 322 | |
| 322 | 323 | /* bpf_context is intentionally undefined structure. Pointer to bpf_context is |
| @@ -1878,4 +1879,7 @@ enum bpf_text_poke_type { · 1555 unmodified lines | ||
| 1878 | 1879 | int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, |
| 1879 | 1880 | void *addr1, void *addr2); |
| 1880 | 1881 | |
| 1882 | +struct btf_id_set; | |
| 1883 | +bool btf_id_set_contains(struct btf_id_set *set, u32 id); | |
| 1884 | + | |
| 1881 | 1885 | #endif /* _LINUX_BPF_H */ |
| @@ -3,6 +3,11 @@ · 2 unmodified lines | ||
| 3 | 3 | #ifndef _LINUX_BTF_IDS_H |
| 4 | 4 | #define _LINUX_BTF_IDS_H |
| 5 | 5 | |
| 6 | +struct btf_id_set { | |
| 7 | + u32 cnt; | |
| 8 | + u32 ids[]; | |
| 9 | +}; | |
| 10 | + | |
| 6 | 11 | #ifdef CONFIG_DEBUG_INFO_BTF |
| 7 | 12 | |
| 8 | 13 | #include <linux/compiler.h> /* for __PASTE */ |
| @@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines | ||
| 62 | 67 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ |
| 63 | 68 | "." #scope " " #name "; \n" \ |
| 64 | 69 | #name ":; \n" \ |
| 65 | −".popsection; \n"); \ | |
| 70 | +".popsection; \n"); | |
| 66 | 71 | |
| 67 | 72 | #define BTF_ID_LIST(name) \ |
| 68 | 73 | __BTF_ID_LIST(name, local) \ |
| @@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines | ||
| 88 | 93 | ".zero 4 \n" \ |
| 89 | 94 | ".popsection; \n"); |
| 90 | 95 | |
| 96 | +/* | |
| 97 | + * The BTF_SET_START/END macros pair defines sorted list of | |
| 98 | + * BTF IDs plus its members count, with following layout: | |
| 99 | + * | |
| 100 | + * BTF_SET_START(list) | |
| 101 | + * BTF_ID(type1, name1) | |
| 102 | + * BTF_ID(type2, name2) | |
| 103 | + * BTF_SET_END(list) | |
| 104 | + * | |
| 105 | + * __BTF_ID__set__list: | |
| 106 | + * .zero 4 | |
| 107 | + * list: | |
| 108 | + * __BTF_ID__type1__name1__3: | |
| 109 | + * .zero 4 | |
| 110 | + * __BTF_ID__type2__name2__4: | |
| 111 | + * .zero 4 | |
| 112 | + * | |
| 113 | + */ | |
| 114 | +#define __BTF_SET_START(name, scope) \ | |
| 115 | +asm( \ | |
| 116 | +".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
| 117 | +"." #scope " __BTF_ID__set__" #name "; \n" \ | |
| 118 | +"__BTF_ID__set__" #name ":; \n" \ | |
| 119 | +".zero 4 \n" \ | |
| 120 | +".popsection; \n"); | |
| 121 | + | |
| 122 | +#define BTF_SET_START(name) \ | |
| 123 | +__BTF_ID_LIST(name, local) \ | |
| 124 | +__BTF_SET_START(name, local) | |
| 125 | + | |
| 126 | +#define BTF_SET_START_GLOBAL(name) \ | |
| 127 | +__BTF_ID_LIST(name, globl) \ | |
| 128 | +__BTF_SET_START(name, globl) | |
| 129 | + | |
| 130 | +#define BTF_SET_END(name) \ | |
| 131 | +asm( \ | |
| 132 | +".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
| 133 | +".size __BTF_ID__set__" #name ", .-" #name " \n" \ | |
| 134 | +".popsection; \n"); \ | |
| 135 | +extern struct btf_id_set name; | |
| 136 | + | |
| 91 | 137 | #else |
| 92 | 138 | |
| 93 | 139 | #define BTF_ID_LIST(name) static u32 name[5]; |
| 94 | 140 | #define BTF_ID(prefix, name) |
| 95 | 141 | #define BTF_ID_UNUSED |
| 96 | 142 | #define BTF_ID_LIST_GLOBAL(name) u32 name[1]; |
| 143 | +#define BTF_SET_START(name) static struct btf_id_set name = { 0 }; | |
| 144 | +#define BTF_SET_START_GLOBAL(name) static struct btf_id_set name = { 0 }; | |
| 145 | +#define BTF_SET_END(name) | |
| 97 | 146 | |
| 98 | 147 | #endif /* CONFIG_DEBUG_INFO_BTF */ |
| 99 | 148 | |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/btf_ids.h> |
| 22 | 22 | #include <linux/skmsg.h> |
| 23 | 23 | #include <linux/perf_event.h> |
| 24 | +#include <linux/bsearch.h> | |
| 25 | +#include <linux/btf_ids.h> | |
| 24 | 26 | #include <net/sock.h> |
| 25 | 27 | |
| 26 | 28 | /* BTF (BPF Type Format) is the meta data format which describes |
| @@ -4762,3 +4764,15 @@ u32 btf_id(const struct btf *btf) · 4735 unmodified lines | ||
| 4762 | 4764 | { |
| 4763 | 4765 | return btf->id; |
| 4764 | 4766 | } |
| 4767 | + | |
| 4768 | +static int btf_id_cmp_func(const void *a, const void *b) | |
| 4769 | +{ | |
| 4770 | + const int *pa = a, *pb = b; | |
| 4771 | + | |
| 4772 | + return *pa - *pb; | |
| 4773 | +} | |
| 4774 | + | |
| 4775 | +bool btf_id_set_contains(struct btf_id_set *set, u32 id) | |
| 4776 | +{ | |
| 4777 | + return bsearch(&id, set->ids, set->cnt, sizeof(u32), btf_id_cmp_func) != NULL; | |
| 4778 | +} | |
| @@ -4859,6 +4859,11 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn · 4858 unmodified lines | ||
| 4859 | 4859 | return -EINVAL; |
| 4860 | 4860 | } |
| 4861 | 4861 | |
| 4862 | + if (fn->allowed && !fn->allowed(env->prog)) { | |
| 4863 | + verbose(env, "helper call is not allowed in probe\n"); | |
| 4864 | + return -EINVAL; | |
| 4865 | + } | |
| 4866 | + | |
| 4862 | 4867 | /* With LD_ABS/IND some JITs save/restore skb from r1. */ |
| 4863 | 4868 | changes_data = bpf_helper_changes_pkt_data(fn->func); |
| 4864 | 4869 | if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) { |
| @@ -3,6 +3,11 @@ · 2 unmodified lines | ||
| 3 | 3 | #ifndef _LINUX_BTF_IDS_H |
| 4 | 4 | #define _LINUX_BTF_IDS_H |
| 5 | 5 | |
| 6 | +struct btf_id_set { | |
| 7 | + u32 cnt; | |
| 8 | + u32 ids[]; | |
| 9 | +}; | |
| 10 | + | |
| 6 | 11 | #ifdef CONFIG_DEBUG_INFO_BTF |
| 7 | 12 | |
| 8 | 13 | #include <linux/compiler.h> /* for __PASTE */ |
| @@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines | ||
| 62 | 67 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ |
| 63 | 68 | "." #scope " " #name "; \n" \ |
| 64 | 69 | #name ":; \n" \ |
| 65 | −".popsection; \n"); \ | |
| 70 | +".popsection; \n"); | |
| 66 | 71 | |
| 67 | 72 | #define BTF_ID_LIST(name) \ |
| 68 | 73 | __BTF_ID_LIST(name, local) \ |
| @@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines | ||
| 88 | 93 | ".zero 4 \n" \ |
| 89 | 94 | ".popsection; \n"); |
| 90 | 95 | |
| 96 | +/* | |
| 97 | + * The BTF_SET_START/END macros pair defines sorted list of | |
| 98 | + * BTF IDs plus its members count, with following layout: | |
| 99 | + * | |
| 100 | + * BTF_SET_START(list) | |
| 101 | + * BTF_ID(type1, name1) | |
| 102 | + * BTF_ID(type2, name2) | |
| 103 | + * BTF_SET_END(list) | |
| 104 | + * | |
| 105 | + * __BTF_ID__set__list: | |
| 106 | + * .zero 4 | |
| 107 | + * list: | |
| 108 | + * __BTF_ID__type1__name1__3: | |
| 109 | + * .zero 4 | |
| 110 | + * __BTF_ID__type2__name2__4: | |
| 111 | + * .zero 4 | |
| 112 | + * | |
| 113 | + */ | |
| 114 | +#define __BTF_SET_START(name, scope) \ | |
| 115 | +asm( \ | |
| 116 | +".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
| 117 | +"." #scope " __BTF_ID__set__" #name "; \n" \ | |
| 118 | +"__BTF_ID__set__" #name ":; \n" \ | |
| 119 | +".zero 4 \n" \ | |
| 120 | +".popsection; \n"); | |
| 121 | + | |
| 122 | +#define BTF_SET_START(name) \ | |
| 123 | +__BTF_ID_LIST(name, local) \ | |
| 124 | +__BTF_SET_START(name, local) | |
| 125 | + | |
| 126 | +#define BTF_SET_START_GLOBAL(name) \ | |
| 127 | +__BTF_ID_LIST(name, globl) \ | |
| 128 | +__BTF_SET_START(name, globl) | |
| 129 | + | |
| 130 | +#define BTF_SET_END(name) \ | |
| 131 | +asm( \ | |
| 132 | +".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
| 133 | +".size __BTF_ID__set__" #name ", .-" #name " \n" \ | |
| 134 | +".popsection; \n"); \ | |
| 135 | +extern struct btf_id_set name; | |
| 136 | + | |
| 91 | 137 | #else |
| 92 | 138 | |
| 93 | 139 | #define BTF_ID_LIST(name) static u32 name[5]; |
| 94 | 140 | #define BTF_ID(prefix, name) |
| 95 | 141 | #define BTF_ID_UNUSED |
| 96 | 142 | #define BTF_ID_LIST_GLOBAL(name) u32 name[1]; |
| 143 | +#define BTF_SET_START(name) static struct btf_id_set name = { 0 }; | |
| 144 | +#define BTF_SET_START_GLOBAL(name) static struct btf_id_set name = { 0 }; | |
| 145 | +#define BTF_SET_END(name) | |
| 97 | 146 | |
| 98 | 147 | #endif /* CONFIG_DEBUG_INFO_BTF */ |
| 99 | 148 | |