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 | * for this argument. | 317 | * for this argument. |
| 318 | */ | 318 | */ |
| 319 | int *ret_btf_id; /* return value btf_id */ | 319 | int *ret_btf_id; /* return value btf_id */ |
| 320 | bool (*allowed)(const struct bpf_prog *prog); | ||
| 320 | }; | 321 | }; |
| 321 | 322 | ||
| 322 | /* bpf_context is intentionally undefined structure. Pointer to bpf_context is | 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 | int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, | 1879 | int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, |
| 1879 | void *addr1, void *addr2); | 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 | #endif /* _LINUX_BPF_H */ | 1885 | #endif /* _LINUX_BPF_H */ |
| @@ -3,6 +3,11 @@ · 2 unmodified lines | |||
| 3 | #ifndef _LINUX_BTF_IDS_H | 3 | #ifndef _LINUX_BTF_IDS_H |
| 4 | #define _LINUX_BTF_IDS_H | 4 | #define _LINUX_BTF_IDS_H |
| 5 | 5 | ||
| 6 | struct btf_id_set { | ||
| 7 | u32 cnt; | ||
| 8 | u32 ids[]; | ||
| 9 | }; | ||
| 10 | |||
| 6 | #ifdef CONFIG_DEBUG_INFO_BTF | 11 | #ifdef CONFIG_DEBUG_INFO_BTF |
| 7 | 12 | ||
| 8 | #include <linux/compiler.h> /* for __PASTE */ | 13 | #include <linux/compiler.h> /* for __PASTE */ |
| @@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines | |||
| 62 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | 67 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ |
| 63 | "." #scope " " #name "; \n" \ | 68 | "." #scope " " #name "; \n" \ |
| 64 | #name ":; \n" \ | 69 | #name ":; \n" \ |
| 65 | ".popsection; \n"); \ | 70 | ".popsection; \n"); |
| 66 | 71 | ||
| 67 | #define BTF_ID_LIST(name) \ | 72 | #define BTF_ID_LIST(name) \ |
| 68 | __BTF_ID_LIST(name, local) \ | 73 | __BTF_ID_LIST(name, local) \ |
| @@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines | |||
| 88 | ".zero 4 \n" \ | 93 | ".zero 4 \n" \ |
| 89 | ".popsection; \n"); | 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 | #else | 137 | #else |
| 92 | 138 | ||
| 93 | #define BTF_ID_LIST(name) static u32 name[5]; | 139 | #define BTF_ID_LIST(name) static u32 name[5]; |
| 94 | #define BTF_ID(prefix, name) | 140 | #define BTF_ID(prefix, name) |
| 95 | #define BTF_ID_UNUSED | 141 | #define BTF_ID_UNUSED |
| 96 | #define BTF_ID_LIST_GLOBAL(name) u32 name[1]; | 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 | #endif /* CONFIG_DEBUG_INFO_BTF */ | 147 | #endif /* CONFIG_DEBUG_INFO_BTF */ |
| 99 | 148 | ||
| @@ -21,6 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <linux/btf_ids.h> | 21 | #include <linux/btf_ids.h> |
| 22 | #include <linux/skmsg.h> | 22 | #include <linux/skmsg.h> |
| 23 | #include <linux/perf_event.h> | 23 | #include <linux/perf_event.h> |
| 24 | #include <linux/bsearch.h> | ||
| 25 | #include <linux/btf_ids.h> | ||
| 24 | #include <net/sock.h> | 26 | #include <net/sock.h> |
| 25 | 27 | ||
| 26 | /* BTF (BPF Type Format) is the meta data format which describes | 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 | return btf->id; | 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 | return -EINVAL; | 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 | /* With LD_ABS/IND some JITs save/restore skb from r1. */ | 4867 | /* With LD_ABS/IND some JITs save/restore skb from r1. */ |
| 4863 | changes_data = bpf_helper_changes_pkt_data(fn->func); | 4868 | changes_data = bpf_helper_changes_pkt_data(fn->func); |
| 4864 | if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) { | 4869 | if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) { |
| @@ -3,6 +3,11 @@ · 2 unmodified lines | |||
| 3 | #ifndef _LINUX_BTF_IDS_H | 3 | #ifndef _LINUX_BTF_IDS_H |
| 4 | #define _LINUX_BTF_IDS_H | 4 | #define _LINUX_BTF_IDS_H |
| 5 | 5 | ||
| 6 | struct btf_id_set { | ||
| 7 | u32 cnt; | ||
| 8 | u32 ids[]; | ||
| 9 | }; | ||
| 10 | |||
| 6 | #ifdef CONFIG_DEBUG_INFO_BTF | 11 | #ifdef CONFIG_DEBUG_INFO_BTF |
| 7 | 12 | ||
| 8 | #include <linux/compiler.h> /* for __PASTE */ | 13 | #include <linux/compiler.h> /* for __PASTE */ |
| @@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines | |||
| 62 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | 67 | ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ |
| 63 | "." #scope " " #name "; \n" \ | 68 | "." #scope " " #name "; \n" \ |
| 64 | #name ":; \n" \ | 69 | #name ":; \n" \ |
| 65 | ".popsection; \n"); \ | 70 | ".popsection; \n"); |
| 66 | 71 | ||
| 67 | #define BTF_ID_LIST(name) \ | 72 | #define BTF_ID_LIST(name) \ |
| 68 | __BTF_ID_LIST(name, local) \ | 73 | __BTF_ID_LIST(name, local) \ |
| @@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines | |||
| 88 | ".zero 4 \n" \ | 93 | ".zero 4 \n" \ |
| 89 | ".popsection; \n"); | 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 | #else | 137 | #else |
| 92 | 138 | ||
| 93 | #define BTF_ID_LIST(name) static u32 name[5]; | 139 | #define BTF_ID_LIST(name) static u32 name[5]; |
| 94 | #define BTF_ID(prefix, name) | 140 | #define BTF_ID(prefix, name) |
| 95 | #define BTF_ID_UNUSED | 141 | #define BTF_ID_UNUSED |
| 96 | #define BTF_ID_LIST_GLOBAL(name) u32 name[1]; | 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 | #endif /* CONFIG_DEBUG_INFO_BTF */ | 147 | #endif /* CONFIG_DEBUG_INFO_BTF */ |
| 99 | 148 | ||