History

bpf: Add BTF_SET_START/END macros

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.

Jiri Olsa committed 6 years ago

Commit eae2e831 parent faaf4a75 files · +123 −2Browse files

Unified · Split

5 files
  1. include/linux/bpf.h +4 −0
  2. include/linux/btf_ids.h +50 −1
  3. kernel/bpf/btf.c +14 −0
  4. kernel/bpf/verifier.c +5 −0
  5. tools/include/linux/btf_ids.h +50 −1
include/linux/bpf.h+4−0
@@ -317,6 +317,7 @@ struct bpf_func_proto { · 316 unmodified lines
317317 * for this argument.
318318 */
319319 int *ret_btf_id; /* return value btf_id */
320+ bool (*allowed)(const struct bpf_prog *prog);
320321 };
321322
322323 /* bpf_context is intentionally undefined structure. Pointer to bpf_context is
@@ -1878,4 +1879,7 @@ enum bpf_text_poke_type { · 1555 unmodified lines
18781879 int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
18791880 void *addr1, void *addr2);
18801881
1882+struct btf_id_set;
1883+bool btf_id_set_contains(struct btf_id_set *set, u32 id);
1884+
18811885 #endif /* _LINUX_BPF_H */
include/linux/btf_ids.h+50−1
@@ -3,6 +3,11 @@ · 2 unmodified lines
33 #ifndef _LINUX_BTF_IDS_H
44 #define _LINUX_BTF_IDS_H
55
6+struct btf_id_set {
7+ u32 cnt;
8+ u32 ids[];
9+};
10+
611 #ifdef CONFIG_DEBUG_INFO_BTF
712
813 #include <linux/compiler.h> /* for __PASTE */
@@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines
6267 ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
6368 "." #scope " " #name "; \n" \
6469 #name ":; \n" \
65−".popsection; \n"); \
70+".popsection; \n");
6671
6772 #define BTF_ID_LIST(name) \
6873 __BTF_ID_LIST(name, local) \
@@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines
8893 ".zero 4 \n" \
8994 ".popsection; \n");
9095
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+
91137 #else
92138
93139 #define BTF_ID_LIST(name) static u32 name[5];
94140 #define BTF_ID(prefix, name)
95141 #define BTF_ID_UNUSED
96142 #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)
97146
98147 #endif /* CONFIG_DEBUG_INFO_BTF */
99148
kernel/bpf/btf.c+14−0
@@ -21,6 +21,8 @@ · 20 unmodified lines
2121 #include <linux/btf_ids.h>
2222 #include <linux/skmsg.h>
2323 #include <linux/perf_event.h>
24+#include <linux/bsearch.h>
25+#include <linux/btf_ids.h>
2426 #include <net/sock.h>
2527
2628 /* 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
47624764 {
47634765 return btf->id;
47644766 }
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+}
kernel/bpf/verifier.c+5−0
@@ -4859,6 +4859,11 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn · 4858 unmodified lines
48594859 return -EINVAL;
48604860 }
48614861
4862+ if (fn->allowed && !fn->allowed(env->prog)) {
4863+ verbose(env, "helper call is not allowed in probe\n");
4864+ return -EINVAL;
4865+ }
4866+
48624867 /* With LD_ABS/IND some JITs save/restore skb from r1. */
48634868 changes_data = bpf_helper_changes_pkt_data(fn->func);
48644869 if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) {
tools/include/linux/btf_ids.h+50−1
@@ -3,6 +3,11 @@ · 2 unmodified lines
33 #ifndef _LINUX_BTF_IDS_H
44 #define _LINUX_BTF_IDS_H
55
6+struct btf_id_set {
7+ u32 cnt;
8+ u32 ids[];
9+};
10+
611 #ifdef CONFIG_DEBUG_INFO_BTF
712
813 #include <linux/compiler.h> /* for __PASTE */
@@ -62,7 +67,7 @@ asm( \ · 53 unmodified lines
6267 ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
6368 "." #scope " " #name "; \n" \
6469 #name ":; \n" \
65−".popsection; \n"); \
70+".popsection; \n");
6671
6772 #define BTF_ID_LIST(name) \
6873 __BTF_ID_LIST(name, local) \
@@ -88,12 +93,56 @@ asm( \ · 19 unmodified lines
8893 ".zero 4 \n" \
8994 ".popsection; \n");
9095
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+
91137 #else
92138
93139 #define BTF_ID_LIST(name) static u32 name[5];
94140 #define BTF_ID(prefix, name)
95141 #define BTF_ID_UNUSED
96142 #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)
97146
98147 #endif /* CONFIG_DEBUG_INFO_BTF */
99148

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t