1# Copyright 2015 syzkaller project authors. All rights reserved.
2# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4# Note these sysctls have radical effect on code paths inside of kernel:
5# net.core.bpf_jit_enable  = { 0, 1, 2 }
6# net.core.bpf_jit_harden  = { 0, 1, 2 }
7
8include <linux/bpf.h>
9
10resource fd_bpf_map[fd]: BPF_PSEUDO_MAP_FD
11resource fd_bpf_prog[fd]
12resource bpf_prog_id[int32]: 0, -1
13resource bpf_map_id[int32]: 0, -1
14
15bpf$MAP_CREATE(cmd const[BPF_MAP_CREATE], arg ptr[in, bpf_map_create_arg], size len[arg]) fd_bpf_map
16bpf$MAP_LOOKUP_ELEM(cmd const[BPF_MAP_LOOKUP_ELEM], arg ptr[in, bpf_map_lookup_arg], size len[arg])
17bpf$MAP_UPDATE_ELEM(cmd const[BPF_MAP_UPDATE_ELEM], arg ptr[in, bpf_map_update_arg], size len[arg])
18bpf$MAP_DELETE_ELEM(cmd const[BPF_MAP_DELETE_ELEM], arg ptr[in, bpf_map_delete_arg], size len[arg])
19bpf$MAP_GET_NEXT_KEY(cmd const[BPF_MAP_GET_NEXT_KEY], arg ptr[in, bpf_map_get_next_arg], size len[arg])
20bpf$PROG_LOAD(cmd const[BPF_PROG_LOAD], arg ptr[in, bpf_prog], size len[arg]) fd_bpf_prog
21bpf$OBJ_PIN_MAP(cmd const[BPF_OBJ_PIN], arg ptr[in, bpf_obj_pin_map], size len[arg])
22bpf$OBJ_PIN_PROG(cmd const[BPF_OBJ_PIN], arg ptr[in, bpf_obj_pin_prog], size len[arg])
23bpf$OBJ_GET_MAP(cmd const[BPF_OBJ_GET], arg ptr[in, bpf_obj_get], size len[arg]) fd_bpf_map
24bpf$OBJ_GET_PROG(cmd const[BPF_OBJ_GET], arg ptr[in, bpf_obj_get], size len[arg]) fd_bpf_prog
25bpf$BPF_PROG_ATTACH(cmd const[BPF_PROG_ATTACH], arg ptr[in, bpf_attach_arg], size len[arg])
26bpf$BPF_PROG_DETACH(cmd const[BPF_PROG_DETACH], arg ptr[in, bpf_detach_arg], size len[arg])
27bpf$BPF_PROG_TEST_RUN(cmd const[BPF_PROG_TEST_RUN], arg ptr[in, bpf_test_prog_arg], size len[arg])
28bpf$BPF_PROG_GET_NEXT_ID(cmd const[BPF_PROG_GET_NEXT_ID], arg ptr[in, int32], size len[arg])
29bpf$BPF_MAP_GET_NEXT_ID(cmd const[BPF_MAP_GET_NEXT_ID], arg ptr[in, int32], size len[arg])
30bpf$BPF_PROG_GET_FD_BY_ID(cmd const[BPF_PROG_GET_FD_BY_ID], arg ptr[in, bpf_prog_id], size len[arg]) fd_bpf_prog
31bpf$BPF_MAP_GET_FD_BY_ID(cmd const[BPF_MAP_GET_FD_BY_ID], arg ptr[in, bpf_map_get_fd_by_id_arg], size len[arg]) fd_bpf_map
32bpf$BPF_GET_PROG_INFO(cmd const[BPF_OBJ_GET_INFO_BY_FD], arg ptr[in, bpf_get_prog_info_arg], size len[arg])
33bpf$BPF_GET_MAP_INFO(cmd const[BPF_OBJ_GET_INFO_BY_FD], arg ptr[in, bpf_get_map_info_arg], size len[arg])
34bpf$BPF_PROG_QUERY(cmd const[BPF_PROG_QUERY], arg ptr[in, bpf_prog_query], size len[arg])
35bpf$BPF_RAW_TRACEPOINT_OPEN(cmd const[BPF_RAW_TRACEPOINT_OPEN], arg ptr[in, bpf_raw_tracepoint], size len[arg]) fd
36
37bpf_map_create_arg {
38	type		flags[bpf_map_type, int32]
39	ksize		int32
40	vsize		int32
41	max		int32
42	flags		flags[map_flags, int32]
43	inner		fd_bpf_map[opt]
44	node		int32
45	map_name	array[const[0, int8], BPF_OBJ_NAME_LEN]
46}
47
48bpf_map_get_fd_by_id_arg {
49	map_id		bpf_map_id
50	next_id		int32
51	open_flags	flags[bpf_open_flags, int32]
52}
53
54bpf_map_lookup_arg {
55	map	fd_bpf_map
56	key	ptr64[in, array[int8]]
57	val	ptr64[out, array[int8]]
58}
59
60bpf_map_update_arg {
61	map	fd_bpf_map
62	key	ptr64[in, array[int8]]
63	val	ptr64[in, array[int8]]
64	flags	flags[bpf_map_flags, int64]
65}
66
67bpf_map_delete_arg {
68	map	fd_bpf_map
69	key	ptr64[in, array[int8]]
70}
71
72bpf_map_get_next_arg {
73	map	fd_bpf_map
74	key	ptr64[in, array[int8]]
75	next	ptr64[out, array[int8]]
76}
77
78bpf_prog {
79	type			flags[bpf_prog_type, int32]
80	ninsn			bytesize8[insns, int32]
81	insns			ptr64[in, bpf_instructions]
82	license			ptr64[in, string[bpf_licenses]]
83	loglev			int32
84	logsize			len[log, int32]
85	log			ptr64[out, array[int8], opt]
86	kern_version		flags[bpf_kern_version, int32]
87	flags			flags[bpf_prog_load_flags, int32]
88	prog_name		array[const[0, int8], BPF_OBJ_NAME_LEN]
89	prog_ifindex		ifindex[opt]
90	expected_attach_type	flags[bpf_attach_type, int32]
91}
92
93bpf_licenses = "GPL", "syzkaller"
94bpf_kern_version = 0x40f00, 0x41000, 0x41100
95
96bpf_instructions [
97	framed	bpf_framed_program
98	raw	array[bpf_insn]
99] [varlen]
100
101bpf_framed_program {
102	initr0	bpf_insn_init_r0
103	body	array[bpf_insn]
104	exit	bpf_insn_exit
105} [packed]
106
107bpf_insn [
108	generic	bpf_insn_generic
109	ldst	bpf_insn_ldst
110	alu	bpf_insn_alu
111	jmp	bpf_insn_jmp
112	call	bpf_insn_call
113	exit	bpf_insn_exit
114	initr0	bpf_insn_init_r0
115	map	bpf_insn_map
116]
117
118bpf_insn_generic {
119	code	int8
120	regs	int8
121	off	int16
122	imm	int32
123}
124
125bpf_insn_ldst {
126	code_class	flags[bpf_ldst_insn, int8:3]
127	code_size	flags[bpf_ldst_size, int8:2]
128	code_mode	flags[bpf_ldst_mode, int8:3]
129	dst		flags[bpf_reg, int8:4]
130	src		flags[bpf_reg, int8:4]
131	off		flags[bpf_insn_offsets, int16]
132	imm		flags[bpf_insn_immediates, int32]
133}
134
135bpf_ldst_insn = BPF_LD, BPF_LDX, BPF_ST, BPF_STX
136bpf_ldst_size = BPF_W0, BPF_H0, BPF_B0, BPF_DW0
137bpf_ldst_mode = BPF_IMM0, BPF_ABS0, BPF_IND0, BPF_MEM0, BPF_XADD0
138
139define BPF_W0	BPF_W >> 3
140define BPF_H0	BPF_H >> 3
141define BPF_B0	BPF_B >> 3
142define BPF_DW0	BPF_DW >> 3
143
144define BPF_IMM0	BPF_IMM >> 5
145define BPF_ABS0	BPF_ABS >> 5
146define BPF_IND0	BPF_IND >> 5
147define BPF_MEM0	BPF_MEM >> 5
148define BPF_XADD0	BPF_XADD >> 5
149
150bpf_insn_alu {
151	code_class	flags[bpf_alu_insn, int8:3]
152	code_s		int8:1
153	code_op		flags[bpf_alu_op, int8:4]
154	dst		flags[bpf_reg, int8:4]
155	src		flags[bpf_reg, int8:4]
156	off		flags[bpf_insn_offsets, int16]
157	imm		flags[bpf_insn_immediates, int32]
158}
159
160bpf_alu_insn = BPF_ALU, BPF_ALU64
161bpf_alu_op = BPF_ADD0, BPF_SUB0, BPF_MUL0, BPF_DIV0, BPF_OR0, BPF_AND0, BPF_LSH0, BPF_RSH0, BPF_NEG0, BPF_MOD0, BPF_XOR0, BPF_MOV0, BPF_ARSH0, BPF_END0
162
163define BPF_ADD0	BPF_ADD >> 4
164define BPF_SUB0	BPF_SUB >> 4
165define BPF_MUL0	BPF_MUL >> 4
166define BPF_DIV0	BPF_DIV >> 4
167define BPF_OR0	BPF_OR >> 4
168define BPF_AND0	BPF_AND >> 4
169define BPF_LSH0	BPF_LSH >> 4
170define BPF_RSH0	BPF_RSH >> 4
171define BPF_NEG0	BPF_NEG >> 4
172define BPF_MOD0	BPF_MOD >> 4
173define BPF_XOR0	BPF_XOR >> 4
174define BPF_MOV0	BPF_MOV >> 4
175define BPF_ARSH0	BPF_ARSH >> 4
176define BPF_END0	BPF_END >> 4
177
178bpf_insn_jmp {
179	code_class	const[BPF_JMP, int8:3]
180	code_s		int8:1
181	code_op		flags[bpf_jmp_op, int8:4]
182	dst		flags[bpf_reg, int8:4]
183	src		flags[bpf_reg, int8:4]
184	off		flags[bpf_insn_offsets, int16]
185	imm		flags[bpf_insn_immediates, int32]
186}
187
188bpf_jmp_op = BPF_JA0, BPF_JEQ0, BPF_JGT0, BPF_JGE0, BPF_JSET0, BPF_JNE0, BPF_JSGT0, BPF_JSGE0, BPF_CALL0, BPF_EXIT0, BPF_JLT0, BPF_JLE0, BPF_JSLT0, BPF_JSLE0
189
190define BPF_JA0	BPF_JA >> 4
191define BPF_JEQ0	BPF_JEQ >> 4
192define BPF_JGT0	BPF_JGT >> 4
193define BPF_JGE0	BPF_JGE >> 4
194define BPF_JSET0	BPF_JSET >> 4
195define BPF_JNE0	BPF_JNE >> 4
196define BPF_JSGT0	BPF_JSGT >> 4
197define BPF_JSGE0	BPF_JSGE >> 4
198define BPF_CALL0	BPF_CALL >> 4
199define BPF_EXIT0	BPF_EXIT >> 4
200define BPF_JLT0	BPF_JLT >> 4
201define BPF_JLE0	BPF_JLE >> 4
202define BPF_JSLT0	BPF_JSLT >> 4
203define BPF_JSLE0	BPF_JSLE >> 4
204
205bpf_insn_call {
206	code	const[bpf_call_code, int8]
207	regs	const[0, int8]
208	off	const[0, int16]
209	func	int32[0:__BPF_FUNC_MAX_ID]
210}
211
212define bpf_call_code	BPF_JMP | BPF_CALL
213
214bpf_insn_exit {
215	code	const[bpf_exit_code, int8]
216	regs	const[0, int8]
217	off	const[0, int16]
218	imm	const[0, int32]
219}
220
221define bpf_exit_code	BPF_JMP | BPF_EXIT
222
223bpf_insn_init_r0 {
224	code	const[bpf_insn_load_imm_dw, int8]
225	dst	const[BPF_REG_0, int8:4]
226	src	const[0, int8:4]
227	off	const[0, int16]
228	imm	int32
229	code2	const[0, int8]
230	regs2	const[0, int8]
231	off2	const[0, int16]
232	imm2	int32
233}
234
235bpf_insn_map {
236	code	const[bpf_insn_load_imm_dw, int8]
237	dst	flags[bpf_reg, int8:4]
238	src	const[BPF_PSEUDO_MAP_FD, int8:4]
239	off	const[0, int16]
240	imm	fd_bpf_map
241	code2	const[0, int8]
242	regs2	const[0, int8]
243	off2	const[0, int16]
244	imm2	const[0, int32]
245}
246
247define bpf_insn_load_imm_dw	BPF_LD | BPF_DW | BPF_IMM
248
249# Slightly prune state space, these values frequently must be 0.
250bpf_insn_offsets = 0, 1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 80, 128, 256, -1, -2, -4, -8, -12, -16, -32, -64
251bpf_insn_immediates = 0, 1, 4, 8, 16, -1, -4, -16
252bpf_reg = BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5, BPF_REG_6, BPF_REG_7, BPF_REG_8, BPF_REG_9, BPF_REG_10
253
254# TODO: these filenames must be on bpf filesystem
255bpf_obj_pin_map {
256	path	ptr64[in, filename]
257	fd	fd_bpf_map
258}
259
260bpf_obj_pin_prog {
261	path	ptr64[in, filename]
262	fd	fd_bpf_prog
263}
264
265bpf_obj_get {
266	path		ptr64[in, filename]
267	fd		const[0, int32]
268	file_flags	flags[bpf_open_flags, int32]
269}
270
271bpf_attach_arg {
272	target_fd	fd_cgroup
273	attach_bpf_fd	fd_bpf_prog
274	type		flags[bpf_attach_type, int32]
275	flags		flags[bpf_attach_flags, int32]
276}
277
278bpf_detach_arg {
279	target	const[0, int32]
280	prog	fd_bpf_prog
281	type	flags[bpf_attach_type, int32]
282	flags	flags[bpf_attach_flags, int32]
283	prog2	const[0, int32]
284}
285
286bpf_test_prog_arg {
287	prog	fd_bpf_prog
288	retval	const[0, int32]
289	insize	len[indata, int32]
290	outsize	len[outdata, int32]
291	indata	ptr64[in, array[int8]]
292	outdata	ptr64[out, array[int8]]
293	repeat	int32
294	dur	const[0, int32]
295}
296
297bpf_get_prog_info_arg {
298	prog	fd_bpf_prog
299	len	len[info, int32]
300	info	ptr64[out, bpf_prog_info]
301}
302
303bpf_prog_info {
304	type			int32
305	id			bpf_prog_id
306	tag			int64
307	jited_prog_len		int32
308	xlated_prog_len		int32
309	jited_prog_insns	int64
310	xlated_prog_insns	int64
311	load_time		int64
312	created_by_uid		int32
313	nr_map_ids		int32
314	map_ids			int64
315	name			array[int8, BPF_OBJ_NAME_LEN]
316} [align_8]
317
318bpf_get_map_info_arg {
319	prog	fd_bpf_map
320	len	len[info, int32]
321	info	ptr64[out, bpf_map_info]
322}
323
324bpf_map_info {
325	type		int32
326	id		bpf_map_id
327	key_size	int32
328	value_size	int32
329	max_entries	int32
330	map_flags	int32
331	name		array[int8, BPF_OBJ_NAME_LEN]
332} [align_8]
333
334bpf_prog_query {
335	target_fd	fd_cgroup
336	attach_type	flags[bpf_prog_query_attach_type, int32]
337	query_flags	flags[bpf_prog_query_flags, int32]
338	attach_flags	int32
339	prog_ids	ptr64[out, array[int32]]
340	prog_cnt	len[prog_ids, int32]
341} [align_8]
342
343bpf_raw_tracepoint {
344	name	ptr64[in, string]
345	prog_fd	fd_bpf_prog
346} [align_8]
347
348bpf_map_type = BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_MAP_TYPE_STACK_TRACE, BPF_MAP_TYPE_CGROUP_ARRAY, BPF_MAP_TYPE_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_ARRAY, BPF_MAP_TYPE_LRU_HASH, BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_ARRAY_OF_MAPS, BPF_MAP_TYPE_HASH_OF_MAPS, BPF_MAP_TYPE_DEVMAP, BPF_MAP_TYPE_SOCKMAP, BPF_MAP_TYPE_CPUMAP
349bpf_map_flags = BPF_ANY, BPF_NOEXIST, BPF_EXIST
350bpf_prog_type = BPF_PROG_TYPE_SOCKET_FILTER, BPF_PROG_TYPE_KPROBE, BPF_PROG_TYPE_SCHED_CLS, BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_TRACEPOINT, BPF_PROG_TYPE_XDP, BPF_PROG_TYPE_PERF_EVENT, BPF_PROG_TYPE_CGROUP_SKB, BPF_PROG_TYPE_CGROUP_SOCK, BPF_PROG_TYPE_LWT_IN, BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SK_SKB, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_PROG_TYPE_SK_MSG, BPF_PROG_TYPE_RAW_TRACEPOINT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR
351map_flags = BPF_F_NO_PREALLOC, BPF_F_NO_COMMON_LRU, BPF_F_NUMA_NODE, BPF_F_RDONLY, BPF_F_WRONLY, BPF_F_STACK_BUILD_ID
352bpf_attach_type = BPF_CGROUP_INET_INGRESS, BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, BPF_SK_SKB_STREAM_PARSER, BPF_SK_SKB_STREAM_VERDICT, BPF_CGROUP_DEVICE, BPF_SK_MSG_VERDICT, BPF_CGROUP_INET4_BIND, BPF_CGROUP_INET6_BIND, BPF_CGROUP_INET4_CONNECT, BPF_CGROUP_INET6_CONNECT, BPF_CGROUP_INET4_POST_BIND, BPF_CGROUP_INET6_POST_BIND
353bpf_prog_load_flags = BPF_F_STRICT_ALIGNMENT
354bpf_attach_flags = BPF_F_ALLOW_OVERRIDE, BPF_F_ALLOW_MULTI
355bpf_prog_query_flags = BPF_F_QUERY_EFFECTIVE
356bpf_prog_query_attach_type = BPF_CGROUP_INET_INGRESS, BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, BPF_CGROUP_DEVICE
357bpf_open_flags = BPF_F_RDONLY, BPF_F_WRONLY
358