1 /*
2 * Check bpf syscall decoding.
3 *
4 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2015-2018 The strace developers.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "tests.h"
32
33 #include <stddef.h>
34 #include <stdio.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include <asm/unistd.h>
40 #include "scno.h"
41
42 #ifdef HAVE_LINUX_BPF_H
43 # include <linux/bpf.h>
44 #endif
45
46 #include "bpf_attr.h"
47 #include "print_fields.h"
48
49 #include "xlat.h"
50 #include "xlat/bpf_commands.h"
51
52 #if defined MPERS_IS_m32 || SIZEOF_KERNEL_LONG_T > 4
53 # define BIG_ADDR(addr64_, addr32_) addr64_
54 # define BIG_ADDR_MAYBE(addr_)
55 #elif defined __arm__ || defined __i386__ || defined __mips__ \
56 || defined __powerpc__ || defined __riscv__ || defined __s390__ \
57 || defined __sparc__ || defined __tile__
58 # define BIG_ADDR(addr64_, addr32_) addr64_ " or " addr32_
59 # define BIG_ADDR_MAYBE(addr_) addr_ " or "
60 #else
61 # define BIG_ADDR(addr64_, addr32_) addr32_
62 # define BIG_ADDR_MAYBE(addr_)
63 #endif
64
65 #ifndef HAVE_STRUCT_BPF_INSN
66 struct bpf_insn {
67 uint8_t code;
68 uint8_t dst_reg:4;
69 uint8_t src_reg:4;
70 int16_t off;
71 int32_t imm;
72 };
73 #endif
74
75 #define BPF_ATTR_DATA_FIELD(cmd_) struct cmd_ ## _struct cmd_ ## _data
76
77 union bpf_attr_data {
78 BPF_ATTR_DATA_FIELD(BPF_MAP_CREATE);
79 BPF_ATTR_DATA_FIELD(BPF_MAP_LOOKUP_ELEM);
80 BPF_ATTR_DATA_FIELD(BPF_MAP_UPDATE_ELEM);
81 BPF_ATTR_DATA_FIELD(BPF_MAP_DELETE_ELEM);
82 BPF_ATTR_DATA_FIELD(BPF_MAP_GET_NEXT_KEY);
83 BPF_ATTR_DATA_FIELD(BPF_PROG_LOAD);
84 BPF_ATTR_DATA_FIELD(BPF_OBJ_PIN);
85 BPF_ATTR_DATA_FIELD(BPF_PROG_ATTACH);
86 BPF_ATTR_DATA_FIELD(BPF_PROG_DETACH);
87 BPF_ATTR_DATA_FIELD(BPF_PROG_TEST_RUN);
88 BPF_ATTR_DATA_FIELD(BPF_PROG_GET_NEXT_ID);
89 BPF_ATTR_DATA_FIELD(BPF_PROG_GET_FD_BY_ID);
90 BPF_ATTR_DATA_FIELD(BPF_MAP_GET_FD_BY_ID);
91 BPF_ATTR_DATA_FIELD(BPF_OBJ_GET_INFO_BY_FD);
92 BPF_ATTR_DATA_FIELD(BPF_PROG_QUERY);
93 BPF_ATTR_DATA_FIELD(BPF_RAW_TRACEPOINT_OPEN);
94 char char_data[256];
95 };
96
97 struct bpf_attr_check {
98 union bpf_attr_data data;
99 size_t size;
100 const char *str;
101 void (*init_fn)(struct bpf_attr_check *check);
102 void (*print_fn)(const struct bpf_attr_check *check,
103 unsigned long addr);
104 };
105
106 struct bpf_check {
107 kernel_ulong_t cmd;
108 const char *cmd_str;
109 const struct bpf_attr_check *checks;
110 size_t count;
111 };
112
113 static const kernel_ulong_t long_bits = (kernel_ulong_t) 0xfacefeed00000000ULL;
114 static const char *errstr;
115 static unsigned int sizeof_attr = sizeof(union bpf_attr_data);
116 static unsigned int page_size;
117 static unsigned long end_of_page;
118
119 static long
sys_bpf(kernel_ulong_t cmd,kernel_ulong_t attr,kernel_ulong_t size)120 sys_bpf(kernel_ulong_t cmd, kernel_ulong_t attr, kernel_ulong_t size)
121 {
122 long rc = syscall(__NR_bpf, cmd, attr, size);
123
124 errstr = sprintrc(rc);
125
126 #ifdef INJECT_RETVAL
127 if (rc != INJECT_RETVAL)
128 error_msg_and_fail("Got a return value of %ld != %d",
129 rc, INJECT_RETVAL);
130
131 static char inj_errstr[4096];
132
133 snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
134 errstr = inj_errstr;
135 #endif
136
137 return rc;
138 }
139
140 #if VERBOSE
141 # define print_extra_data(addr_, offs_, size_) \
142 do { \
143 printf("/* bytes %u..%u */ ", (offs_), (size_) + (offs_) - 1); \
144 print_quoted_hex((addr_) + (offs_), (size_)); \
145 } while (0)
146 #else
147 # define print_extra_data(addr_, offs_, size_) printf("...")
148 #endif
149
150 static void
print_bpf_attr(const struct bpf_attr_check * check,unsigned long addr)151 print_bpf_attr(const struct bpf_attr_check *check, unsigned long addr)
152 {
153 if (check->print_fn)
154 check->print_fn(check, addr);
155 else
156 printf("%s", check->str);
157 }
158
159 static void
test_bpf(const struct bpf_check * cmd_check)160 test_bpf(const struct bpf_check *cmd_check)
161 {
162 const struct bpf_attr_check *check = 0;
163 const union bpf_attr_data *data = 0;
164 unsigned int offset = 0;
165
166 /* zero addr */
167 sys_bpf(cmd_check->cmd, 0, long_bits | sizeof(union bpf_attr_data));
168 printf("bpf(%s, NULL, %u) = %s\n",
169 cmd_check->cmd_str, sizeof_attr, errstr);
170
171 /* zero size */
172 unsigned long addr = end_of_page - sizeof_attr;
173 sys_bpf(cmd_check->cmd, addr, long_bits);
174 printf("bpf(%s, %#lx, 0) = %s\n",
175 cmd_check->cmd_str, addr, errstr);
176
177 for (size_t i = 0; i < cmd_check->count; i++) {
178 check = &cmd_check->checks[i];
179 if (check->init_fn)
180 check->init_fn((struct bpf_attr_check *) check);
181 data = &check->data;
182 offset = check->size;
183
184 addr = end_of_page - offset;
185 memcpy((void *) addr, data, offset);
186
187 /* starting piece of bpf_attr_data */
188 sys_bpf(cmd_check->cmd, addr, offset);
189 printf("bpf(%s, {", cmd_check->cmd_str);
190 print_bpf_attr(check, addr);
191 printf("}, %u) = %s\n", offset, errstr);
192
193 /* short read of the starting piece */
194 sys_bpf(cmd_check->cmd, addr + 1, offset);
195 printf("bpf(%s, %#lx, %u) = %s\n",
196 cmd_check->cmd_str, addr + 1, offset, errstr);
197 }
198
199 if (offset < sizeof_attr) {
200 /* short read of the whole bpf_attr_data */
201 memcpy((void *) end_of_page - sizeof_attr + 1, data, offset);
202 addr = end_of_page - sizeof_attr + 1;
203 memset((void *) addr + offset, 0, sizeof_attr - offset - 1);
204 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
205 printf("bpf(%s, %#lx, %u) = %s\n",
206 cmd_check->cmd_str, addr, sizeof_attr, errstr);
207
208 /* the whole bpf_attr_data */
209 memcpy((void *) end_of_page - sizeof_attr, data, offset);
210 addr = end_of_page - sizeof_attr;
211 memset((void *) addr + offset, 0, sizeof_attr - offset);
212 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
213 printf("bpf(%s, {", cmd_check->cmd_str);
214 print_bpf_attr(check, addr);
215 printf("}, %u) = %s\n", sizeof_attr, errstr);
216
217 /* non-zero bytes after the relevant part */
218 fill_memory_ex((void *) addr + offset,
219 sizeof_attr - offset, '0', 10);
220 sys_bpf(cmd_check->cmd, addr, sizeof_attr);
221 printf("bpf(%s, {", cmd_check->cmd_str);
222 print_bpf_attr(check, addr);
223 printf(", ");
224 print_extra_data((char *) addr, offset,
225 sizeof_attr - offset);
226 printf("}, %u) = %s\n", sizeof_attr, errstr);
227 }
228
229 /* short read of the whole page */
230 memcpy((void *) end_of_page - page_size + 1, data, offset);
231 addr = end_of_page - page_size + 1;
232 memset((void *) addr + offset, 0, page_size - offset - 1);
233 sys_bpf(cmd_check->cmd, addr, page_size);
234 printf("bpf(%s, %#lx, %u) = %s\n",
235 cmd_check->cmd_str, addr, page_size, errstr);
236
237 /* the whole page */
238 memcpy((void *) end_of_page - page_size, data, offset);
239 addr = end_of_page - page_size;
240 memset((void *) addr + offset, 0, page_size - offset);
241 sys_bpf(cmd_check->cmd, addr, page_size);
242 printf("bpf(%s, {", cmd_check->cmd_str);
243 print_bpf_attr(check, addr);
244 printf("}, %u) = %s\n", page_size, errstr);
245
246 /* non-zero bytes after the whole bpf_attr_data */
247 fill_memory_ex((void *) addr + offset,
248 page_size - offset, '0', 10);
249 sys_bpf(cmd_check->cmd, addr, page_size);
250 printf("bpf(%s, {", cmd_check->cmd_str);
251 print_bpf_attr(check, addr);
252 printf(", ");
253 print_extra_data((char *) addr, offset,
254 page_size - offset);
255 printf("}, %u) = %s\n", page_size, errstr);
256
257 /* more than a page */
258 sys_bpf(cmd_check->cmd, addr, page_size + 1);
259 printf("bpf(%s, %#lx, %u) = %s\n",
260 cmd_check->cmd_str, addr, page_size + 1, errstr);
261 }
262
263 static void
init_BPF_MAP_CREATE_attr7(struct bpf_attr_check * check)264 init_BPF_MAP_CREATE_attr7(struct bpf_attr_check *check)
265 {
266 struct BPF_MAP_CREATE_struct *attr = &check->data.BPF_MAP_CREATE_data;
267 attr->map_ifindex = ifindex_lo();
268 }
269
270 static struct bpf_attr_check BPF_MAP_CREATE_checks[] = {
271 {
272 .data = { .BPF_MAP_CREATE_data = { .map_type = 2 } },
273 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_type),
274 .str = "map_type=BPF_MAP_TYPE_ARRAY, key_size=0, value_size=0"
275 ", max_entries=0"
276 },
277 { /* 1 */
278 .data = { .BPF_MAP_CREATE_data = {
279 .map_type = 20,
280 .key_size = 4,
281 .value_size = 8,
282 .max_entries = 256,
283 .map_flags = 63,
284 .inner_map_fd = -1,
285 .numa_node = 3141592653,
286 .map_name = "0123456789abcde",
287 } },
288 .size = offsetof(struct BPF_MAP_CREATE_struct, map_name) + 8,
289 .str = "map_type=BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, key_size=4"
290 ", value_size=8, max_entries=256"
291 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NO_COMMON_LRU"
292 "|BPF_F_NUMA_NODE|BPF_F_RDONLY|BPF_F_WRONLY"
293 "|BPF_F_STACK_BUILD_ID"
294 ", inner_map_fd=-1"
295 ", numa_node=3141592653"
296 ", map_name=\"0123456\"...",
297
298 },
299 { /* 2 */
300 .data = { .BPF_MAP_CREATE_data = {
301 .map_type = 21,
302 .key_size = 0xface1e55,
303 .value_size = 0xbadc0ded,
304 .max_entries = 0xbeefcafe,
305 .map_flags = 0xffffffc0,
306 .inner_map_fd = 2718281828,
307 .numa_node = -1,
308 .map_name = "",
309 .map_ifindex = 3141592653,
310 } },
311 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
312 .str = "map_type=0x15 /* BPF_MAP_TYPE_??? */"
313 ", key_size=4207812181, value_size=3134983661"
314 ", max_entries=3203386110"
315 ", map_flags=0xffffffc0 /* BPF_F_??? */"
316 ", inner_map_fd=-1576685468"
317 ", map_name=\"\", map_ifindex=3141592653",
318
319 },
320 { /* 3 */
321 .data = { .BPF_MAP_CREATE_data = {
322 .map_type = 0xdeadf00d,
323 .key_size = 0xface1e55,
324 .value_size = 0xbadc0ded,
325 .max_entries = 0xbeefcafe,
326 .map_flags = 0xc0dedead,
327 .inner_map_fd = 2718281828,
328 .numa_node = -1,
329 } },
330 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_flags),
331 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
332 ", key_size=4207812181, value_size=3134983661"
333 ", max_entries=3203386110"
334 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
335 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
336 "|0xc0dede80",
337 },
338 { /* 4 */
339 .data = { .BPF_MAP_CREATE_data = {
340 .map_type = 0xdeadf00d,
341 .key_size = 0xface1e55,
342 .value_size = 0xbadc0ded,
343 .max_entries = 0xbeefcafe,
344 .map_flags = 0xc0dedead,
345 .inner_map_fd = 2718281828,
346 .numa_node = -1,
347 } },
348 .size = offsetofend(struct BPF_MAP_CREATE_struct, inner_map_fd),
349 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
350 ", key_size=4207812181, value_size=3134983661"
351 ", max_entries=3203386110"
352 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
353 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
354 "|0xc0dede80"
355 ", inner_map_fd=-1576685468",
356 },
357 { /* 5 */
358 .data = { .BPF_MAP_CREATE_data = {
359 .map_type = 0xdeadf00d,
360 .key_size = 0xface1e55,
361 .value_size = 0xbadc0ded,
362 .max_entries = 0xbeefcafe,
363 .map_flags = 0xc0dedead,
364 .inner_map_fd = 2718281828,
365 .numa_node = -1,
366 } },
367 .size = offsetofend(struct BPF_MAP_CREATE_struct, numa_node),
368 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
369 ", key_size=4207812181, value_size=3134983661"
370 ", max_entries=3203386110"
371 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
372 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
373 "|0xc0dede80"
374 ", inner_map_fd=-1576685468"
375 ", numa_node=4294967295 /* NUMA_NO_NODE */",
376 },
377 { /* 6 */
378 .data = { .BPF_MAP_CREATE_data = {
379 .map_type = 0xdeadf00d,
380 .key_size = 0xface1e55,
381 .value_size = 0xbadc0ded,
382 .max_entries = 0xbeefcafe,
383 .map_flags = 0xc0dedead,
384 .inner_map_fd = 2718281828,
385 .numa_node = -1,
386 .map_name = "fedcba9876543210",
387 } },
388 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_name),
389 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
390 ", key_size=4207812181, value_size=3134983661"
391 ", max_entries=3203386110"
392 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
393 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
394 "|0xc0dede80"
395 ", inner_map_fd=-1576685468"
396 ", numa_node=4294967295 /* NUMA_NO_NODE */"
397 ", map_name=\"fedcba987654321\"...",
398 },
399 { /* 7 */
400 .data = { .BPF_MAP_CREATE_data = {
401 .map_type = 0xdeadf00d,
402 .key_size = 0xface1e55,
403 .value_size = 0xbadc0ded,
404 .max_entries = 0xbeefcafe,
405 .map_flags = 0xc0dedead,
406 .inner_map_fd = 2718281828,
407 .numa_node = -1,
408 .map_name = "0123456789abcde",
409 } },
410 .size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
411 .str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
412 ", key_size=4207812181, value_size=3134983661"
413 ", max_entries=3203386110"
414 ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
415 "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
416 "|0xc0dede80"
417 ", inner_map_fd=-1576685468"
418 ", numa_node=4294967295 /* NUMA_NO_NODE */"
419 ", map_name=\"0123456789abcde\""
420 ", map_ifindex=" IFINDEX_LO_STR,
421 .init_fn = init_BPF_MAP_CREATE_attr7,
422 },
423 };
424
425 static const struct bpf_attr_check BPF_MAP_LOOKUP_ELEM_checks[] = {
426 {
427 .data = { .BPF_MAP_LOOKUP_ELEM_data = { .map_fd = -1 } },
428 .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, map_fd),
429 .str = "map_fd=-1, key=NULL, value=NULL"
430 },
431 {
432 .data = { .BPF_MAP_LOOKUP_ELEM_data = {
433 .map_fd = -1,
434 .key = 0xdeadbeef,
435 .value = 0xbadc0ded
436 } },
437 .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, value),
438 .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
439 }
440 };
441
442 static const struct bpf_attr_check BPF_MAP_UPDATE_ELEM_checks[] = {
443 {
444 .data = { .BPF_MAP_UPDATE_ELEM_data = { .map_fd = -1 } },
445 .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, map_fd),
446 .str = "map_fd=-1, key=NULL, value=NULL, flags=BPF_ANY"
447 },
448 {
449 .data = { .BPF_MAP_UPDATE_ELEM_data = {
450 .map_fd = -1,
451 .key = 0xdeadbeef,
452 .value = 0xbadc0ded,
453 .flags = 2
454 } },
455 .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, flags),
456 .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
457 ", flags=BPF_EXIST"
458 }
459 };
460
461 static const struct bpf_attr_check BPF_MAP_DELETE_ELEM_checks[] = {
462 {
463 .data = { .BPF_MAP_DELETE_ELEM_data = { .map_fd = -1 } },
464 .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, map_fd),
465 .str = "map_fd=-1, key=NULL"
466 },
467 {
468 .data = { .BPF_MAP_DELETE_ELEM_data = {
469 .map_fd = -1,
470 .key = 0xdeadbeef
471 } },
472 .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, key),
473 .str = "map_fd=-1, key=0xdeadbeef"
474 }
475 };
476
477 static const struct bpf_attr_check BPF_MAP_GET_NEXT_KEY_checks[] = {
478 {
479 .data = { .BPF_MAP_GET_NEXT_KEY_data = { .map_fd = -1 } },
480 .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, map_fd),
481 .str = "map_fd=-1, key=NULL, next_key=NULL"
482 },
483 {
484 .data = { .BPF_MAP_GET_NEXT_KEY_data = {
485 .map_fd = -1,
486 .key = 0xdeadbeef,
487 .next_key = 0xbadc0ded
488 } },
489 .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, next_key),
490 .str = "map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded"
491 }
492 };
493
494 static const struct bpf_insn insns[] = {
495 {
496 .code = 0x95,
497 .dst_reg = 10,
498 .src_reg = 11,
499 .off = 0xdead,
500 .imm = 0xbadc0ded,
501 },
502 };
503 static const char license[] = "GPL";
504 static const char pathname[] = "/sys/fs/bpf/foo/bar";
505
506 static char *log_buf;
507 /*
508 * This has to be a macro, otherwise the compiler complains that
509 * initializer element is not constant.
510 */
511 #define log_buf_size 4096U
512
513 static inline char *
get_log_buf(void)514 get_log_buf(void)
515 {
516 if (!log_buf)
517 log_buf = tail_alloc(log_buf_size);
518 return log_buf;
519 }
520
521 static inline char *
get_log_buf_tail(void)522 get_log_buf_tail(void)
523 {
524 return get_log_buf() + log_buf_size;
525 }
526
527 #if VERBOSE
528 # define INSNS_FMT \
529 "[{code=BPF_JMP|BPF_K|BPF_EXIT, dst_reg=BPF_REG_10" \
530 ", src_reg=0xb /* BPF_REG_??? */, off=%d, imm=%#x}]"
531 # define INSNS_ARG insns[0].off, insns[0].imm
532 #else
533 # define INSNS_FMT "%p"
534 # define INSNS_ARG insns
535 #endif
536
537 static void
init_BPF_PROG_LOAD_attr3(struct bpf_attr_check * check)538 init_BPF_PROG_LOAD_attr3(struct bpf_attr_check *check)
539 {
540 struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
541
542 attr->insns = (uintptr_t) insns;
543 attr->license = (uintptr_t) license;
544 attr->log_buf = (uintptr_t) get_log_buf_tail();
545 }
546
547 static void
print_BPF_PROG_LOAD_attr3(const struct bpf_attr_check * check,unsigned long addr)548 print_BPF_PROG_LOAD_attr3(const struct bpf_attr_check *check, unsigned long addr)
549 {
550 printf("prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=%u"
551 ", insns=" INSNS_FMT ", license=\"%s\", log_level=2718281828"
552 ", log_size=%u, log_buf=%p"
553 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
554 ", prog_flags=0x2 /* BPF_F_??? */"
555 ", prog_name=\"0123456789abcde\"..., prog_ifindex=3203399405",
556 (unsigned int) ARRAY_SIZE(insns), INSNS_ARG, license,
557 log_buf_size, get_log_buf_tail());
558 }
559
560 static void
init_BPF_PROG_LOAD_attr4(struct bpf_attr_check * check)561 init_BPF_PROG_LOAD_attr4(struct bpf_attr_check *check)
562 {
563 struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
564
565 attr->insns = (uintptr_t) insns;
566 attr->license = (uintptr_t) license;
567 attr->log_buf = (uintptr_t) get_log_buf();
568 attr->prog_ifindex = ifindex_lo();
569
570 strncpy(log_buf, "log test", 9);
571 }
572
573 static void
print_BPF_PROG_LOAD_attr4(const struct bpf_attr_check * check,unsigned long addr)574 print_BPF_PROG_LOAD_attr4(const struct bpf_attr_check *check, unsigned long addr)
575 {
576 printf("prog_type=BPF_PROG_TYPE_UNSPEC, insn_cnt=%u, insns=" INSNS_FMT
577 ", license=\"%s\", log_level=2718281828, log_size=4"
578 ", log_buf=\"log \"..."
579 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
580 ", prog_flags=BPF_F_STRICT_ALIGNMENT|0x2"
581 ", prog_name=\"0123456789abcde\"..., prog_ifindex=%s"
582 ", expected_attach_type=BPF_CGROUP_INET6_BIND",
583 (unsigned int) ARRAY_SIZE(insns), INSNS_ARG,
584 license, IFINDEX_LO_STR);
585 }
586
587 static struct bpf_attr_check BPF_PROG_LOAD_checks[] = {
588 {
589 .data = { .BPF_PROG_LOAD_data = { .prog_type = 1 } },
590 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_type),
591 .str = "prog_type=BPF_PROG_TYPE_SOCKET_FILTER"
592 ", insn_cnt=0, insns=NULL, license=NULL"
593 },
594 { /* 1 */
595 .data = { .BPF_PROG_LOAD_data = {
596 .prog_type = 21,
597 .insn_cnt = 0xbadc0ded,
598 .insns = 0,
599 .license = 0,
600 .log_level = 42,
601 .log_size = 3141592653U,
602 .log_buf = 0,
603 .kern_version = 0xcafef00d,
604 .prog_flags = 0,
605 } },
606 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_flags),
607 .str = "prog_type=0x15 /* BPF_PROG_TYPE_??? */"
608 ", insn_cnt=3134983661, insns=NULL, license=NULL"
609 ", log_level=42, log_size=3141592653, log_buf=NULL"
610 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
611 ", prog_flags=0",
612 },
613 { /* 2 */
614 .data = { .BPF_PROG_LOAD_data = {
615 .prog_type = 20,
616 .insn_cnt = 0xbadc0ded,
617 .insns = 0xffffffff00000000,
618 .license = 0xffffffff00000000,
619 .log_level = 2718281828U,
620 .log_size = log_buf_size,
621 .log_buf = 0xffffffff00000000,
622 .kern_version = 0xcafef00d,
623 .prog_flags = 1,
624 .prog_name = "fedcba987654321",
625 } },
626 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_name),
627 .str = "prog_type=BPF_PROG_TYPE_SK_REUSEPORT"
628 ", insn_cnt=3134983661"
629 ", insns=" BIG_ADDR("0xffffffff00000000", "NULL")
630 ", license=" BIG_ADDR("0xffffffff00000000", "NULL")
631 ", log_level=2718281828, log_size=4096"
632 ", log_buf=" BIG_ADDR("0xffffffff00000000", "NULL")
633 ", kern_version=KERNEL_VERSION(51966, 240, 13)"
634 ", prog_flags=BPF_F_STRICT_ALIGNMENT"
635 ", prog_name=\"fedcba987654321\"",
636 },
637 { /* 3 */
638 .data = { .BPF_PROG_LOAD_data = {
639 .prog_type = 1,
640 .insn_cnt = ARRAY_SIZE(insns),
641 .log_level = 2718281828U,
642 .log_size = log_buf_size,
643 .kern_version = 0xcafef00d,
644 .prog_flags = 2,
645 .prog_name = "0123456789abcdef",
646 .prog_ifindex = 0xbeeffeed,
647 } },
648 .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_ifindex),
649 .init_fn = init_BPF_PROG_LOAD_attr3,
650 .print_fn = print_BPF_PROG_LOAD_attr3
651 },
652 { /* 4 */
653 .data = { .BPF_PROG_LOAD_data = {
654 .prog_type = 0,
655 .insn_cnt = ARRAY_SIZE(insns),
656 .log_level = 2718281828U,
657 .log_size = 4,
658 .kern_version = 0xcafef00d,
659 .prog_flags = 3,
660 .prog_name = "0123456789abcdef",
661 .expected_attach_type = 9,
662 } },
663 .size = offsetofend(struct BPF_PROG_LOAD_struct,
664 expected_attach_type),
665 .init_fn = init_BPF_PROG_LOAD_attr4,
666 .print_fn = print_BPF_PROG_LOAD_attr4
667 },
668 };
669
670 static void
init_BPF_OBJ_PIN_attr(struct bpf_attr_check * check)671 init_BPF_OBJ_PIN_attr(struct bpf_attr_check *check)
672 {
673 struct BPF_OBJ_PIN_struct *attr = &check->data.BPF_OBJ_PIN_data;
674 attr->pathname = (uintptr_t) pathname;
675 }
676
677 static struct bpf_attr_check BPF_OBJ_PIN_checks[] = {
678 {
679 .data = { .BPF_OBJ_PIN_data = { .pathname = 0 } },
680 .size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
681 .str = "pathname=NULL, bpf_fd=0"
682 },
683 {
684 .data = { .BPF_OBJ_PIN_data = {
685 .pathname = 0xFFFFFFFFFFFFFFFFULL
686 } },
687 .size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
688 .str = "pathname=" BIG_ADDR("0xffffffffffffffff", "0xffffffff")
689 ", bpf_fd=0",
690 },
691 {
692 .data = { .BPF_OBJ_PIN_data = { .bpf_fd = -1 } },
693 .size = offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd),
694 .init_fn = init_BPF_OBJ_PIN_attr,
695 .str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
696 },
697 {
698 .data = { .BPF_OBJ_PIN_data = {
699 .bpf_fd = -1,
700 .file_flags = 0x18
701 } },
702 .size = offsetofend(struct BPF_OBJ_PIN_struct, file_flags),
703 .init_fn = init_BPF_OBJ_PIN_attr,
704 .str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
705 ", file_flags=BPF_F_RDONLY|BPF_F_WRONLY"
706 }
707 };
708
709 #define BPF_OBJ_GET_checks BPF_OBJ_PIN_checks
710
711 static const struct bpf_attr_check BPF_PROG_ATTACH_checks[] = {
712 {
713 .data = { .BPF_PROG_ATTACH_data = { .target_fd = -1 } },
714 .size = offsetofend(struct BPF_PROG_ATTACH_struct, target_fd),
715 .str = "target_fd=-1, attach_bpf_fd=0"
716 ", attach_type=BPF_CGROUP_INET_INGRESS, attach_flags=0"
717 },
718 {
719 .data = { .BPF_PROG_ATTACH_data = {
720 .target_fd = -1,
721 .attach_bpf_fd = -2,
722 .attach_type = 2,
723 .attach_flags = 1
724 } },
725 .size = offsetofend(struct BPF_PROG_ATTACH_struct, attach_flags),
726 .str = "target_fd=-1, attach_bpf_fd=-2"
727 ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
728 ", attach_flags=BPF_F_ALLOW_OVERRIDE"
729 }
730 };
731
732
733 static const struct bpf_attr_check BPF_PROG_DETACH_checks[] = {
734 {
735 .data = { .BPF_PROG_DETACH_data = { .target_fd = -1 } },
736 .size = offsetofend(struct BPF_PROG_DETACH_struct, target_fd),
737 .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS"
738 },
739 {
740 .data = { .BPF_PROG_DETACH_data = {
741 .target_fd = -1,
742 .attach_type = 2
743 } },
744 .size = offsetofend(struct BPF_PROG_DETACH_struct, attach_type),
745 .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_SOCK_CREATE"
746 }
747 };
748
749 static const struct bpf_attr_check BPF_PROG_TEST_RUN_checks[] = {
750 {
751 .data = { .BPF_PROG_TEST_RUN_data = { .prog_fd = -1 } },
752 .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, prog_fd),
753 .str = "test={prog_fd=-1, retval=0, data_size_in=0"
754 ", data_size_out=0, data_in=NULL, data_out=NULL"
755 ", repeat=0, duration=0}"
756 },
757 {
758 .data = { .BPF_PROG_TEST_RUN_data = {
759 .prog_fd = -1,
760 .retval = 0xfac1fed2,
761 .data_size_in = 0xfac3fed4,
762 .data_size_out = 0xfac5fed6,
763 .data_in = (uint64_t) 0xfacef11dbadc2dedULL,
764 .data_out = (uint64_t) 0xfacef33dbadc4dedULL,
765 .repeat = 0xfac7fed8,
766 .duration = 0xfac9feda
767 } },
768 .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, duration),
769 .str = "test={prog_fd=-1, retval=4207017682"
770 ", data_size_in=4207148756, data_size_out=4207279830"
771 ", data_in=0xfacef11dbadc2ded"
772 ", data_out=0xfacef33dbadc4ded"
773 ", repeat=4207410904, duration=4207541978}"
774 }
775 };
776
777 static const struct bpf_attr_check BPF_PROG_GET_NEXT_ID_checks[] = {
778 {
779 .data = { .BPF_PROG_GET_NEXT_ID_data = {
780 .start_id = 0xdeadbeef
781 } },
782 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, start_id),
783 .str = "start_id=3735928559, next_id=0"
784 },
785 {
786 .data = { .BPF_PROG_GET_NEXT_ID_data = {
787 .start_id = 0xdeadbeef
788 } },
789 .size = 1,
790 .str = "start_id="
791 #if WORDS_BIGENDIAN
792 "3724541952" /* 0xde000000 */
793 #else
794 "239" /* 0x000000ef */
795 #endif
796 ", next_id=0"
797 },
798 {
799 .data = { .BPF_PROG_GET_NEXT_ID_data = {
800 .start_id = 0xbadc0ded,
801 .next_id = 0xcafef00d
802 } },
803 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id),
804 .str = "start_id=3134983661, next_id=3405705229"
805 },
806 {
807 .data = { .BPF_PROG_GET_NEXT_ID_data = {
808 .start_id = 0xbadc0ded,
809 .next_id = 0xcafef00d,
810 .open_flags = 0xffffff27
811 } },
812 .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, open_flags),
813 .str = "start_id=3134983661, next_id=3405705229"
814 ", open_flags=0xffffff27 /* BPF_F_??? */"
815 }
816 };
817
818 #define BPF_MAP_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
819
820 static const struct bpf_attr_check BPF_PROG_GET_FD_BY_ID_checks[] = {
821 {
822 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
823 .prog_id = 0xdeadbeef
824 } },
825 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, prog_id),
826 .str = "prog_id=3735928559, next_id=0"
827 },
828 {
829 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
830 .prog_id = 0xbadc0ded,
831 .next_id = 0xcafef00d
832 } },
833 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, next_id),
834 .str = "prog_id=3134983661, next_id=3405705229"
835 },
836 {
837 .data = { .BPF_PROG_GET_FD_BY_ID_data = {
838 .prog_id = 0xbadc0ded,
839 .next_id = 0xcafef00d,
840 .open_flags = 0xffffff27
841 } },
842 .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, open_flags),
843 .str = "prog_id=3134983661, next_id=3405705229"
844 ", open_flags=0xffffff27 /* BPF_F_??? */"
845 }
846 };
847
848 static const struct bpf_attr_check BPF_MAP_GET_FD_BY_ID_checks[] = {
849 {
850 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
851 .map_id = 0xdeadbeef
852 } },
853 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, map_id),
854 .str = "map_id=3735928559, next_id=0"
855 },
856 {
857 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
858 .map_id = 0xbadc0ded,
859 .next_id = 0xcafef00d
860 } },
861 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, next_id),
862 .str = "map_id=3134983661, next_id=3405705229"
863 },
864 {
865 .data = { .BPF_MAP_GET_FD_BY_ID_data = {
866 .map_id = 0xbadc0ded,
867 .next_id = 0xcafef00d,
868 .open_flags = 0xffffff27
869 } },
870 .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, open_flags),
871 .str = "map_id=3134983661, next_id=3405705229"
872 ", open_flags=0xffffff27 /* BPF_F_??? */"
873 }
874 };
875
876 static const struct bpf_attr_check BPF_OBJ_GET_INFO_BY_FD_checks[] = {
877 {
878 .data = { .BPF_OBJ_GET_INFO_BY_FD_data = { .bpf_fd = -1 } },
879 .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, bpf_fd),
880 .str = "info={bpf_fd=-1, info_len=0, info=NULL}"
881 },
882 {
883 .data = { .BPF_OBJ_GET_INFO_BY_FD_data = {
884 .bpf_fd = -1,
885 .info_len = 0xdeadbeef,
886 .info = (uint64_t) 0xfacefeedbadc0dedULL
887 } },
888 .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, info),
889 .str = "info={bpf_fd=-1, info_len=3735928559"
890 ", info=0xfacefeedbadc0ded}"
891 }
892 };
893
894
895 static uint32_t prog_load_ids[] = { 0, 1, 0xffffffff, 2718281828, };
896 uint32_t *prog_load_ids_ptr;
897
898 static void
init_BPF_PROG_QUERY_attr4(struct bpf_attr_check * check)899 init_BPF_PROG_QUERY_attr4(struct bpf_attr_check *check)
900 {
901 struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
902
903 if (!prog_load_ids_ptr)
904 prog_load_ids_ptr = tail_memdup(prog_load_ids,
905 sizeof(prog_load_ids));
906
907 attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
908 attr->prog_cnt = ARRAY_SIZE(prog_load_ids);
909 }
910
911 static void
print_BPF_PROG_QUERY_attr4(const struct bpf_attr_check * check,unsigned long addr)912 print_BPF_PROG_QUERY_attr4(const struct bpf_attr_check *check, unsigned long addr)
913 {
914 printf("query={target_fd=-1153374643"
915 ", attach_type=0xfeedface /* BPF_??? */"
916 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
917 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
918 #if defined(INJECT_RETVAL) && INJECT_RETVAL > 0
919 ", prog_ids=[0, 1, 4294967295, 2718281828], prog_cnt=4}"
920 #else
921 ", prog_ids=%p, prog_cnt=4}", prog_load_ids_ptr
922 #endif
923 );
924 }
925
926 static void
init_BPF_PROG_QUERY_attr5(struct bpf_attr_check * check)927 init_BPF_PROG_QUERY_attr5(struct bpf_attr_check *check)
928 {
929 struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
930
931 if (!prog_load_ids_ptr)
932 prog_load_ids_ptr = tail_memdup(prog_load_ids,
933 sizeof(prog_load_ids));
934
935 attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
936 attr->prog_cnt = ARRAY_SIZE(prog_load_ids) + 1;
937 }
938
939 static void
print_BPF_PROG_QUERY_attr5(const struct bpf_attr_check * check,unsigned long addr)940 print_BPF_PROG_QUERY_attr5(const struct bpf_attr_check *check, unsigned long addr)
941 {
942 printf("query={target_fd=-1153374643"
943 ", attach_type=0xfeedface /* BPF_??? */"
944 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
945 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
946 #if defined(INJECT_RETVAL) && INJECT_RETVAL > 0
947 ", prog_ids=[0, 1, 4294967295, 2718281828, ... /* %p */]"
948 ", prog_cnt=5}",
949 prog_load_ids_ptr + ARRAY_SIZE(prog_load_ids)
950 #else
951 ", prog_ids=%p, prog_cnt=5}", prog_load_ids_ptr
952 #endif
953 );
954 }
955
956 static struct bpf_attr_check BPF_PROG_QUERY_checks[] = {
957 {
958 .data = { .BPF_PROG_QUERY_data = { .target_fd = -1 } },
959 .size = offsetofend(struct BPF_PROG_QUERY_struct, target_fd),
960 .str = "query={target_fd=-1"
961 ", attach_type=BPF_CGROUP_INET_INGRESS, query_flags=0"
962 ", attach_flags=0, prog_ids=NULL, prog_cnt=0}",
963 },
964 { /* 1 */
965 .data = { .BPF_PROG_QUERY_data = {
966 .target_fd = 3141592653U,
967 .attach_type = 16,
968 .query_flags = 1,
969 .attach_flags = 3,
970 } },
971 .size = offsetofend(struct BPF_PROG_QUERY_struct, attach_flags),
972 .str = "query={target_fd=-1153374643"
973 ", attach_type=BPF_LIRC_MODE2"
974 ", query_flags=BPF_F_QUERY_EFFECTIVE"
975 ", attach_flags=BPF_F_ALLOW_OVERRIDE|BPF_F_ALLOW_MULTI"
976 ", prog_ids=NULL, prog_cnt=0}",
977 },
978 { /* 2 */
979 .data = { .BPF_PROG_QUERY_data = {
980 .target_fd = 3141592653U,
981 .attach_type = 17,
982 .query_flags = 0xfffffffe,
983 .attach_flags = 0xfffffffc,
984 .prog_ids = 0xffffffffffffffffULL,
985 .prog_cnt = 2718281828,
986 } },
987 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
988 .str = "query={target_fd=-1153374643"
989 ", attach_type=0x11 /* BPF_??? */"
990 ", query_flags=0xfffffffe /* BPF_F_QUERY_??? */"
991 ", attach_flags=0xfffffffc /* BPF_F_??? */"
992 ", prog_ids="
993 BIG_ADDR("0xffffffffffffffff", "0xffffffff")
994 ", prog_cnt=2718281828}",
995 },
996 { /* 3 */
997 .data = { .BPF_PROG_QUERY_data = {
998 .target_fd = 3141592653U,
999 .attach_type = 0xfeedface,
1000 .query_flags = 0xdeadf00d,
1001 .attach_flags = 0xbeefcafe,
1002 .prog_ids = 0xffffffffffffffffULL,
1003 .prog_cnt = 0,
1004 } },
1005 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1006 .str = "query={target_fd=-1153374643"
1007 ", attach_type=0xfeedface /* BPF_??? */"
1008 ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
1009 ", attach_flags=BPF_F_ALLOW_MULTI|0xbeefcafc"
1010 ", prog_ids=" BIG_ADDR_MAYBE("0xffffffffffffffff") "[]"
1011 ", prog_cnt=0}",
1012 },
1013 { /* 4 */
1014 .data = { .BPF_PROG_QUERY_data = {
1015 .target_fd = 3141592653U,
1016 .attach_type = 0xfeedface,
1017 .query_flags = 0xdeadf00d,
1018 .attach_flags = 0xbeefcafe,
1019 } },
1020 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1021 .init_fn = init_BPF_PROG_QUERY_attr4,
1022 .print_fn = print_BPF_PROG_QUERY_attr4,
1023 },
1024 { /* 5 */
1025 .data = { .BPF_PROG_QUERY_data = {
1026 .target_fd = 3141592653U,
1027 .attach_type = 0xfeedface,
1028 .query_flags = 0xdeadf00d,
1029 .attach_flags = 0xbeefcafe,
1030 } },
1031 .size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
1032 .init_fn = init_BPF_PROG_QUERY_attr5,
1033 .print_fn = print_BPF_PROG_QUERY_attr5,
1034 },
1035 };
1036
1037
1038 static void
init_BPF_RAW_TRACEPOINT_attr2(struct bpf_attr_check * check)1039 init_BPF_RAW_TRACEPOINT_attr2(struct bpf_attr_check *check)
1040 {
1041 /* TODO: test the 128 byte limit */
1042 static const char tp_name[] = "0123456789qwertyuiop0123456789qwe";
1043
1044 struct BPF_RAW_TRACEPOINT_OPEN_struct *attr =
1045 &check->data.BPF_RAW_TRACEPOINT_OPEN_data;
1046
1047 attr->name = (uintptr_t) tp_name;
1048 }
1049
1050 static struct bpf_attr_check BPF_RAW_TRACEPOINT_OPEN_checks[] = {
1051 {
1052 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = { .name = 0 } },
1053 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1054 name),
1055 .str = "raw_tracepoint={name=NULL, prog_fd=0}",
1056 },
1057 { /* 1 */
1058 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
1059 .name = 0xffffffff00000000ULL,
1060 .prog_fd = 0xdeadbeef,
1061 } },
1062 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1063 prog_fd),
1064 .str = "raw_tracepoint="
1065 "{name=" BIG_ADDR("0xffffffff00000000", "NULL")
1066 ", prog_fd=-559038737}",
1067 },
1068 {
1069 .data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
1070 .prog_fd = 0xdeadbeef,
1071 } },
1072 .size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
1073 prog_fd),
1074 .init_fn = init_BPF_RAW_TRACEPOINT_attr2,
1075 .str = "raw_tracepoint="
1076 "{name=\"0123456789qwertyuiop0123456789qw\"..."
1077 ", prog_fd=-559038737}",
1078 }
1079 };
1080
1081
1082 #define CHK(cmd_) \
1083 { \
1084 cmd_, #cmd_, \
1085 cmd_##_checks, ARRAY_SIZE(cmd_##_checks), \
1086 } \
1087 /* End of CHK definition */
1088
1089 int
main(void)1090 main(void)
1091 {
1092 static const struct bpf_check checks[] = {
1093 CHK(BPF_MAP_CREATE),
1094 CHK(BPF_MAP_LOOKUP_ELEM),
1095 CHK(BPF_MAP_UPDATE_ELEM),
1096 CHK(BPF_MAP_DELETE_ELEM),
1097 CHK(BPF_MAP_GET_NEXT_KEY),
1098 CHK(BPF_PROG_LOAD),
1099 CHK(BPF_OBJ_PIN),
1100 CHK(BPF_OBJ_GET),
1101 CHK(BPF_PROG_ATTACH),
1102 CHK(BPF_PROG_DETACH),
1103 CHK(BPF_PROG_TEST_RUN),
1104 CHK(BPF_PROG_GET_NEXT_ID),
1105 CHK(BPF_MAP_GET_NEXT_ID),
1106 CHK(BPF_PROG_GET_FD_BY_ID),
1107 CHK(BPF_MAP_GET_FD_BY_ID),
1108 CHK(BPF_OBJ_GET_INFO_BY_FD),
1109 CHK(BPF_PROG_QUERY),
1110 CHK(BPF_RAW_TRACEPOINT_OPEN),
1111 };
1112
1113 page_size = get_page_size();
1114 end_of_page = (unsigned long) tail_alloc(1) + 1;
1115
1116 for (size_t i = 0; i < ARRAY_SIZE(checks); i++)
1117 test_bpf(checks + i);
1118
1119 sys_bpf(0xfacefeed, 0, (kernel_ulong_t) 0xfacefeedbadc0dedULL);
1120 printf("bpf(0xfacefeed /* BPF_??? */, NULL, %u) = %s\n",
1121 0xbadc0dedu, errstr);
1122
1123 sys_bpf(0xfacefeed, end_of_page, 40);
1124 printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
1125 end_of_page, errstr);
1126
1127 puts("+++ exited with 0 +++");
1128 return 0;
1129 }
1130