2 * Check bpf syscall decoding.
4 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2015-2019 The strace developers.
8 * SPDX-License-Identifier: GPL-2.0-or-later
21 #ifdef HAVE_LINUX_BPF_H
22 # include <linux/bpf.h>
26 #include "print_fields.h"
29 #include "xlat/bpf_commands.h"
31 #if defined MPERS_IS_m32 || SIZEOF_KERNEL_LONG_T > 4
32 # define BIG_ADDR(addr64_, addr32_) addr64_
33 # define BIG_ADDR_MAYBE(addr_)
34 #elif defined __arm__ || defined __i386__ || defined __mips__ \
35 || defined __powerpc__ || defined __riscv__ || defined __s390__ \
36 || defined __sparc__ || defined __tile__
37 # define BIG_ADDR(addr64_, addr32_) addr64_ " or " addr32_
38 # define BIG_ADDR_MAYBE(addr_) addr_ " or "
40 # define BIG_ADDR(addr64_, addr32_) addr32_
41 # define BIG_ADDR_MAYBE(addr_)
44 #ifndef HAVE_STRUCT_BPF_INSN
54 #define BPF_ATTR_DATA_FIELD(cmd_) struct cmd_ ## _struct cmd_ ## _data
57 BPF_ATTR_DATA_FIELD(BPF_MAP_CREATE);
58 BPF_ATTR_DATA_FIELD(BPF_MAP_LOOKUP_ELEM);
59 BPF_ATTR_DATA_FIELD(BPF_MAP_UPDATE_ELEM);
60 BPF_ATTR_DATA_FIELD(BPF_MAP_DELETE_ELEM);
61 BPF_ATTR_DATA_FIELD(BPF_MAP_GET_NEXT_KEY);
62 BPF_ATTR_DATA_FIELD(BPF_PROG_LOAD);
63 BPF_ATTR_DATA_FIELD(BPF_OBJ_PIN);
64 BPF_ATTR_DATA_FIELD(BPF_PROG_ATTACH);
65 BPF_ATTR_DATA_FIELD(BPF_PROG_DETACH);
66 BPF_ATTR_DATA_FIELD(BPF_PROG_TEST_RUN);
67 BPF_ATTR_DATA_FIELD(BPF_PROG_GET_NEXT_ID);
68 BPF_ATTR_DATA_FIELD(BPF_PROG_GET_FD_BY_ID);
69 BPF_ATTR_DATA_FIELD(BPF_MAP_GET_FD_BY_ID);
70 BPF_ATTR_DATA_FIELD(BPF_OBJ_GET_INFO_BY_FD);
71 BPF_ATTR_DATA_FIELD(BPF_PROG_QUERY);
72 BPF_ATTR_DATA_FIELD(BPF_RAW_TRACEPOINT_OPEN);
73 BPF_ATTR_DATA_FIELD(BPF_BTF_LOAD);
74 BPF_ATTR_DATA_FIELD(BPF_BTF_GET_FD_BY_ID);
75 BPF_ATTR_DATA_FIELD(BPF_TASK_FD_QUERY);
76 BPF_ATTR_DATA_FIELD(BPF_MAP_FREEZE);
80 struct bpf_attr_check {
81 union bpf_attr_data data;
84 void (*init_fn)(struct bpf_attr_check *check);
85 void (*print_fn)(const struct bpf_attr_check *check,
92 const struct bpf_attr_check *checks;
96 static const kernel_ulong_t long_bits = (kernel_ulong_t) 0xfacefeed00000000ULL;
97 static const char *errstr;
98 static unsigned int sizeof_attr = sizeof(union bpf_attr_data);
99 static unsigned int page_size;
100 static unsigned long end_of_page;
103 sys_bpf(kernel_ulong_t cmd, kernel_ulong_t attr, kernel_ulong_t size)
105 long rc = syscall(__NR_bpf, cmd, attr, size);
107 errstr = sprintrc(rc);
110 if (rc != INJECT_RETVAL)
111 error_msg_and_fail("Got a return value of %ld != %d",
114 static char inj_errstr[4096];
116 snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
124 # define print_extra_data(addr_, offs_, size_) \
126 printf("/* bytes %u..%u */ ", (offs_), (size_) + (offs_) - 1); \
127 print_quoted_hex((addr_) + (offs_), (size_)); \
130 # define print_extra_data(addr_, offs_, size_) printf("...")
134 print_bpf_attr(const struct bpf_attr_check *check, unsigned long addr)
137 check->print_fn(check, addr);
139 printf("%s", check->str);
143 test_bpf(const struct bpf_check *cmd_check)
145 const struct bpf_attr_check *check = 0;
146 const union bpf_attr_data *data = 0;
147 unsigned int offset = 0;
150 sys_bpf(cmd_check->cmd, 0, long_bits | sizeof(union bpf_attr_data));
151 printf("bpf(%s, NULL, %u) = %s\n",
152 cmd_check->cmd_str, sizeof_attr, errstr);
155 unsigned long addr = end_of_page - sizeof_attr;
156 sys_bpf(cmd_check->cmd, addr, long_bits);
157 printf("bpf(%s, %#lx, 0) = %s\n",
158 cmd_check->cmd_str, addr, errstr);
160 for (size_t i = 0; i < cmd_check->count; i++) {
161 check = &cmd_check->checks[i];
163 check->init_fn((struct bpf_attr_check *) check);
165 offset = check->size;
167 addr = end_of_page - offset;
168 memcpy((void *) addr, data, offset);
170 /* starting piece of bpf_attr_data */
171 sys_bpf(cmd_check->cmd, addr, offset);
172 printf("bpf(%s, {", cmd_check->cmd_str);
173 print_bpf_attr(check, addr);
174 printf("}, %u) = %s\n", offset, errstr);
176 /* short read of the starting piece */
177 sys_bpf(cmd_check->cmd, addr + 1, offset);
178 printf("bpf(%s, %#lx, %u) = %s\n",
179 cmd_check->cmd_str, addr + 1, offset, errstr);
182 if (offset < sizeof_attr) {
183 /* short read of the whole bpf_attr_data */
184 memcpy((void *) end_of_page - sizeof_attr + 1, data, offset);
185 addr = end_of_page - sizeof_attr + 1;
186 memset((void *) addr + offset, 0, sizeof_attr - offset - 1);
187 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
188 printf("bpf(%s, %#lx, %u) = %s\n",
189 cmd_check->cmd_str, addr, sizeof_attr, errstr);
191 /* the whole bpf_attr_data */
192 memcpy((void *) end_of_page - sizeof_attr, data, offset);
193 addr = end_of_page - sizeof_attr;
194 memset((void *) addr + offset, 0, sizeof_attr - offset);
195 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
196 printf("bpf(%s, {", cmd_check->cmd_str);
197 print_bpf_attr(check, addr);
198 printf("}, %u) = %s\n", sizeof_attr, errstr);
200 /* non-zero bytes after the relevant part */
201 fill_memory_ex((void *) addr + offset,
202 sizeof_attr - offset, '0', 10);
203 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
204 printf("bpf(%s, {", cmd_check->cmd_str);
205 print_bpf_attr(check, addr);
207 print_extra_data((char *) addr, offset,
208 sizeof_attr - offset);
209 printf("}, %u) = %s\n", sizeof_attr, errstr);
212 /* short read of the whole page */
213 memcpy((void *) end_of_page - page_size + 1, data, offset);
214 addr = end_of_page - page_size + 1;
215 memset((void *) addr + offset, 0, page_size - offset - 1);
216 sys_bpf(cmd_check->cmd, addr, page_size);
217 printf("bpf(%s, %#lx, %u) = %s\n",
218 cmd_check->cmd_str, addr, page_size, errstr);
221 memcpy((void *) end_of_page - page_size, data, offset);
222 addr = end_of_page - page_size;
223 memset((void *) addr + offset, 0, page_size - offset);
224 sys_bpf(cmd_check->cmd, addr, page_size);
225 printf("bpf(%s, {", cmd_check->cmd_str);
226 print_bpf_attr(check, addr);
227 printf("}, %u) = %s\n", page_size, errstr);
229 /* non-zero bytes after the whole bpf_attr_data */
230 fill_memory_ex((void *) addr + offset,
231 page_size - offset, '0', 10);
232 sys_bpf(cmd_check->cmd, addr, page_size);
233 printf("bpf(%s, {", cmd_check->cmd_str);
234 print_bpf_attr(check, addr);
236 print_extra_data((char *) addr, offset,
238 printf("}, %u) = %s\n", page_size, errstr);
240 /* more than a page */
241 sys_bpf(cmd_check->cmd, addr, page_size + 1);
242 printf("bpf(%s, %#lx, %u) = %s\n",
243 cmd_check->cmd_str, addr, page_size + 1, errstr);
247 init_BPF_MAP_CREATE_attr7(struct bpf_attr_check *check)
249 struct BPF_MAP_CREATE_struct *attr = &check->data.BPF_MAP_CREATE_data;
250 attr->map_ifindex = ifindex_lo();
253 static struct bpf_attr_check BPF_MAP_CREATE_checks[] = {
255 .data = { .BPF_MAP_CREATE_data = { .map_type = 2 } },
256 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_type),
257 .str = "map_type=BPF_MAP_TYPE_ARRAY, key_size=0, value_size=0"
261 .data = { .BPF_MAP_CREATE_data = {
268 .numa_node = 3141592653,
269 .map_name = "0123456789abcde",
271 .size = offsetof(struct BPF_MAP_CREATE_struct, map_name) + 8,
272 .str = "map_type=BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, key_size=4"
273 ", value_size=8, max_entries=256"
274 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NO_COMMON_LRU"
275 "|BPF_F_NUMA_NODE|BPF_F_RDONLY|BPF_F_WRONLY"
276 "|BPF_F_STACK_BUILD_ID"
278 ", numa_node=3141592653"
279 ", map_name=\"0123456\"...",
283 .data = { .BPF_MAP_CREATE_data = {
285 .key_size = 0xface1e55,
286 .value_size = 0xbadc0ded,
287 .max_entries = 0xbeefcafe,
288 .map_flags = 0xfffffc00,
289 .inner_map_fd = 2718281828,
292 .map_ifindex = 3141592653,
294 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
295 .str = "map_type=0x19 /* BPF_MAP_TYPE_??? */"
296 ", key_size=4207812181, value_size=3134983661"
297 ", max_entries=3203386110"
298 ", map_flags=0xfffffc00 /* BPF_F_??? */"
299 ", inner_map_fd=-1576685468"
300 ", map_name=\"\", map_ifindex=3141592653",
304 .data = { .BPF_MAP_CREATE_data = {
305 .map_type = 0xdeadf00d,
306 .key_size = 0xface1e55,
307 .value_size = 0xbadc0ded,
308 .max_entries = 0xbeefcafe,
309 .map_flags = 0xc0dedead,
310 .inner_map_fd = 2718281828,
313 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_flags),
314 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
315 ", key_size=4207812181, value_size=3134983661"
316 ", max_entries=3203386110"
317 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
318 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
319 "|BPF_F_RDONLY_PROG|BPF_F_CLONE|0xc0dedc00",
322 .data = { .BPF_MAP_CREATE_data = {
323 .map_type = 0xdeadf00d,
324 .key_size = 0xface1e55,
325 .value_size = 0xbadc0ded,
326 .max_entries = 0xbeefcafe,
327 .map_flags = 0xc0dedead,
328 .inner_map_fd = 2718281828,
331 .size = offsetofend(struct BPF_MAP_CREATE_struct, inner_map_fd),
332 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
333 ", key_size=4207812181, value_size=3134983661"
334 ", max_entries=3203386110"
335 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
336 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
337 "|BPF_F_RDONLY_PROG|BPF_F_CLONE|0xc0dedc00"
338 ", inner_map_fd=-1576685468",
341 .data = { .BPF_MAP_CREATE_data = {
342 .map_type = 0xdeadf00d,
343 .key_size = 0xface1e55,
344 .value_size = 0xbadc0ded,
345 .max_entries = 0xbeefcafe,
346 .map_flags = 0xc0dedead,
347 .inner_map_fd = 2718281828,
350 .size = offsetofend(struct BPF_MAP_CREATE_struct, numa_node),
351 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
352 ", key_size=4207812181, value_size=3134983661"
353 ", max_entries=3203386110"
354 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
355 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
356 "|BPF_F_RDONLY_PROG|BPF_F_CLONE|0xc0dedc00"
357 ", inner_map_fd=-1576685468"
358 ", numa_node=4294967295 /* NUMA_NO_NODE */",
361 .data = { .BPF_MAP_CREATE_data = {
362 .map_type = 0xdeadf00d,
363 .key_size = 0xface1e55,
364 .value_size = 0xbadc0ded,
365 .max_entries = 0xbeefcafe,
366 .map_flags = 0xc0dedead,
367 .inner_map_fd = 2718281828,
369 .map_name = "fedcba9876543210",
371 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_name),
372 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
373 ", key_size=4207812181, value_size=3134983661"
374 ", max_entries=3203386110"
375 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
376 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
377 "|BPF_F_RDONLY_PROG|BPF_F_CLONE|0xc0dedc00"
378 ", inner_map_fd=-1576685468"
379 ", numa_node=4294967295 /* NUMA_NO_NODE */"
380 ", map_name=\"fedcba987654321\"...",
383 .data = { .BPF_MAP_CREATE_data = {
384 .map_type = 0xdeadf00d,
385 .key_size = 0xface1e55,
386 .value_size = 0xbadc0ded,
387 .max_entries = 0xbeefcafe,
388 .map_flags = 0xc0dedead,
389 .inner_map_fd = 2718281828,
391 .map_name = "0123456789abcde",
393 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
394 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
395 ", key_size=4207812181, value_size=3134983661"
396 ", max_entries=3203386110"
397 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
398 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
399 "|BPF_F_RDONLY_PROG|BPF_F_CLONE|0xc0dedc00"
400 ", inner_map_fd=-1576685468"
401 ", numa_node=4294967295 /* NUMA_NO_NODE */"
402 ", map_name=\"0123456789abcde\""
403 ", map_ifindex=" IFINDEX_LO_STR,
404 .init_fn = init_BPF_MAP_CREATE_attr7,
407 .data = { .BPF_MAP_CREATE_data = {
408 .btf_fd = 0xbadc0ded,
409 .btf_key_type_id = 0xfacefeed,
410 .btf_value_type_id = 0xcafef00d
412 .size = offsetofend(struct BPF_MAP_CREATE_struct,
414 .str = "map_type=BPF_MAP_TYPE_UNSPEC"
422 ", btf_fd=-1159983635"
423 ", btf_key_type_id=4207869677"
424 ", btf_value_type_id=3405705229"
428 static const struct bpf_attr_check BPF_MAP_LOOKUP_ELEM_checks[] = {
430 .data = { .BPF_MAP_LOOKUP_ELEM_data = { .map_fd = -1 } },
431 .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, map_fd),
432 .str = "map_fd=-1, key=NULL, value=NULL"
435 .data = { .BPF_MAP_LOOKUP_ELEM_data = {
440 .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, value),
441 .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
445 #define BPF_MAP_LOOKUP_AND_DELETE_ELEM_checks BPF_MAP_LOOKUP_ELEM_checks
447 static const struct bpf_attr_check BPF_MAP_UPDATE_ELEM_checks[] = {
449 .data = { .BPF_MAP_UPDATE_ELEM_data = { .map_fd = -1 } },
450 .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, map_fd),
451 .str = "map_fd=-1, key=NULL, value=NULL, flags=BPF_ANY"
454 .data = { .BPF_MAP_UPDATE_ELEM_data = {
460 .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, flags),
461 .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
466 static const struct bpf_attr_check BPF_MAP_DELETE_ELEM_checks[] = {
468 .data = { .BPF_MAP_DELETE_ELEM_data = { .map_fd = -1 } },
469 .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, map_fd),
470 .str = "map_fd=-1, key=NULL"
473 .data = { .BPF_MAP_DELETE_ELEM_data = {
477 .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, key),
478 .str = "map_fd=-1, key=0xdeadbeef"
482 static const struct bpf_attr_check BPF_MAP_GET_NEXT_KEY_checks[] = {
484 .data = { .BPF_MAP_GET_NEXT_KEY_data = { .map_fd = -1 } },
485 .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, map_fd),
486 .str = "map_fd=-1, key=NULL, next_key=NULL"
489 .data = { .BPF_MAP_GET_NEXT_KEY_data = {
492 .next_key = 0xbadc0ded
494 .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, next_key),
495 .str = "map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded"
499 static const struct bpf_attr_check BPF_MAP_FREEZE_checks[] = {
501 .data = { .BPF_MAP_FREEZE_data = { .map_fd = -1 } },
502 .size = offsetofend(struct BPF_MAP_FREEZE_struct, map_fd),
507 static const struct bpf_insn insns[] = {
516 static const char license[] = "GPL";
517 static const char pathname[] = "/sys/fs/bpf/foo/bar";
519 static char *log_buf;
521 * This has to be a macro, otherwise the compiler complains that
522 * initializer element is not constant.
524 #define log_buf_size 4096U
530 log_buf = tail_alloc(log_buf_size);
535 get_log_buf_tail(void)
537 return get_log_buf() + log_buf_size;
542 "[{code=BPF_JMP|BPF_K|BPF_EXIT, dst_reg=BPF_REG_10" \
543 ", src_reg=0xb /* BPF_REG_??? */, off=%d, imm=%#x}]"
544 # define INSNS_ARG insns[0].off, insns[0].imm
546 # define INSNS_FMT "%p"
547 # define INSNS_ARG insns
551 init_BPF_PROG_LOAD_attr3(struct bpf_attr_check *check)
553 struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
555 attr->insns = (uintptr_t) insns;
556 attr->license = (uintptr_t) license;
557 attr->log_buf = (uintptr_t) get_log_buf_tail();
561 print_BPF_PROG_LOAD_attr3(const struct bpf_attr_check *check, unsigned long addr)
563 printf("prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=%u"
564 ", insns=" INSNS_FMT ", license=\"%s\", log_level=2718281828"
565 ", log_size=%u, log_buf=%p"
566 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
567 ", prog_flags=0x10 /* BPF_F_??? */"
568 ", prog_name=\"0123456789abcde\"..., prog_ifindex=3203399405",
569 (unsigned int) ARRAY_SIZE(insns), INSNS_ARG, license,
570 log_buf_size, get_log_buf_tail());
574 init_BPF_PROG_LOAD_attr4(struct bpf_attr_check *check)
576 struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
578 attr->insns = (uintptr_t) insns;
579 attr->license = (uintptr_t) license;
580 attr->log_buf = (uintptr_t) get_log_buf();
581 attr->prog_ifindex = ifindex_lo();
583 strncpy(log_buf, "log test", 9);
587 print_BPF_PROG_LOAD_attr4(const struct bpf_attr_check *check, unsigned long addr)
589 printf("prog_type=BPF_PROG_TYPE_UNSPEC, insn_cnt=%u, insns=" INSNS_FMT
590 ", license=\"%s\", log_level=2718281828, log_size=4"
591 ", log_buf=\"log \"..."
592 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
593 ", prog_flags=BPF_F_STRICT_ALIGNMENT|BPF_F_ANY_ALIGNMENT"
594 "|BPF_F_TEST_RND_HI32|BPF_F_TEST_STATE_FREQ|0x10"
595 ", prog_name=\"0123456789abcde\"..., prog_ifindex=%s"
596 ", expected_attach_type=BPF_CGROUP_INET6_BIND",
597 (unsigned int) ARRAY_SIZE(insns), INSNS_ARG,
598 license, IFINDEX_LO_STR);
601 static struct bpf_attr_check BPF_PROG_LOAD_checks[] = {
603 .data = { .BPF_PROG_LOAD_data = { .prog_type = 1 } },
604 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_type),
605 .str = "prog_type=BPF_PROG_TYPE_SOCKET_FILTER"
606 ", insn_cnt=0, insns=NULL, license=NULL"
609 .data = { .BPF_PROG_LOAD_data = {
611 .insn_cnt = 0xbadc0ded,
615 .log_size = 3141592653U,
617 .kern_version = 0xcafef00d,
620 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_flags),
621 .str = "prog_type=0x19 /* BPF_PROG_TYPE_??? */"
622 ", insn_cnt=3134983661, insns=NULL, license=NULL"
623 ", log_level=42, log_size=3141592653, log_buf=NULL"
624 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
628 .data = { .BPF_PROG_LOAD_data = {
630 .insn_cnt = 0xbadc0ded,
631 .insns = 0xffffffff00000000,
632 .license = 0xffffffff00000000,
633 .log_level = 2718281828U,
634 .log_size = log_buf_size,
635 .log_buf = 0xffffffff00000000,
636 .kern_version = 0xcafef00d,
638 .prog_name = "fedcba987654321",
640 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_name),
641 .str = "prog_type=BPF_PROG_TYPE_SK_REUSEPORT"
642 ", insn_cnt=3134983661"
643 ", insns=" BIG_ADDR("0xffffffff00000000", "NULL")
644 ", license=" BIG_ADDR("0xffffffff00000000", "NULL")
645 ", log_level=2718281828, log_size=4096"
646 ", log_buf=" BIG_ADDR("0xffffffff00000000", "NULL")
647 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
648 ", prog_flags=BPF_F_STRICT_ALIGNMENT"
649 ", prog_name=\"fedcba987654321\"",
652 .data = { .BPF_PROG_LOAD_data = {
654 .insn_cnt = ARRAY_SIZE(insns),
655 .log_level = 2718281828U,
656 .log_size = log_buf_size,
657 .kern_version = 0xcafef00d,
659 .prog_name = "0123456789abcdef",
660 .prog_ifindex = 0xbeeffeed,
662 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_ifindex),
663 .init_fn = init_BPF_PROG_LOAD_attr3,
664 .print_fn = print_BPF_PROG_LOAD_attr3
667 .data = { .BPF_PROG_LOAD_data = {
669 .insn_cnt = ARRAY_SIZE(insns),
670 .log_level = 2718281828U,
672 .kern_version = 0xcafef00d,
674 .prog_name = "0123456789abcdef",
675 .expected_attach_type = 9,
677 .size = offsetofend(struct BPF_PROG_LOAD_struct,
678 expected_attach_type),
679 .init_fn = init_BPF_PROG_LOAD_attr4,
680 .print_fn = print_BPF_PROG_LOAD_attr4
683 .data = { .BPF_PROG_LOAD_data = {
685 .expected_attach_type = 17,
686 .prog_btf_fd = 0xbadc0ded,
687 .func_info_rec_size = 0xdad1bef2,
688 .func_info = 0xfac1fed2fac3fed4,
689 .func_info_cnt = 0xdad3bef4,
690 .line_info_rec_size = 0xdad5bef6,
691 .line_info = 0xfac5fed5fac7fed8,
692 .line_info_cnt = 0xdad7bef8
694 .size = offsetofend(struct BPF_PROG_LOAD_struct,
696 .str = "prog_type=BPF_PROG_TYPE_UNSPEC"
703 ", kern_version=KERNEL_VERSION(0, 0, 0)"
704 ", prog_flags=BPF_F_ANY_ALIGNMENT"
707 ", expected_attach_type=BPF_FLOW_DISSECTOR"
708 ", prog_btf_fd=-1159983635"
709 ", func_info_rec_size=3671178994"
710 ", func_info=0xfac1fed2fac3fed4"
711 ", func_info_cnt=3671310068"
712 ", line_info_rec_size=3671441142"
713 ", line_info=0xfac5fed5fac7fed8"
714 ", line_info_cnt=3671572216"
719 init_BPF_OBJ_PIN_attr(struct bpf_attr_check *check)
721 struct BPF_OBJ_PIN_struct *attr = &check->data.BPF_OBJ_PIN_data;
722 attr->pathname = (uintptr_t) pathname;
725 static struct bpf_attr_check BPF_OBJ_PIN_checks[] = {
727 .data = { .BPF_OBJ_PIN_data = { .pathname = 0 } },
728 .size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
729 .str = "pathname=NULL, bpf_fd=0"
732 .data = { .BPF_OBJ_PIN_data = {
733 .pathname = 0xFFFFFFFFFFFFFFFFULL
735 .size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
736 .str = "pathname=" BIG_ADDR("0xffffffffffffffff", "0xffffffff")
740 .data = { .BPF_OBJ_PIN_data = { .bpf_fd = -1 } },
741 .size = offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd),
742 .init_fn = init_BPF_OBJ_PIN_attr,
743 .str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
746 .data = { .BPF_OBJ_PIN_data = {
750 .size = offsetofend(struct BPF_OBJ_PIN_struct, file_flags),
751 .init_fn = init_BPF_OBJ_PIN_attr,
752 .str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
753 ", file_flags=BPF_F_RDONLY|BPF_F_WRONLY"
757 #define BPF_OBJ_GET_checks BPF_OBJ_PIN_checks
759 static const struct bpf_attr_check BPF_PROG_ATTACH_checks[] = {
761 .data = { .BPF_PROG_ATTACH_data = { .target_fd = -1 } },
762 .size = offsetofend(struct BPF_PROG_ATTACH_struct, target_fd),
763 .str = "target_fd=-1, attach_bpf_fd=0"
764 ", attach_type=BPF_CGROUP_INET_INGRESS, attach_flags=0"
767 .data = { .BPF_PROG_ATTACH_data = {
773 .size = offsetofend(struct BPF_PROG_ATTACH_struct, attach_flags),
774 .str = "target_fd=-1, attach_bpf_fd=-2"
775 ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
776 ", attach_flags=BPF_F_ALLOW_OVERRIDE"
781 static const struct bpf_attr_check BPF_PROG_DETACH_checks[] = {
783 .data = { .BPF_PROG_DETACH_data = { .target_fd = -1 } },
784 .size = offsetofend(struct BPF_PROG_DETACH_struct, target_fd),
785 .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS"
788 .data = { .BPF_PROG_DETACH_data = {
792 .size = offsetofend(struct BPF_PROG_DETACH_struct, attach_type),
793 .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_SOCK_CREATE"
797 static const struct bpf_attr_check BPF_PROG_TEST_RUN_checks[] = {
799 .data = { .BPF_PROG_TEST_RUN_data = { .prog_fd = -1 } },
800 .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, prog_fd),
801 .str = "test={prog_fd=-1, retval=0, data_size_in=0"
802 ", data_size_out=0, data_in=NULL, data_out=NULL"
803 ", repeat=0, duration=0}"
806 .data = { .BPF_PROG_TEST_RUN_data = {
808 .retval = 0xfac1fed2,
809 .data_size_in = 0xfac3fed4,
810 .data_size_out = 0xfac5fed6,
811 .data_in = (uint64_t) 0xfacef11dbadc2dedULL,
812 .data_out = (uint64_t) 0xfacef33dbadc4dedULL,
813 .repeat = 0xfac7fed8,
814 .duration = 0xfac9feda
816 .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, duration),
817 .str = "test={prog_fd=-1, retval=4207017682"
818 ", data_size_in=4207148756, data_size_out=4207279830"
819 ", data_in=0xfacef11dbadc2ded"
820 ", data_out=0xfacef33dbadc4ded"
821 ", repeat=4207410904, duration=4207541978}"
824 .data = { .BPF_PROG_TEST_RUN_data = {
826 .retval = 0xfac1fed2,
827 .data_size_in = 0xfac3fed4,
828 .data_size_out = 0xfac5fed6,
829 .data_in = (uint64_t) 0xfacef11dbadc2dedULL,
830 .data_out = (uint64_t) 0xfacef33dbadc4dedULL,
831 .repeat = 0xfac7fed8,
832 .duration = 0xfac9feda,
833 .ctx_size_in = 0xfacbfedc,
834 .ctx_size_out = 0xfacdfede,
835 .ctx_in = (uint64_t) 0xfacef55dbadc6dedULL,
836 .ctx_out = (uint64_t) 0xfacef77dbadc8dedULL
838 .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, ctx_out),
839 .str = "test={prog_fd=-1, retval=4207017682"
840 ", data_size_in=4207148756, data_size_out=4207279830"
841 ", data_in=0xfacef11dbadc2ded"
842 ", data_out=0xfacef33dbadc4ded"
843 ", repeat=4207410904"
844 ", duration=4207541978"
845 ", ctx_size_in=4207673052"
846 ", ctx_size_out=4207804126"
847 ", ctx_in=0xfacef55dbadc6ded"
848 ", ctx_out=0xfacef77dbadc8ded}"
852 static const struct bpf_attr_check BPF_PROG_GET_NEXT_ID_checks[] = {
854 .data = { .BPF_PROG_GET_NEXT_ID_data = {
855 .start_id = 0xdeadbeef
857 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, start_id),
858 .str = "start_id=3735928559, next_id=0"
861 .data = { .BPF_PROG_GET_NEXT_ID_data = {
862 .start_id = 0xdeadbeef
867 "3724541952" /* 0xde000000 */
869 "239" /* 0x000000ef */
874 .data = { .BPF_PROG_GET_NEXT_ID_data = {
875 .start_id = 0xbadc0ded,
876 .next_id = 0xcafef00d
878 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id),
879 .str = "start_id=3134983661, next_id=3405705229"
882 .data = { .BPF_PROG_GET_NEXT_ID_data = {
883 .start_id = 0xbadc0ded,
884 .next_id = 0xcafef00d,
885 .open_flags = 0xffffff27
887 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, open_flags),
888 .str = "start_id=3134983661, next_id=3405705229"
889 ", open_flags=0xffffff27 /* BPF_F_??? */"
893 #define BPF_MAP_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
895 static const struct bpf_attr_check BPF_PROG_GET_FD_BY_ID_checks[] = {
897 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
898 .prog_id = 0xdeadbeef
900 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, prog_id),
901 .str = "prog_id=3735928559, next_id=0"
904 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
905 .prog_id = 0xbadc0ded,
906 .next_id = 0xcafef00d
908 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, next_id),
909 .str = "prog_id=3134983661, next_id=3405705229"
912 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
913 .prog_id = 0xbadc0ded,
914 .next_id = 0xcafef00d,
915 .open_flags = 0xffffff27
917 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, open_flags),
918 .str = "prog_id=3134983661, next_id=3405705229"
919 ", open_flags=0xffffff27 /* BPF_F_??? */"
923 static const struct bpf_attr_check BPF_MAP_GET_FD_BY_ID_checks[] = {
925 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
928 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, map_id),
929 .str = "map_id=3735928559, next_id=0"
932 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
933 .map_id = 0xbadc0ded,
934 .next_id = 0xcafef00d
936 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, next_id),
937 .str = "map_id=3134983661, next_id=3405705229"
940 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
941 .map_id = 0xbadc0ded,
942 .next_id = 0xcafef00d,
943 .open_flags = 0xffffff27
945 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, open_flags),
946 .str = "map_id=3134983661, next_id=3405705229"
947 ", open_flags=0xffffff27 /* BPF_F_??? */"
951 static const struct bpf_attr_check BPF_OBJ_GET_INFO_BY_FD_checks[] = {
953 .data = { .BPF_OBJ_GET_INFO_BY_FD_data = { .bpf_fd = -1 } },
954 .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, bpf_fd),
955 .str = "info={bpf_fd=-1, info_len=0, info=NULL}"
958 .data = { .BPF_OBJ_GET_INFO_BY_FD_data = {
960 .info_len = 0xdeadbeef,
961 .info = (uint64_t) 0xfacefeedbadc0dedULL
963 .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, info),
964 .str = "info={bpf_fd=-1, info_len=3735928559"
965 ", info=0xfacefeedbadc0ded}"
970 static uint32_t prog_load_ids[] = { 0, 1, 0xffffffff, 2718281828, };
971 uint32_t *prog_load_ids_ptr;
974 init_BPF_PROG_QUERY_attr4(struct bpf_attr_check *check)
976 struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
978 if (!prog_load_ids_ptr)
979 prog_load_ids_ptr = tail_memdup(prog_load_ids,
980 sizeof(prog_load_ids));
982 attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
983 attr->prog_cnt = ARRAY_SIZE(prog_load_ids);
987 print_BPF_PROG_QUERY_attr4(const struct bpf_attr_check *check, unsigned long addr)
989 printf("query={target_fd=-1153374643"
990 ", attach_type=0xfeedface /* BPF_??? */"
991 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
992 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
993 #if defined(INJECT_RETVAL) && INJECT_RETVAL > 0
994 ", prog_ids=[0, 1, 4294967295, 2718281828], prog_cnt=4}"
996 ", prog_ids=%p, prog_cnt=4}", prog_load_ids_ptr
1002 init_BPF_PROG_QUERY_attr5(struct bpf_attr_check *check)
1004 struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
1006 if (!prog_load_ids_ptr)
1007 prog_load_ids_ptr = tail_memdup(prog_load_ids,
1008 sizeof(prog_load_ids));
1010 attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
1011 attr->prog_cnt = ARRAY_SIZE(prog_load_ids) + 1;
1015 print_BPF_PROG_QUERY_attr5(const struct bpf_attr_check *check, unsigned long addr)
1017 printf("query={target_fd=-1153374643"
1018 ", attach_type=0xfeedface /* BPF_??? */"
1019 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
1020 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
1021 #if defined(INJECT_RETVAL) && INJECT_RETVAL > 0
1022 ", prog_ids=[0, 1, 4294967295, 2718281828, ... /* %p */]"
1024 prog_load_ids_ptr + ARRAY_SIZE(prog_load_ids)
1026 ", prog_ids=%p, prog_cnt=5}", prog_load_ids_ptr
1031 static struct bpf_attr_check BPF_PROG_QUERY_checks[] = {
1033 .data = { .BPF_PROG_QUERY_data = { .target_fd = -1 } },
1034 .size = offsetofend(struct BPF_PROG_QUERY_struct, target_fd),
1035 .str = "query={target_fd=-1"
1036 ", attach_type=BPF_CGROUP_INET_INGRESS, query_flags=0"
1037 ", attach_flags=0, prog_ids=NULL, prog_cnt=0}",
1040 .data = { .BPF_PROG_QUERY_data = {
1041 .target_fd = 3141592653U,
1046 .size = offsetofend(struct BPF_PROG_QUERY_struct, attach_flags),
1047 .str = "query={target_fd=-1153374643"
1048 ", attach_type=BPF_LIRC_MODE2"
1049 ", query_flags=BPF_F_QUERY_EFFECTIVE"
1050 ", attach_flags=BPF_F_ALLOW_OVERRIDE|BPF_F_ALLOW_MULTI"
1051 ", prog_ids=NULL, prog_cnt=0}",
1054 .data = { .BPF_PROG_QUERY_data = {
1055 .target_fd = 3141592653U,
1057 .query_flags = 0xfffffffe,
1058 .attach_flags = 0xfffffffc,
1059 .prog_ids = 0xffffffffffffffffULL,
1060 .prog_cnt = 2718281828,
1062 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1063 .str = "query={target_fd=-1153374643"
1064 ", attach_type=0x17 /* BPF_??? */"
1065 ", query_flags=0xfffffffe /* BPF_F_QUERY_??? */"
1066 ", attach_flags=0xfffffffc /* BPF_F_??? */"
1068 BIG_ADDR("0xffffffffffffffff", "0xffffffff")
1069 ", prog_cnt=2718281828}",
1072 .data = { .BPF_PROG_QUERY_data = {
1073 .target_fd = 3141592653U,
1074 .attach_type = 0xfeedface,
1075 .query_flags = 0xdeadf00d,
1076 .attach_flags = 0xbeefcafe,
1077 .prog_ids = 0xffffffffffffffffULL,
1080 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1081 .str = "query={target_fd=-1153374643"
1082 ", attach_type=0xfeedface /* BPF_??? */"
1083 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
1084 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
1085 ", prog_ids=" BIG_ADDR_MAYBE("0xffffffffffffffff") "[]"
1089 .data = { .BPF_PROG_QUERY_data = {
1090 .target_fd = 3141592653U,
1091 .attach_type = 0xfeedface,
1092 .query_flags = 0xdeadf00d,
1093 .attach_flags = 0xbeefcafe,
1095 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1096 .init_fn = init_BPF_PROG_QUERY_attr4,
1097 .print_fn = print_BPF_PROG_QUERY_attr4,
1100 .data = { .BPF_PROG_QUERY_data = {
1101 .target_fd = 3141592653U,
1102 .attach_type = 0xfeedface,
1103 .query_flags = 0xdeadf00d,
1104 .attach_flags = 0xbeefcafe,
1106 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1107 .init_fn = init_BPF_PROG_QUERY_attr5,
1108 .print_fn = print_BPF_PROG_QUERY_attr5,
1114 init_BPF_RAW_TRACEPOINT_attr2(struct bpf_attr_check *check)
1116 /* TODO: test the 128 byte limit */
1117 static const char tp_name[] = "0123456789qwertyuiop0123456789qwe";
1119 struct BPF_RAW_TRACEPOINT_OPEN_struct *attr =
1120 &check->data.BPF_RAW_TRACEPOINT_OPEN_data;
1122 attr->name = (uintptr_t) tp_name;
1125 static struct bpf_attr_check BPF_RAW_TRACEPOINT_OPEN_checks[] = {
1127 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = { .name = 0 } },
1128 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1130 .str = "raw_tracepoint={name=NULL, prog_fd=0}",
1133 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
1134 .name = 0xffffffff00000000ULL,
1135 .prog_fd = 0xdeadbeef,
1137 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1139 .str = "raw_tracepoint="
1140 "{name=" BIG_ADDR("0xffffffff00000000", "NULL")
1141 ", prog_fd=-559038737}",
1144 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
1145 .prog_fd = 0xdeadbeef,
1147 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1149 .init_fn = init_BPF_RAW_TRACEPOINT_attr2,
1150 .str = "raw_tracepoint="
1151 "{name=\"0123456789qwertyuiop0123456789qw\"..."
1152 ", prog_fd=-559038737}",
1157 init_BPF_BTF_LOAD_attr(struct bpf_attr_check *check)
1159 static const char sample_btf_data[] = "bPf\0daTum";
1161 static char *btf_data;
1163 btf_data = tail_memdup(sample_btf_data,
1164 sizeof(sample_btf_data) - 1);
1166 struct BPF_BTF_LOAD_struct *attr = &check->data.BPF_BTF_LOAD_data;
1167 attr->btf = (uintptr_t) btf_data;
1170 static struct bpf_attr_check BPF_BTF_LOAD_checks[] = {
1172 .data = { .BPF_BTF_LOAD_data = { .btf = 0 } },
1173 .size = offsetofend(struct BPF_BTF_LOAD_struct, btf),
1174 .str = "btf=NULL, btf_log_buf=NULL, btf_size=0"
1175 ", btf_log_size=0, btf_log_level=0"
1178 .data = { .BPF_BTF_LOAD_data = {
1179 .btf_log_buf = 0xfacefeeddeadbeefULL,
1181 .btf_log_size = -1U,
1184 .size = offsetofend(struct BPF_BTF_LOAD_struct, btf_log_level),
1185 .init_fn = init_BPF_BTF_LOAD_attr,
1186 .str = "btf=\"bPf\\0daTum\""
1187 ", btf_log_buf=0xfacefeeddeadbeef"
1189 ", btf_log_size=4294967295"
1190 ", btf_log_level=42"
1194 static const struct bpf_attr_check BPF_BTF_GET_FD_BY_ID_checks[] = {
1196 .data = { .BPF_BTF_GET_FD_BY_ID_data = { .btf_id = 0xdeadbeef } },
1197 .size = offsetofend(struct BPF_BTF_GET_FD_BY_ID_struct, btf_id),
1198 .str = "btf_id=3735928559"
1202 static const struct bpf_attr_check BPF_TASK_FD_QUERY_checks[] = {
1204 .data = { .BPF_TASK_FD_QUERY_data = { .pid = 0xdeadbeef } },
1205 .size = offsetofend(struct BPF_TASK_FD_QUERY_struct, pid),
1206 .str = "task_fd_query={pid=3735928559, fd=0, flags=0"
1207 ", buf_len=0, buf=NULL, prog_id=0"
1208 ", fd_type=BPF_FD_TYPE_RAW_TRACEPOINT"
1209 ", probe_offset=0, probe_addr=0}"
1212 .data = { .BPF_TASK_FD_QUERY_data = {
1215 .flags = 0xfacefeed,
1216 .buf_len = 0xdefaced,
1217 .buf = 0xfffffffffffffffe,
1218 .prog_id = 0xbadc0ded,
1220 .probe_offset = 0xfac1fed2fac3fed4,
1221 .probe_addr = 0xfac5fed5fac7fed8
1223 .size = offsetofend(struct BPF_TASK_FD_QUERY_struct, probe_addr),
1224 .str = "task_fd_query={pid=3405705229"
1226 ", flags=4207869677"
1227 ", buf_len=233811181"
1228 ", buf=" BIG_ADDR("0xfffffffffffffffe", "0xfffffffe")
1229 ", prog_id=3134983661"
1230 ", fd_type=BPF_FD_TYPE_URETPROBE"
1231 ", probe_offset=0xfac1fed2fac3fed4"
1232 ", probe_addr=0xfac5fed5fac7fed8}"
1240 cmd_##_checks, ARRAY_SIZE(cmd_##_checks), \
1242 /* End of CHK definition */
1247 static const struct bpf_check checks[] = {
1248 CHK(BPF_MAP_CREATE),
1249 CHK(BPF_MAP_LOOKUP_ELEM),
1250 CHK(BPF_MAP_UPDATE_ELEM),
1251 CHK(BPF_MAP_DELETE_ELEM),
1252 CHK(BPF_MAP_GET_NEXT_KEY),
1256 CHK(BPF_PROG_ATTACH),
1257 CHK(BPF_PROG_DETACH),
1258 CHK(BPF_PROG_TEST_RUN),
1259 CHK(BPF_PROG_GET_NEXT_ID),
1260 CHK(BPF_MAP_GET_NEXT_ID),
1261 CHK(BPF_PROG_GET_FD_BY_ID),
1262 CHK(BPF_MAP_GET_FD_BY_ID),
1263 CHK(BPF_OBJ_GET_INFO_BY_FD),
1264 CHK(BPF_PROG_QUERY),
1265 CHK(BPF_RAW_TRACEPOINT_OPEN),
1267 CHK(BPF_BTF_GET_FD_BY_ID),
1268 CHK(BPF_TASK_FD_QUERY),
1269 CHK(BPF_MAP_LOOKUP_AND_DELETE_ELEM),
1270 CHK(BPF_MAP_FREEZE),
1273 page_size = get_page_size();
1274 end_of_page = (unsigned long) tail_alloc(1) + 1;
1276 for (size_t i = 0; i < ARRAY_SIZE(checks); i++)
1277 test_bpf(checks + i);
1279 sys_bpf(0xfacefeed, 0, (kernel_ulong_t) 0xfacefeedbadc0dedULL);
1280 printf("bpf(0xfacefeed /* BPF_??? */, NULL, %u) = %s\n",
1281 0xbadc0dedu, errstr);
1283 sys_bpf(0xfacefeed, end_of_page, 40);
1284 printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
1285 end_of_page, errstr);
1287 puts("+++ exited with 0 +++");