(root)/
strace-6.5/
tests-mx32/
bpf.c
       1  /*
       2   * Check bpf syscall decoding.
       3   *
       4   * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2015-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  
      13  #include <stddef.h>
      14  #include <stdio.h>
      15  #include <stdint.h>
      16  #include <string.h>
      17  #include <unistd.h>
      18  
      19  #include "scno.h"
      20  
      21  #ifdef HAVE_LINUX_BPF_H
      22  # include <linux/bpf.h>
      23  #endif
      24  
      25  #include "bpf_attr.h"
      26  #include "print_fields.h"
      27  #include "xmalloc.h"
      28  
      29  #include "xlat.h"
      30  #include "xlat/bpf_attach_type.h"
      31  #include "xlat/bpf_commands.h"
      32  #include "xlat/bpf_map_types.h"
      33  #include "xlat/bpf_prog_types.h"
      34  #include "xlat/bpf_test_run_flags.h"
      35  
      36  #if defined MPERS_IS_m32 || SIZEOF_KERNEL_LONG_T > 4
      37  # define BIG_ADDR(addr64_, addr32_) addr64_
      38  # define BIG_ADDR_MAYBE(addr_)
      39  #elif defined __arm__ || defined __i386__ || defined __mips__ \
      40     || defined __powerpc__ || defined __riscv || defined __s390__ \
      41     || defined __sparc__ || defined __tile__
      42  # define BIG_ADDR(addr64_, addr32_) addr64_ " or " addr32_
      43  # define BIG_ADDR_MAYBE(addr_) addr_ " or "
      44  #else
      45  # define BIG_ADDR(addr64_, addr32_) addr32_
      46  # define BIG_ADDR_MAYBE(addr_)
      47  #endif
      48  
      49  #ifndef FD0_PATH
      50  # define FD0_PATH ""
      51  #endif
      52  
      53  #ifndef HAVE_STRUCT_BPF_INSN
      54  struct bpf_insn {
      55  	uint8_t	code;
      56  	uint8_t	dst_reg:4;
      57  	uint8_t	src_reg:4;
      58  	int16_t	off;
      59  	int32_t	imm;
      60  };
      61  #endif
      62  
      63  #define BPF_ATTR_DATA_FIELD(cmd_) struct cmd_ ## _struct cmd_ ## _data
      64  
      65  union bpf_attr_data {
      66  	BPF_ATTR_DATA_FIELD(BPF_MAP_CREATE);
      67  	BPF_ATTR_DATA_FIELD(BPF_MAP_LOOKUP_ELEM);
      68  	BPF_ATTR_DATA_FIELD(BPF_MAP_UPDATE_ELEM);
      69  	BPF_ATTR_DATA_FIELD(BPF_MAP_DELETE_ELEM);
      70  	BPF_ATTR_DATA_FIELD(BPF_MAP_GET_NEXT_KEY);
      71  	BPF_ATTR_DATA_FIELD(BPF_PROG_LOAD);
      72  	BPF_ATTR_DATA_FIELD(BPF_OBJ_PIN);
      73  	BPF_ATTR_DATA_FIELD(BPF_PROG_ATTACH);
      74  	BPF_ATTR_DATA_FIELD(BPF_PROG_DETACH);
      75  	BPF_ATTR_DATA_FIELD(BPF_PROG_TEST_RUN);
      76  	BPF_ATTR_DATA_FIELD(BPF_PROG_GET_NEXT_ID);
      77  	BPF_ATTR_DATA_FIELD(BPF_PROG_GET_FD_BY_ID);
      78  	BPF_ATTR_DATA_FIELD(BPF_MAP_GET_FD_BY_ID);
      79  	BPF_ATTR_DATA_FIELD(BPF_OBJ_GET_INFO_BY_FD);
      80  	BPF_ATTR_DATA_FIELD(BPF_PROG_QUERY);
      81  	BPF_ATTR_DATA_FIELD(BPF_RAW_TRACEPOINT_OPEN);
      82  	BPF_ATTR_DATA_FIELD(BPF_BTF_LOAD);
      83  	BPF_ATTR_DATA_FIELD(BPF_BTF_GET_FD_BY_ID);
      84  	BPF_ATTR_DATA_FIELD(BPF_TASK_FD_QUERY);
      85  	BPF_ATTR_DATA_FIELD(BPF_MAP_FREEZE);
      86  	BPF_ATTR_DATA_FIELD(BPF_MAP_LOOKUP_BATCH);
      87  	BPF_ATTR_DATA_FIELD(BPF_MAP_UPDATE_BATCH);
      88  	BPF_ATTR_DATA_FIELD(BPF_MAP_DELETE_BATCH);
      89  	BPF_ATTR_DATA_FIELD(BPF_LINK_CREATE);
      90  	BPF_ATTR_DATA_FIELD(BPF_LINK_UPDATE);
      91  	BPF_ATTR_DATA_FIELD(BPF_LINK_GET_FD_BY_ID);
      92  	BPF_ATTR_DATA_FIELD(BPF_ENABLE_STATS);
      93  	BPF_ATTR_DATA_FIELD(BPF_ITER_CREATE);
      94  	BPF_ATTR_DATA_FIELD(BPF_LINK_DETACH);
      95  	BPF_ATTR_DATA_FIELD(BPF_PROG_BIND_MAP);
      96  	char char_data[256];
      97  };
      98  
      99  struct bpf_attr_check {
     100  	union bpf_attr_data data;
     101  	size_t size;
     102  	size_t iters;
     103  	const char *str;
     104  	void (*init_fn)(struct bpf_attr_check *check, size_t idx);
     105  	void (*print_fn)(const struct bpf_attr_check *check,
     106  			 unsigned long addr, size_t idx);
     107  };
     108  
     109  struct bpf_check {
     110  	kernel_ulong_t cmd;
     111  	const char *cmd_str;
     112  	const struct bpf_attr_check *checks;
     113  	size_t count;
     114  };
     115  
     116  static const kernel_ulong_t long_bits = (kernel_ulong_t) 0xfacefeed00000000ULL;
     117  static const char *errstr;
     118  static const char *at_fdcwd_str;
     119  static const unsigned int sizeof_attr = sizeof(union bpf_attr_data);
     120  static unsigned int page_size;
     121  static unsigned long end_of_page;
     122  
     123  static long
     124  sys_bpf(kernel_ulong_t cmd, kernel_ulong_t attr, kernel_ulong_t size)
     125  {
     126  	long rc = syscall(__NR_bpf, cmd, attr, size);
     127  
     128  	errstr = sprintrc(rc);
     129  
     130  #ifdef INJECT_RETVAL
     131  	if (rc != INJECT_RETVAL)
     132  		error_msg_and_fail("Got a return value of %ld != %ld",
     133  				   rc, (long) INJECT_RETVAL);
     134  
     135  	static char inj_errstr[4096];
     136  
     137  	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
     138  	errstr = inj_errstr;
     139  #endif
     140  
     141  	return rc;
     142  }
     143  
     144  #if VERBOSE
     145  # define print_extra_data(addr_, offs_, size_) \
     146  	do { \
     147  		printf("extra_data="); \
     148  		print_quoted_hex((addr_) + (offs_), (size_)); \
     149  		printf(" /* bytes %u..%u */", (offs_), (size_) + (offs_) - 1); \
     150  	} while (0)
     151  #else
     152  # define print_extra_data(addr_, offs_, size_) printf("...")
     153  #endif
     154  
     155  static void
     156  print_bpf_attr(const struct bpf_attr_check *check, unsigned long addr,
     157  	       size_t idx)
     158  {
     159  	if (check->print_fn)
     160  		check->print_fn(check, addr, idx);
     161  	else
     162  		printf("%s", check->str);
     163  }
     164  
     165  static void
     166  test_bpf(const struct bpf_check *cmd_check)
     167  {
     168  	const struct bpf_attr_check *check = 0;
     169  	const union bpf_attr_data *data = 0;
     170  	unsigned int offset = 0;
     171  	size_t j = 0;
     172  
     173  	/* zero addr */
     174  	sys_bpf(cmd_check->cmd, 0, long_bits | sizeof(union bpf_attr_data));
     175  	printf("bpf(%s, NULL, %u) = %s\n",
     176  	       cmd_check->cmd_str, sizeof_attr, errstr);
     177  
     178  	/* zero size */
     179  	unsigned long addr = end_of_page - sizeof_attr;
     180  	sys_bpf(cmd_check->cmd, addr, long_bits);
     181  	printf("bpf(%s, %#lx, 0) = %s\n",
     182  	       cmd_check->cmd_str, addr, errstr);
     183  
     184  	for (size_t i = 0; i < cmd_check->count; i++) {
     185  		check = &cmd_check->checks[i];
     186  		for (j = 0; j < MAX(check->iters, 1); j++) {
     187  			if (check->init_fn)
     188  				check->init_fn((struct bpf_attr_check *) check, j);
     189  			data = &check->data;
     190  			offset = check->size;
     191  
     192  			addr = end_of_page - offset;
     193  			memcpy((void *) addr, data, offset);
     194  
     195  			/* starting piece of bpf_attr_data */
     196  			sys_bpf(cmd_check->cmd, addr, offset);
     197  			printf("bpf(%s, {", cmd_check->cmd_str);
     198  			print_bpf_attr(check, addr, j);
     199  			printf("}, %u) = %s\n", offset, errstr);
     200  
     201  			/* short read of the starting piece */
     202  			sys_bpf(cmd_check->cmd, addr + 1, offset);
     203  			printf("bpf(%s, %#lx, %u) = %s\n",
     204  			       cmd_check->cmd_str, addr + 1, offset, errstr);
     205  		}
     206  	}
     207  
     208  	j = MAX(check->iters, 1) - 1;
     209  
     210  	if (offset < sizeof_attr) {
     211  		/* short read of the whole bpf_attr_data */
     212  		memcpy((void *) end_of_page - sizeof_attr + 1, data, offset);
     213  		addr = end_of_page - sizeof_attr + 1;
     214  		memset((void *) addr + offset, 0, sizeof_attr - offset - 1);
     215  		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
     216  		printf("bpf(%s, %#lx, %u) = %s\n",
     217  		       cmd_check->cmd_str, addr, sizeof_attr, errstr);
     218  
     219  		/* the whole bpf_attr_data */
     220  		memcpy((void *) end_of_page - sizeof_attr, data, offset);
     221  		addr = end_of_page - sizeof_attr;
     222  		memset((void *) addr + offset, 0, sizeof_attr - offset);
     223  		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
     224  		printf("bpf(%s, {", cmd_check->cmd_str);
     225  		print_bpf_attr(check, addr, j);
     226  		printf("}, %u) = %s\n", sizeof_attr, errstr);
     227  
     228  		/* non-zero bytes after the relevant part */
     229  		fill_memory_ex((void *) addr + offset,
     230  			       sizeof_attr - offset, '0', 10);
     231  		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
     232  		printf("bpf(%s, {", cmd_check->cmd_str);
     233  		print_bpf_attr(check, addr, j);
     234  		printf(", ");
     235  		print_extra_data((char *) addr, offset,
     236  				 sizeof_attr - offset);
     237  		printf("}, %u) = %s\n", sizeof_attr, errstr);
     238  	}
     239  
     240  	/* short read of the whole page */
     241  	memcpy((void *) end_of_page - page_size + 1, data, offset);
     242  	addr = end_of_page - page_size + 1;
     243  	memset((void *) addr + offset, 0, page_size - offset - 1);
     244  	sys_bpf(cmd_check->cmd, addr, page_size);
     245  	printf("bpf(%s, %#lx, %u) = %s\n",
     246  	       cmd_check->cmd_str, addr, page_size, errstr);
     247  
     248  	/* the whole page */
     249  	memcpy((void *) end_of_page - page_size, data, offset);
     250  	addr = end_of_page - page_size;
     251  	memset((void *) addr + offset, 0, page_size - offset);
     252  	sys_bpf(cmd_check->cmd, addr, page_size);
     253  	printf("bpf(%s, {", cmd_check->cmd_str);
     254  	print_bpf_attr(check, addr, j);
     255  	printf("}, %u) = %s\n", page_size, errstr);
     256  
     257  	/* non-zero bytes after the whole bpf_attr_data */
     258  	fill_memory_ex((void *) addr + offset,
     259  		       page_size - offset, '0', 10);
     260  	sys_bpf(cmd_check->cmd, addr, page_size);
     261  	printf("bpf(%s, {", cmd_check->cmd_str);
     262  	print_bpf_attr(check, addr, j);
     263  	printf(", ");
     264  	print_extra_data((char *) addr, offset,
     265  			 page_size - offset);
     266  	printf("}, %u) = %s\n", page_size, errstr);
     267  
     268  	/* more than a page */
     269  	sys_bpf(cmd_check->cmd, addr, page_size + 1);
     270  	printf("bpf(%s, %#lx, %u) = %s\n",
     271  	       cmd_check->cmd_str, addr, page_size + 1, errstr);
     272  }
     273  
     274  static void
     275  init_BPF_MAP_CREATE_attr7(struct bpf_attr_check *check, size_t idx)
     276  {
     277  	struct BPF_MAP_CREATE_struct *attr = &check->data.BPF_MAP_CREATE_data;
     278  	attr->map_ifindex = ifindex_lo();
     279  }
     280  
     281  static_assert(ARRAY_SIZE(bpf_map_types_xdata) == 33,
     282  	      "The map_type for tests 1 and 2 below needs to be updated");
     283  static struct bpf_attr_check BPF_MAP_CREATE_checks[] = {
     284  	{
     285  		.data = { .BPF_MAP_CREATE_data = { .map_type = 2 } },
     286  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_type),
     287  		.str = "map_type=BPF_MAP_TYPE_ARRAY, key_size=0, value_size=0"
     288  		       ", max_entries=0"
     289  	},
     290  	{ /* 1 */
     291  		.data = { .BPF_MAP_CREATE_data = {
     292  			.map_type = 32,
     293  			.key_size = 4,
     294  			.value_size = 8,
     295  			.max_entries = 256,
     296  			.map_flags = 63,
     297  			.inner_map_fd = -1,
     298  			.numa_node = 3141592653,
     299  			.map_name = "0123456789abcde",
     300  		} },
     301  		.size = offsetof(struct BPF_MAP_CREATE_struct, map_name) + 8,
     302  		.str = "map_type=BPF_MAP_TYPE_CGRP_STORAGE, key_size=4"
     303  		       ", value_size=8, max_entries=256"
     304  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NO_COMMON_LRU"
     305  				   "|BPF_F_NUMA_NODE|BPF_F_RDONLY|BPF_F_WRONLY"
     306  				   "|BPF_F_STACK_BUILD_ID"
     307  		       ", inner_map_fd=-1"
     308  		       ", numa_node=3141592653"
     309  		       ", map_name=\"0123456\"...",
     310  
     311  	},
     312  	{ /* 2 */
     313  		.data = { .BPF_MAP_CREATE_data = {
     314  			.map_type = 33,
     315  			.key_size = 0xface1e55,
     316  			.value_size = 0xbadc0ded,
     317  			.max_entries = 0xbeefcafe,
     318  			.map_flags = 0xffffc000,
     319  			.inner_map_fd = 2718281828,
     320  			.numa_node = -1,
     321  			.map_name = "",
     322  			.map_ifindex = 3141592653,
     323  		} },
     324  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
     325  		.str = "map_type=0x21 /* BPF_MAP_TYPE_??? */"
     326  		       ", key_size=4207812181, value_size=3134983661"
     327  		       ", max_entries=3203386110"
     328  		       ", map_flags=0xffffc000 /* BPF_F_??? */"
     329  		       ", inner_map_fd=-1576685468"
     330  		       ", map_name=\"\", map_ifindex=3141592653",
     331  
     332  	},
     333  	{ /* 3 */
     334  		.data = { .BPF_MAP_CREATE_data = {
     335  			.map_type = 0xdeadf00d,
     336  			.key_size = 0xface1e55,
     337  			.value_size = 0xbadc0ded,
     338  			.max_entries = 0xbeefcafe,
     339  			.map_flags = 0xc0defead,
     340  			.inner_map_fd = 2718281828,
     341  			.numa_node = -1,
     342  		} },
     343  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_flags),
     344  		.str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
     345  		       ", key_size=4207812181, value_size=3134983661"
     346  		       ", max_entries=3203386110"
     347  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
     348  				   "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
     349  				   "|BPF_F_RDONLY_PROG|BPF_F_CLONE"
     350  				   "|BPF_F_MMAPABLE|BPF_F_PRESERVE_ELEMS"
     351  				   "|BPF_F_INNER_MAP|BPF_F_LINK|0xc0dec000",
     352  	},
     353  	{ /* 4 */
     354  		.data = { .BPF_MAP_CREATE_data = {
     355  			.map_type = 0xdeadf00d,
     356  			.key_size = 0xface1e55,
     357  			.value_size = 0xbadc0ded,
     358  			.max_entries = 0xbeefcafe,
     359  			.map_flags = 0xc0defead,
     360  			.inner_map_fd = 2718281828,
     361  			.numa_node = -1,
     362  		} },
     363  		.size = offsetofend(struct BPF_MAP_CREATE_struct, inner_map_fd),
     364  		.str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
     365  		       ", key_size=4207812181, value_size=3134983661"
     366  		       ", max_entries=3203386110"
     367  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
     368  				   "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
     369  				   "|BPF_F_RDONLY_PROG|BPF_F_CLONE"
     370  				   "|BPF_F_MMAPABLE|BPF_F_PRESERVE_ELEMS"
     371  				   "|BPF_F_INNER_MAP|BPF_F_LINK|0xc0dec000"
     372  		       ", inner_map_fd=-1576685468",
     373  	},
     374  	{ /* 5 */
     375  		.data = { .BPF_MAP_CREATE_data = {
     376  			.map_type = 0xdeadf00d,
     377  			.key_size = 0xface1e55,
     378  			.value_size = 0xbadc0ded,
     379  			.max_entries = 0xbeefcafe,
     380  			.map_flags = 0xc0defead,
     381  			.inner_map_fd = 2718281828,
     382  			.numa_node = -1,
     383  		} },
     384  		.size = offsetofend(struct BPF_MAP_CREATE_struct, numa_node),
     385  		.str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
     386  		       ", key_size=4207812181, value_size=3134983661"
     387  		       ", max_entries=3203386110"
     388  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
     389  				   "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
     390  				   "|BPF_F_RDONLY_PROG|BPF_F_CLONE"
     391  				   "|BPF_F_MMAPABLE|BPF_F_PRESERVE_ELEMS"
     392  				   "|BPF_F_INNER_MAP|BPF_F_LINK|0xc0dec000"
     393  		       ", inner_map_fd=-1576685468"
     394  		       ", numa_node=4294967295 /* NUMA_NO_NODE */",
     395  	},
     396  	{ /* 6 */
     397  		.data = { .BPF_MAP_CREATE_data = {
     398  			.map_type = 0xdeadf00d,
     399  			.key_size = 0xface1e55,
     400  			.value_size = 0xbadc0ded,
     401  			.max_entries = 0xbeefcafe,
     402  			.map_flags = 0xc0defead,
     403  			.inner_map_fd = 2718281828,
     404  			.numa_node = -1,
     405  			.map_name = "fedcba9876543210",
     406  		} },
     407  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_name),
     408  		.str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
     409  		       ", key_size=4207812181, value_size=3134983661"
     410  		       ", max_entries=3203386110"
     411  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
     412  				   "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
     413  				   "|BPF_F_RDONLY_PROG|BPF_F_CLONE"
     414  				   "|BPF_F_MMAPABLE|BPF_F_PRESERVE_ELEMS"
     415  				   "|BPF_F_INNER_MAP|BPF_F_LINK|0xc0dec000"
     416  		       ", inner_map_fd=-1576685468"
     417  		       ", numa_node=4294967295 /* NUMA_NO_NODE */"
     418  		       ", map_name=\"fedcba987654321\"...",
     419  	},
     420  	{ /* 7 */
     421  		.data = { .BPF_MAP_CREATE_data = {
     422  			.map_type = 0xdeadf00d,
     423  			.key_size = 0xface1e55,
     424  			.value_size = 0xbadc0ded,
     425  			.max_entries = 0xbeefcafe,
     426  			.map_flags = 0xc0defead,
     427  			.inner_map_fd = 2718281828,
     428  			.numa_node = -1,
     429  			.map_name = "0123456789abcde",
     430  		} },
     431  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_ifindex),
     432  		.str = "map_type=0xdeadf00d /* BPF_MAP_TYPE_??? */"
     433  		       ", key_size=4207812181, value_size=3134983661"
     434  		       ", max_entries=3203386110"
     435  		       ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NUMA_NODE"
     436  				   "|BPF_F_RDONLY|BPF_F_STACK_BUILD_ID"
     437  				   "|BPF_F_RDONLY_PROG|BPF_F_CLONE"
     438  				   "|BPF_F_MMAPABLE|BPF_F_PRESERVE_ELEMS"
     439  				   "|BPF_F_INNER_MAP|BPF_F_LINK|0xc0dec000"
     440  		       ", inner_map_fd=-1576685468"
     441  		       ", numa_node=4294967295 /* NUMA_NO_NODE */"
     442  		       ", map_name=\"0123456789abcde\""
     443  		       ", map_ifindex=" IFINDEX_LO_STR,
     444  		.init_fn = init_BPF_MAP_CREATE_attr7,
     445  	},
     446  	{ /* 8 */
     447  		.data = { .BPF_MAP_CREATE_data = {
     448  			.btf_fd = 0xbadc0ded,
     449  			.btf_key_type_id = 0xfacefeed,
     450  			.btf_value_type_id = 0xcafef00d
     451  		} },
     452  		.size = offsetofend(struct BPF_MAP_CREATE_struct,
     453  				    btf_value_type_id),
     454  		.str = "map_type=BPF_MAP_TYPE_UNSPEC"
     455  		       ", key_size=0"
     456  		       ", value_size=0"
     457  		       ", max_entries=0"
     458  		       ", map_flags=0"
     459  		       ", inner_map_fd=0" FD0_PATH
     460  		       ", map_name=\"\""
     461  		       ", map_ifindex=0"
     462  		       ", btf_fd=-1159983635"
     463  		       ", btf_key_type_id=4207869677"
     464  		       ", btf_value_type_id=3405705229"
     465  	},
     466  	{ /* 9 */
     467  		.data = { .BPF_MAP_CREATE_data = {
     468  			.btf_fd = 0xbadc0ded,
     469  			.btf_key_type_id = 0xfacefeed,
     470  			.btf_value_type_id = 0xcafef00d,
     471  			.btf_vmlinux_value_type_id = 0xdeadc0de,
     472  		} },
     473  		.size = offsetofend(struct BPF_MAP_CREATE_struct,
     474  				    btf_vmlinux_value_type_id),
     475  		.str = "map_type=BPF_MAP_TYPE_UNSPEC"
     476  		       ", key_size=0"
     477  		       ", value_size=0"
     478  		       ", max_entries=0"
     479  		       ", map_flags=0"
     480  		       ", inner_map_fd=0" FD0_PATH
     481  		       ", map_name=\"\""
     482  		       ", map_ifindex=0"
     483  		       ", btf_fd=-1159983635"
     484  		       ", btf_key_type_id=4207869677"
     485  		       ", btf_value_type_id=3405705229"
     486  		       ", btf_vmlinux_value_type_id=3735929054"
     487  	},
     488  	{ /* 10 */
     489  		.data = { .BPF_MAP_CREATE_data = {
     490  			.map_type = BPF_MAP_TYPE_BLOOM_FILTER,
     491  			.map_extra = 4
     492  		} },
     493  		.size = offsetofend(struct BPF_MAP_CREATE_struct, map_extra),
     494  		.str = "map_type=BPF_MAP_TYPE_BLOOM_FILTER"
     495  		       ", key_size=0"
     496  		       ", value_size=0"
     497  		       ", max_entries=0"
     498  		       ", map_flags=0"
     499  		       ", inner_map_fd=0" FD0_PATH
     500  		       ", map_name=\"\""
     501  		       ", map_ifindex=0"
     502  		       ", btf_fd=0" FD0_PATH
     503  		       ", btf_key_type_id=0"
     504  		       ", btf_value_type_id=0"
     505  		       ", btf_vmlinux_value_type_id=0"
     506  		       ", map_extra=4"
     507  	},
     508  };
     509  
     510  static const struct bpf_attr_check BPF_MAP_LOOKUP_ELEM_checks[] = {
     511  	{
     512  		.data = { .BPF_MAP_LOOKUP_ELEM_data = { .map_fd = -1 } },
     513  		.size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, map_fd),
     514  		.str = "map_fd=-1, key=NULL, value=NULL"
     515  	},
     516  	{
     517  		.data = { .BPF_MAP_LOOKUP_ELEM_data = {
     518  			.map_fd = -1,
     519  			.key = 0xdeadbeef,
     520  			.value = 0xbadc0ded,
     521  			.flags = 4
     522  		} },
     523  		.size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, flags),
     524  		.str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
     525  		       ", flags=BPF_F_LOCK"
     526  	}
     527  };
     528  
     529  #define BPF_MAP_LOOKUP_AND_DELETE_ELEM_checks BPF_MAP_LOOKUP_ELEM_checks
     530  
     531  static const struct bpf_attr_check BPF_MAP_UPDATE_ELEM_checks[] = {
     532  	{
     533  		.data = { .BPF_MAP_UPDATE_ELEM_data = { .map_fd = -1 } },
     534  		.size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, map_fd),
     535  		.str = "map_fd=-1, key=NULL, value=NULL, flags=BPF_ANY"
     536  	},
     537  	{
     538  		.data = { .BPF_MAP_UPDATE_ELEM_data = {
     539  			.map_fd = -1,
     540  			.key = 0xdeadbeef,
     541  			.value = 0xbadc0ded,
     542  			.flags = 2
     543  		} },
     544  		.size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, flags),
     545  		.str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
     546  		       ", flags=BPF_EXIST"
     547  	}
     548  };
     549  
     550  static const struct bpf_attr_check BPF_MAP_DELETE_ELEM_checks[] = {
     551  	{
     552  		.data = { .BPF_MAP_DELETE_ELEM_data = { .map_fd = -1 } },
     553  		.size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, map_fd),
     554  		.str = "map_fd=-1, key=NULL"
     555  	},
     556  	{
     557  		.data = { .BPF_MAP_DELETE_ELEM_data = {
     558  			.map_fd = -1,
     559  			.key = 0xdeadbeef
     560  		} },
     561  		.size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, key),
     562  		.str = "map_fd=-1, key=0xdeadbeef"
     563  	}
     564  };
     565  
     566  static const struct bpf_attr_check BPF_MAP_GET_NEXT_KEY_checks[] = {
     567  	{
     568  		.data = { .BPF_MAP_GET_NEXT_KEY_data = { .map_fd = -1 } },
     569  		.size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, map_fd),
     570  		.str = "map_fd=-1, key=NULL, next_key=NULL"
     571  	},
     572  	{
     573  		.data = { .BPF_MAP_GET_NEXT_KEY_data = {
     574  			.map_fd = -1,
     575  			.key = 0xdeadbeef,
     576  			.next_key = 0xbadc0ded
     577  		} },
     578  		.size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, next_key),
     579  		.str = "map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded"
     580  	}
     581  };
     582  
     583  static const struct bpf_attr_check BPF_MAP_FREEZE_checks[] = {
     584  	{
     585  		.data = { .BPF_MAP_FREEZE_data = { .map_fd = -1 } },
     586  		.size = offsetofend(struct BPF_MAP_FREEZE_struct, map_fd),
     587  		.str = "map_fd=-1"
     588  	}
     589  };
     590  
     591  static const struct bpf_insn insns[] = {
     592  	{
     593  		.code = 0x95,
     594  		.dst_reg = 10,
     595  		.src_reg = 11,
     596  		.off = 0xdead,
     597  		.imm = 0xbadc0ded,
     598  	},
     599  };
     600  static const char license[] = "GPL";
     601  static const char pathname[] = "/sys/fs/bpf/foo/bar";
     602  
     603  static char *log_buf;
     604  /*
     605   * This has to be a macro, otherwise the compiler complains that
     606   * initializer element is not constant.
     607   */
     608  #define log_buf_size 4096U
     609  
     610  static char *
     611  get_log_buf(void)
     612  {
     613  	if (!log_buf)
     614  		log_buf = tail_alloc(log_buf_size);
     615  	return log_buf;
     616  }
     617  
     618  static char *
     619  get_log_buf_tail(void)
     620  {
     621  	return get_log_buf() + log_buf_size;
     622  }
     623  
     624  #if VERBOSE
     625  # define INSNS_FMT \
     626  	"[{code=BPF_JMP|BPF_K|BPF_EXIT, dst_reg=BPF_REG_10" \
     627  	", src_reg=0xb /* BPF_REG_??? */, off=%d, imm=%#x}]"
     628  # define INSNS_ARG insns[0].off, insns[0].imm
     629  #else
     630  # define INSNS_FMT "%p"
     631  # define INSNS_ARG insns
     632  #endif
     633  
     634  static void
     635  init_BPF_PROG_LOAD_attr3(struct bpf_attr_check *check, size_t idx)
     636  {
     637  	struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
     638  
     639  	attr->insns = (uintptr_t) insns;
     640  	attr->license = (uintptr_t) license;
     641  	attr->log_buf = (uintptr_t) get_log_buf_tail();
     642  }
     643  
     644  static void
     645  print_BPF_PROG_LOAD_attr3(const struct bpf_attr_check *check,
     646  			  unsigned long addr, size_t idx)
     647  {
     648  	printf("prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=%u"
     649  	       ", insns=" INSNS_FMT ", license=\"%s\", log_level=2718281828"
     650  	       ", log_size=%u, log_buf=%p"
     651  	       ", kern_version=KERNEL_VERSION(51966, 240, 13)"
     652  	       ", prog_flags=0x20 /* BPF_F_??? */"
     653  	       ", prog_name=\"0123456789abcde\"..., prog_ifindex=3203399405",
     654  	       (unsigned int) ARRAY_SIZE(insns), INSNS_ARG, license,
     655  	       log_buf_size, get_log_buf_tail());
     656  }
     657  
     658  static void
     659  init_BPF_PROG_LOAD_attr4(struct bpf_attr_check *check, size_t idx)
     660  {
     661  	struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
     662  
     663  	attr->insns = (uintptr_t) insns;
     664  	attr->license = (uintptr_t) license;
     665  	attr->log_buf = (uintptr_t) get_log_buf();
     666  	attr->prog_ifindex = ifindex_lo();
     667  
     668  	strncpy(log_buf, "log test", 9);
     669  }
     670  
     671  static void
     672  print_BPF_PROG_LOAD_attr4(const struct bpf_attr_check *check,
     673  			  unsigned long addr, size_t idx)
     674  {
     675  	printf("prog_type=BPF_PROG_TYPE_UNSPEC, insn_cnt=%u, insns=" INSNS_FMT
     676  	       ", license=\"%s\", log_level=2718281828, log_size=4"
     677  	       ", log_buf=\"log \"..."
     678  	       ", kern_version=KERNEL_VERSION(51966, 240, 13)"
     679  	       ", prog_flags=BPF_F_STRICT_ALIGNMENT|BPF_F_ANY_ALIGNMENT"
     680  	       "|BPF_F_TEST_RND_HI32|BPF_F_TEST_STATE_FREQ|BPF_F_SLEEPABLE"
     681  	       "|0x20, prog_name=\"0123456789abcde\"..., prog_ifindex=%s"
     682  	       ", expected_attach_type=BPF_CGROUP_INET6_BIND",
     683  	       (unsigned int) ARRAY_SIZE(insns), INSNS_ARG,
     684  	       license, IFINDEX_LO_STR);
     685  }
     686  
     687  static_assert(ARRAY_SIZE(bpf_prog_types_xdata) == 33,
     688  	      "The prog_type for tests 1 and 5 below needs to be updated");
     689  static struct bpf_attr_check BPF_PROG_LOAD_checks[] = {
     690  	{
     691  		.data = { .BPF_PROG_LOAD_data = { .prog_type = 1 } },
     692  		.size = offsetofend(struct BPF_PROG_LOAD_struct, prog_type),
     693  		.str = "prog_type=BPF_PROG_TYPE_SOCKET_FILTER"
     694  		       ", insn_cnt=0, insns=NULL, license=NULL"
     695  	},
     696  	{ /* 1 */
     697  		.data = { .BPF_PROG_LOAD_data = {
     698  			.prog_type = 33,
     699  			.insn_cnt = 0xbadc0ded,
     700  			.insns = 0,
     701  			.license = 0,
     702  			.log_level = 42,
     703  			.log_size = 3141592653U,
     704  			.log_buf = 0,
     705  			.kern_version = 0xcafef00d,
     706  			.prog_flags = 0,
     707  		} },
     708  		.size = offsetofend(struct BPF_PROG_LOAD_struct, prog_flags),
     709  		.str = "prog_type=0x21 /* BPF_PROG_TYPE_??? */"
     710  		       ", insn_cnt=3134983661, insns=NULL, license=NULL"
     711  		       ", log_level=42, log_size=3141592653, log_buf=NULL"
     712  		       ", kern_version=KERNEL_VERSION(51966, 240, 13)"
     713  		       ", prog_flags=0",
     714  	},
     715  	{ /* 2 */
     716  		.data = { .BPF_PROG_LOAD_data = {
     717  			.prog_type = 20,
     718  			.insn_cnt = 0xbadc0ded,
     719  			.insns = 0xffffffff00000000,
     720  			.license = 0xffffffff00000000,
     721  			.log_level = 2718281828U,
     722  			.log_size = log_buf_size,
     723  			.log_buf = 0xffffffff00000000,
     724  			.kern_version = 0xcafef00d,
     725  			.prog_flags = 1,
     726  			.prog_name = "fedcba987654321",
     727  		} },
     728  		.size = offsetofend(struct BPF_PROG_LOAD_struct, prog_name),
     729  		.str = "prog_type=BPF_PROG_TYPE_LIRC_MODE2"
     730  		       ", insn_cnt=3134983661"
     731  		       ", insns=" BIG_ADDR("0xffffffff00000000", "NULL")
     732  		       ", license=" BIG_ADDR("0xffffffff00000000", "NULL")
     733  		       ", log_level=2718281828, log_size=4096"
     734  		       ", log_buf=" BIG_ADDR("0xffffffff00000000", "NULL")
     735  		       ", kern_version=KERNEL_VERSION(51966, 240, 13)"
     736  		       ", prog_flags=BPF_F_STRICT_ALIGNMENT"
     737  		       ", prog_name=\"fedcba987654321\"",
     738  	},
     739  	{ /* 3 */
     740  		.data = { .BPF_PROG_LOAD_data = {
     741  			.prog_type = 1,
     742  			.insn_cnt = ARRAY_SIZE(insns),
     743  			.log_level = 2718281828U,
     744  			.log_size = log_buf_size,
     745  			.kern_version = 0xcafef00d,
     746  			.prog_flags = 32,
     747  			.prog_name = "0123456789abcdef",
     748  			.prog_ifindex = 0xbeeffeed,
     749  		} },
     750  		.size = offsetofend(struct BPF_PROG_LOAD_struct, prog_ifindex),
     751  		.init_fn = init_BPF_PROG_LOAD_attr3,
     752  		.print_fn = print_BPF_PROG_LOAD_attr3
     753  	},
     754  	{ /* 4 */
     755  		.data = { .BPF_PROG_LOAD_data = {
     756  			.prog_type = 0,
     757  			.insn_cnt = ARRAY_SIZE(insns),
     758  			.log_level = 2718281828U,
     759  			.log_size = 4,
     760  			.kern_version = 0xcafef00d,
     761  			.prog_flags = 0x3f,
     762  			.prog_name = "0123456789abcdef",
     763  			.expected_attach_type = 9,
     764  		} },
     765  		.size = offsetofend(struct BPF_PROG_LOAD_struct,
     766  				    expected_attach_type),
     767  		.init_fn = init_BPF_PROG_LOAD_attr4,
     768  		.print_fn = print_BPF_PROG_LOAD_attr4
     769  	},
     770  	{ /* 5 */
     771  		.data = { .BPF_PROG_LOAD_data = {
     772  			.prog_type = 32,
     773  			.insn_cnt = 0xbadc0ded,
     774  			.insns = 0xffffffff00000000,
     775  			.license = 0xffffffff00000000,
     776  			.log_level = 2718281828U,
     777  			.log_size = log_buf_size,
     778  			.log_buf = 0xffffffff00000000,
     779  			.kern_version = 0xcafef00d,
     780  			.prog_flags = 1,
     781  			.prog_name = "fedcba987654321",
     782  		} },
     783  		.size = offsetofend(struct BPF_PROG_LOAD_struct, prog_name),
     784  		.str = "prog_type=BPF_PROG_TYPE_NETFILTER"
     785  		       ", insn_cnt=3134983661"
     786  		       ", insns=" BIG_ADDR("0xffffffff00000000", "NULL")
     787  		       ", license=" BIG_ADDR("0xffffffff00000000", "NULL")
     788  		       ", log_level=2718281828, log_size=4096"
     789  		       ", log_buf=" BIG_ADDR("0xffffffff00000000", "NULL")
     790  		       ", kern_version=KERNEL_VERSION(51966, 240, 13)"
     791  		       ", prog_flags=BPF_F_STRICT_ALIGNMENT"
     792  		       ", prog_name=\"fedcba987654321\"",
     793  	},
     794  	{ /* 6 */
     795  		.data = { .BPF_PROG_LOAD_data = {
     796  			.prog_flags = 2,
     797  			.expected_attach_type = 17,
     798  			.prog_btf_fd = 0xbadc0ded,
     799  			.func_info_rec_size = 0xdad1bef2,
     800  			.func_info = 0xfac1fed2fac3fed4,
     801  			.func_info_cnt = 0xdad3bef4,
     802  			.line_info_rec_size = 0xdad5bef6,
     803  			.line_info = 0xfac5fed5fac7fed8,
     804  			.line_info_cnt = 0xdad7bef8,
     805  			.attach_btf_id = 0xdad7befa,
     806  			.attach_prog_fd = 0xbadc0def,
     807  			.fd_array = 0xfaceb00c,
     808  		} },
     809  		.size = offsetofend(struct BPF_PROG_LOAD_struct, fd_array),
     810  		.str = "prog_type=BPF_PROG_TYPE_UNSPEC"
     811  		       ", insn_cnt=0"
     812  		       ", insns=NULL"
     813  		       ", license=NULL"
     814  		       ", log_level=0"
     815  		       ", log_size=0"
     816  		       ", log_buf=NULL"
     817  		       ", kern_version=KERNEL_VERSION(0, 0, 0)"
     818  		       ", prog_flags=BPF_F_ANY_ALIGNMENT"
     819  		       ", prog_name=\"\""
     820  		       ", prog_ifindex=0"
     821  		       ", expected_attach_type=BPF_FLOW_DISSECTOR"
     822  		       ", prog_btf_fd=-1159983635"
     823  		       ", func_info_rec_size=3671178994"
     824  		       ", func_info=0xfac1fed2fac3fed4"
     825  		       ", func_info_cnt=3671310068"
     826  		       ", line_info_rec_size=3671441142"
     827  		       ", line_info=0xfac5fed5fac7fed8"
     828  		       ", line_info_cnt=3671572216"
     829  		       ", attach_btf_id=3671572218"
     830  		       ", attach_prog_fd=-1159983633"
     831  		       ", fd_array=0xfaceb00c"
     832  	},
     833  };
     834  
     835  static void
     836  init_BPF_OBJ_PIN_attr(struct bpf_attr_check *check, size_t idx)
     837  {
     838  	struct BPF_OBJ_PIN_struct *attr = &check->data.BPF_OBJ_PIN_data;
     839  	attr->pathname = (uintptr_t) pathname;
     840  }
     841  
     842  static void
     843  init_BPF_OBJ_PIN_str(struct bpf_attr_check *check, size_t idx)
     844  {
     845  	check->str = xasprintf("pathname=NULL, bpf_fd=-1, file_flags=BPF_F_PATH_FD"
     846  			       ", path_fd=%s", at_fdcwd_str);
     847  }
     848  
     849  static struct bpf_attr_check BPF_OBJ_PIN_checks[] = {
     850  	{
     851  		.data = { .BPF_OBJ_PIN_data = { .pathname = 0 } },
     852  		.size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
     853  		.str = "pathname=NULL, bpf_fd=0" FD0_PATH
     854  	},
     855  	{
     856  		.data = { .BPF_OBJ_PIN_data = {
     857  			.pathname = 0xFFFFFFFFFFFFFFFFULL
     858  		} },
     859  		.size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
     860  		.str = "pathname=" BIG_ADDR("0xffffffffffffffff", "0xffffffff")
     861  		       ", bpf_fd=0" FD0_PATH,
     862  	},
     863  	{
     864  		.data = { .BPF_OBJ_PIN_data = { .bpf_fd = -1 } },
     865  		.size = offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd),
     866  		.init_fn = init_BPF_OBJ_PIN_attr,
     867  		.str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
     868  	},
     869  	{
     870  		.data = { .BPF_OBJ_PIN_data = {
     871  			.bpf_fd = -1,
     872  			.file_flags = 0x18
     873  		} },
     874  		.size = offsetofend(struct BPF_OBJ_PIN_struct, file_flags),
     875  		.init_fn = init_BPF_OBJ_PIN_attr,
     876  		.str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
     877  		       ", file_flags=BPF_F_RDONLY|BPF_F_WRONLY"
     878  	},
     879  	{
     880  		.data = { .BPF_OBJ_PIN_data = {
     881  			.pathname = 0,
     882  			.bpf_fd = -1,
     883  			.file_flags = 0x4000,
     884  			.path_fd = -100
     885  		} },
     886  		.size = offsetofend(struct BPF_OBJ_PIN_struct, path_fd),
     887  		.init_fn = init_BPF_OBJ_PIN_str,
     888  	}
     889  };
     890  
     891  #define BPF_OBJ_GET_checks BPF_OBJ_PIN_checks
     892  
     893  static const struct bpf_attr_check BPF_PROG_ATTACH_checks[] = {
     894  	{
     895  		.data = { .BPF_PROG_ATTACH_data = { .target_fd = -1 } },
     896  		.size = offsetofend(struct BPF_PROG_ATTACH_struct, target_fd),
     897  		.str = "target_fd=-1, attach_bpf_fd=0" FD0_PATH
     898  		       ", attach_type=BPF_CGROUP_INET_INGRESS, attach_flags=0"
     899  	},
     900  	{
     901  		.data = { .BPF_PROG_ATTACH_data = {
     902  			.target_fd = -1,
     903  			.attach_bpf_fd = -2,
     904  			.attach_type = 2,
     905  			.attach_flags = 7
     906  		} },
     907  		.size = offsetofend(struct BPF_PROG_ATTACH_struct, attach_flags),
     908  		.str = "target_fd=-1, attach_bpf_fd=-2"
     909  		       ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
     910  		       ", attach_flags=BPF_F_ALLOW_OVERRIDE|BPF_F_ALLOW_MULTI"
     911  				       "|BPF_F_REPLACE"
     912  	},
     913  	{
     914  		.data = { .BPF_PROG_ATTACH_data = {
     915  			.target_fd = -1,
     916  			.attach_bpf_fd = -2,
     917  			.attach_type = 2,
     918  			.attach_flags = 0xf8,
     919  			.replace_bpf_fd = -3,
     920  		} },
     921  		.size = offsetofend(struct BPF_PROG_ATTACH_struct, replace_bpf_fd),
     922  		.str = "target_fd=-1, attach_bpf_fd=-2"
     923  		       ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
     924  		       ", attach_flags=0xf8 /* BPF_F_??? */"
     925  		       ", replace_bpf_fd=-3"
     926  	},
     927  };
     928  
     929  
     930  static const struct bpf_attr_check BPF_PROG_DETACH_checks[] = {
     931  	{
     932  		.data = { .BPF_PROG_DETACH_data = { .target_fd = -1 } },
     933  		.size = offsetofend(struct BPF_PROG_DETACH_struct, target_fd),
     934  		.str = "target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS"
     935  	},
     936  	{
     937  		.data = { .BPF_PROG_DETACH_data = {
     938  			.target_fd = -1,
     939  			.attach_type = 2
     940  		} },
     941  		.size = offsetofend(struct BPF_PROG_DETACH_struct, attach_type),
     942  		.str = "target_fd=-1, attach_type=BPF_CGROUP_INET_SOCK_CREATE"
     943  	}
     944  };
     945  
     946  static const struct bpf_attr_check BPF_PROG_TEST_RUN_checks[] = {
     947  	{
     948  		.data = { .BPF_PROG_TEST_RUN_data = { .prog_fd = -1 } },
     949  		.size = offsetofend(struct BPF_PROG_TEST_RUN_struct, prog_fd),
     950  		.str = "test={prog_fd=-1, retval=0, data_size_in=0"
     951  		       ", data_size_out=0, data_in=NULL, data_out=NULL"
     952  		       ", repeat=0, duration=0}"
     953  	},
     954  	{
     955  		.data = { .BPF_PROG_TEST_RUN_data = {
     956  			.prog_fd = -1,
     957  			.retval = 0xfac1fed2,
     958  			.data_size_in = 0xfac3fed4,
     959  			.data_size_out = 0xfac5fed6,
     960  			.data_in = (uint64_t) 0xfacef11dbadc2dedULL,
     961  			.data_out = (uint64_t) 0xfacef33dbadc4dedULL,
     962  			.repeat = 0xfac7fed8,
     963  			.duration = 0xfac9feda
     964  		} },
     965  		.size = offsetofend(struct BPF_PROG_TEST_RUN_struct, duration),
     966  		.str = "test={prog_fd=-1, retval=4207017682"
     967  		       ", data_size_in=4207148756, data_size_out=4207279830"
     968  		       ", data_in=0xfacef11dbadc2ded"
     969  		       ", data_out=0xfacef33dbadc4ded"
     970  		       ", repeat=4207410904, duration=4207541978}"
     971  	},
     972  	{
     973  		.data = { .BPF_PROG_TEST_RUN_data = {
     974  			.prog_fd = -1,
     975  			.retval = 0xfac1fed2,
     976  			.data_size_in = 0xfac3fed4,
     977  			.data_size_out = 0xfac5fed6,
     978  			.data_in = (uint64_t) 0xfacef11dbadc2dedULL,
     979  			.data_out = (uint64_t) 0xfacef33dbadc4dedULL,
     980  			.repeat = 0xfac7fed8,
     981  			.duration = 0xfac9feda,
     982  			.ctx_size_in = 0,
     983  			.ctx_size_out = 0xfacdfede,
     984  			.ctx_in = (uint64_t) 0xfacef55dbadc6dedULL,
     985  		} },
     986  		.size = offsetofend(struct BPF_PROG_TEST_RUN_struct, ctx_in),
     987  		.str = "test={prog_fd=-1, retval=4207017682"
     988  		       ", data_size_in=4207148756, data_size_out=4207279830"
     989  		       ", data_in=0xfacef11dbadc2ded"
     990  		       ", data_out=0xfacef33dbadc4ded"
     991  		       ", repeat=4207410904"
     992  		       ", duration=4207541978"
     993  		       ", ctx_size_in=0, ctx_size_out=4207804126"
     994  		       ", ctx_in=0xfacef55dbadc6ded, ctx_out=NULL}"
     995  	},
     996  	{
     997  		.data = { .BPF_PROG_TEST_RUN_data = {
     998  			.prog_fd = -1,
     999  			.retval = 0xfac1fed2,
    1000  			.data_size_in = 0xfac3fed4,
    1001  			.data_size_out = 0xfac5fed6,
    1002  			.data_in = (uint64_t) 0xfacef11dbadc2dedULL,
    1003  			.data_out = (uint64_t) 0xfacef33dbadc4dedULL,
    1004  			.repeat = 0xfac7fed8,
    1005  			.duration = 0xfac9feda,
    1006  			.ctx_size_in = 0xfacbfedc,
    1007  			.ctx_size_out = 0xfacdfede,
    1008  			.ctx_in = (uint64_t) 0xfacef55dbadc6dedULL,
    1009  			.ctx_out = (uint64_t) 0xfacef77dbadc8dedULL,
    1010  			.flags = BPF_F_TEST_RUN_ON_CPU|BPF_F_TEST_XDP_LIVE_FRAMES,
    1011  			.cpu = 0,
    1012  		} },
    1013  		.size = offsetofend(struct BPF_PROG_TEST_RUN_struct, cpu),
    1014  		.str = "test={prog_fd=-1, retval=4207017682"
    1015  		       ", data_size_in=4207148756, data_size_out=4207279830"
    1016  		       ", data_in=0xfacef11dbadc2ded"
    1017  		       ", data_out=0xfacef33dbadc4ded"
    1018  		       ", repeat=4207410904"
    1019  		       ", duration=4207541978"
    1020  		       ", ctx_size_in=4207673052"
    1021  		       ", ctx_size_out=4207804126"
    1022  		       ", ctx_in=0xfacef55dbadc6ded"
    1023  		       ", ctx_out=0xfacef77dbadc8ded"
    1024  		       ", flags=BPF_F_TEST_RUN_ON_CPU|BPF_F_TEST_XDP_LIVE_FRAMES"
    1025  		       ", cpu=0}"
    1026  	},
    1027  	{
    1028  		.data = { .BPF_PROG_TEST_RUN_data = {
    1029  			.prog_fd = -1,
    1030  			.retval = 0xfac1fed2,
    1031  			.data_size_in = 0xfac3fed4,
    1032  			.data_size_out = 0xfac5fed6,
    1033  			.data_in = (uint64_t) 0xfacef11dbadc2dedULL,
    1034  			.data_out = (uint64_t) 0xfacef33dbadc4dedULL,
    1035  			.repeat = 0xfac7fed8,
    1036  			.duration = 0xfac9feda,
    1037  			.ctx_size_in = 0,
    1038  			.ctx_size_out = 0,
    1039  			.ctx_in = 0,
    1040  			.ctx_out = 0,
    1041  			.flags = 0xfffffffc,
    1042  			.cpu = 3141592653,
    1043  			.batch_size = 2718281828,
    1044  		} },
    1045  		.size = offsetofend(struct BPF_PROG_TEST_RUN_struct, batch_size),
    1046  		.str = "test={prog_fd=-1, retval=4207017682"
    1047  		       ", data_size_in=4207148756, data_size_out=4207279830"
    1048  		       ", data_in=0xfacef11dbadc2ded"
    1049  		       ", data_out=0xfacef33dbadc4ded"
    1050  		       ", repeat=4207410904"
    1051  		       ", duration=4207541978"
    1052  		       ", ctx_size_in=0, ctx_size_out=0"
    1053  		       ", ctx_in=NULL, ctx_out=NULL"
    1054  		       ", flags=0xfffffffc /* BPF_F_??? */"
    1055  		       ", cpu=3141592653, batch_size=2718281828}"
    1056  	},
    1057  };
    1058  
    1059  static const struct bpf_attr_check BPF_PROG_GET_NEXT_ID_checks[] = {
    1060  	{
    1061  		.data = { .BPF_PROG_GET_NEXT_ID_data = {
    1062  			.start_id = 0xdeadbeef
    1063  		} },
    1064  		.size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, start_id),
    1065  		.str = "start_id=3735928559, next_id=0"
    1066  	},
    1067  	{
    1068  		.data = { .BPF_PROG_GET_NEXT_ID_data = {
    1069  			.start_id = 0xdeadbeef
    1070  		} },
    1071  		.size = 1,
    1072  		/*                        0xde000000 0x000000ef */
    1073  		.str = "start_id=" BE_LE("3724541952", "239") ", next_id=0"
    1074  	},
    1075  	{
    1076  		.data = { .BPF_PROG_GET_NEXT_ID_data = {
    1077  			.start_id = 0xbadc0ded,
    1078  			.next_id = 0xcafef00d
    1079  		} },
    1080  		.size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id),
    1081  		.str = "start_id=3134983661, next_id=3405705229"
    1082  	},
    1083  	{
    1084  		.data = { .BPF_PROG_GET_NEXT_ID_data = {
    1085  			.start_id = 0xbadc0ded,
    1086  			.next_id = 0xcafef00d,
    1087  			.open_flags = 0xffffff27
    1088  		} },
    1089  		.size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, open_flags),
    1090  		.str = "start_id=3134983661, next_id=3405705229"
    1091  		       ", open_flags=0xffffff27 /* BPF_F_??? */"
    1092  	}
    1093  };
    1094  
    1095  #define BPF_MAP_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
    1096  #define BPF_BTF_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
    1097  #define BPF_LINK_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
    1098  
    1099  static const struct bpf_attr_check BPF_PROG_GET_FD_BY_ID_checks[] = {
    1100  	{
    1101  		.data = { .BPF_PROG_GET_FD_BY_ID_data = {
    1102  			.prog_id = 0xdeadbeef
    1103  		} },
    1104  		.size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, prog_id),
    1105  		.str = "prog_id=3735928559, next_id=0"
    1106  	},
    1107  	{
    1108  		.data = { .BPF_PROG_GET_FD_BY_ID_data = {
    1109  			.prog_id = 0xbadc0ded,
    1110  			.next_id = 0xcafef00d
    1111  		} },
    1112  		.size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, next_id),
    1113  		.str = "prog_id=3134983661, next_id=3405705229"
    1114  	},
    1115  	{
    1116  		.data = { .BPF_PROG_GET_FD_BY_ID_data = {
    1117  			.prog_id = 0xbadc0ded,
    1118  			.next_id = 0xcafef00d,
    1119  			.open_flags = 0xffffff27
    1120  		} },
    1121  		.size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, open_flags),
    1122  		.str = "prog_id=3134983661, next_id=3405705229"
    1123  		       ", open_flags=0xffffff27 /* BPF_F_??? */"
    1124  	}
    1125  };
    1126  
    1127  static const struct bpf_attr_check BPF_MAP_GET_FD_BY_ID_checks[] = {
    1128  	{
    1129  		.data = { .BPF_MAP_GET_FD_BY_ID_data = {
    1130  			.map_id = 0xdeadbeef
    1131  		} },
    1132  		.size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, map_id),
    1133  		.str = "map_id=3735928559, next_id=0"
    1134  	},
    1135  	{
    1136  		.data = { .BPF_MAP_GET_FD_BY_ID_data = {
    1137  			.map_id = 0xbadc0ded,
    1138  			.next_id = 0xcafef00d
    1139  		} },
    1140  		.size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, next_id),
    1141  		.str = "map_id=3134983661, next_id=3405705229"
    1142  	},
    1143  	{
    1144  		.data = { .BPF_MAP_GET_FD_BY_ID_data = {
    1145  			.map_id = 0xbadc0ded,
    1146  			.next_id = 0xcafef00d,
    1147  			.open_flags = 0xffffff27
    1148  		} },
    1149  		.size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, open_flags),
    1150  		.str = "map_id=3134983661, next_id=3405705229"
    1151  		       ", open_flags=0xffffff27 /* BPF_F_??? */"
    1152  	}
    1153  };
    1154  
    1155  static const struct bpf_attr_check BPF_OBJ_GET_INFO_BY_FD_checks[] = {
    1156  	{
    1157  		.data = { .BPF_OBJ_GET_INFO_BY_FD_data = { .bpf_fd = -1 } },
    1158  		.size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, bpf_fd),
    1159  		.str = "info={bpf_fd=-1, info_len=0, info=NULL}"
    1160  	},
    1161  	{
    1162  		.data = { .BPF_OBJ_GET_INFO_BY_FD_data = {
    1163  			.bpf_fd = -1,
    1164  			.info_len = 0xdeadbeef,
    1165  			.info = (uint64_t) 0xfacefeedbadc0dedULL
    1166  		} },
    1167  		.size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, info),
    1168  		.str = "info={bpf_fd=-1, info_len=3735928559"
    1169  		       ", info=0xfacefeedbadc0ded}"
    1170  	}
    1171  };
    1172  
    1173  
    1174  static uint32_t prog_load_ids[] = { 0, 1, 0xffffffff, 2718281828, };
    1175  uint32_t *prog_load_ids_ptr;
    1176  
    1177  static void
    1178  init_BPF_PROG_QUERY_attr4(struct bpf_attr_check *check, size_t idx)
    1179  {
    1180  	struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
    1181  
    1182  	if (!prog_load_ids_ptr)
    1183  		prog_load_ids_ptr = tail_memdup(prog_load_ids,
    1184  						sizeof(prog_load_ids));
    1185  
    1186  	attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
    1187  	attr->prog_cnt = ARRAY_SIZE(prog_load_ids);
    1188  }
    1189  
    1190  static void
    1191  print_BPF_PROG_QUERY_attr4(const struct bpf_attr_check *check,
    1192  			   unsigned long addr, size_t idx)
    1193  {
    1194  	printf("query={target_fd=-1153374643"
    1195  	       ", attach_type=0xfeedface /* BPF_??? */"
    1196  	       ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
    1197  	       ", attach_flags=BPF_F_ALLOW_MULTI|BPF_F_REPLACE|0xbeefcaf8"
    1198  #if defined(INJECT_RETVAL)
    1199  	       ", prog_ids=[0, 1, 4294967295, 2718281828], prog_cnt=4}"
    1200  #else
    1201  	       ", prog_ids=%p, prog_cnt=4}", prog_load_ids_ptr
    1202  #endif
    1203  	       );
    1204  }
    1205  
    1206  static void
    1207  init_BPF_PROG_QUERY_attr5(struct bpf_attr_check *check, size_t idx)
    1208  {
    1209  	struct BPF_PROG_QUERY_struct *attr = &check->data.BPF_PROG_QUERY_data;
    1210  
    1211  	if (!prog_load_ids_ptr)
    1212  		prog_load_ids_ptr = tail_memdup(prog_load_ids,
    1213  						sizeof(prog_load_ids));
    1214  
    1215  	attr->prog_ids = (uintptr_t) prog_load_ids_ptr;
    1216  	attr->prog_cnt = ARRAY_SIZE(prog_load_ids) + 1;
    1217  }
    1218  
    1219  static void
    1220  print_BPF_PROG_QUERY_attr5(const struct bpf_attr_check *check,
    1221  			   unsigned long addr, size_t idx)
    1222  {
    1223  	printf("query={target_fd=-1153374643"
    1224  	       ", attach_type=0xfeedface /* BPF_??? */"
    1225  	       ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
    1226  	       ", attach_flags=BPF_F_ALLOW_MULTI|BPF_F_REPLACE|0xbeefcaf8"
    1227  #if defined(INJECT_RETVAL)
    1228  	       ", prog_ids=[0, 1, 4294967295, 2718281828, ... /* %p */]"
    1229  	       ", prog_cnt=5}",
    1230  	       prog_load_ids_ptr + ARRAY_SIZE(prog_load_ids)
    1231  #else
    1232  	       ", prog_ids=%p, prog_cnt=5}", prog_load_ids_ptr
    1233  #endif
    1234  	       );
    1235  }
    1236  
    1237  static struct bpf_attr_check BPF_PROG_QUERY_checks[] = {
    1238  	{
    1239  		.data = { .BPF_PROG_QUERY_data = { .target_fd = -1 } },
    1240  		.size = offsetofend(struct BPF_PROG_QUERY_struct, target_fd),
    1241  		.str = "query={target_fd=-1"
    1242  		       ", attach_type=BPF_CGROUP_INET_INGRESS, query_flags=0"
    1243  		       ", attach_flags=0, prog_ids=NULL, prog_cnt=0}",
    1244  	},
    1245  	{ /* 1 */
    1246  		.data = { .BPF_PROG_QUERY_data = {
    1247  			.target_fd = 3141592653U,
    1248  			.attach_type = 45,
    1249  			.query_flags = 1,
    1250  			.attach_flags = 3,
    1251  		} },
    1252  		.size = offsetofend(struct BPF_PROG_QUERY_struct, attach_flags),
    1253  		.str = "query={target_fd=-1153374643"
    1254  		       ", attach_type=BPF_NETFILTER"
    1255  		       ", query_flags=BPF_F_QUERY_EFFECTIVE"
    1256  		       ", attach_flags=BPF_F_ALLOW_OVERRIDE|BPF_F_ALLOW_MULTI"
    1257  		       ", prog_ids=NULL, prog_cnt=0}",
    1258  	},
    1259  	{ /* 2 */
    1260  		.data = { .BPF_PROG_QUERY_data = {
    1261  			.target_fd = 3141592653U,
    1262  			.attach_type = 46,
    1263  			.query_flags = 0xfffffffe,
    1264  			.attach_flags = 0xfffffff8,
    1265  			.prog_ids = 0xffffffffffffffffULL,
    1266  			.prog_cnt = 2718281828,
    1267  		} },
    1268  		.size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
    1269  		.str = "query={target_fd=-1153374643"
    1270  		       ", attach_type=0x2e /* BPF_??? */"
    1271  		       ", query_flags=0xfffffffe /* BPF_F_QUERY_??? */"
    1272  		       ", attach_flags=0xfffffff8 /* BPF_F_??? */"
    1273  		       ", prog_ids="
    1274  		       BIG_ADDR("0xffffffffffffffff", "0xffffffff")
    1275  		       ", prog_cnt=2718281828}",
    1276  	},
    1277  	{ /* 3 */
    1278  		.data = { .BPF_PROG_QUERY_data = {
    1279  			.target_fd = 3141592653U,
    1280  			.attach_type = 0xfeedface,
    1281  			.query_flags = 0xdeadf00d,
    1282  			.attach_flags = 0xbeefcafe,
    1283  			.prog_ids = 0xffffffffffffffffULL,
    1284  			.prog_cnt = 0,
    1285  		} },
    1286  		.size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
    1287  		.str = "query={target_fd=-1153374643"
    1288  		       ", attach_type=0xfeedface /* BPF_??? */"
    1289  		       ", query_flags=BPF_F_QUERY_EFFECTIVE|0xdeadf00c"
    1290  		       ", attach_flags=BPF_F_ALLOW_MULTI|BPF_F_REPLACE|0xbeefcaf8"
    1291  		       ", prog_ids=" BIG_ADDR_MAYBE("0xffffffffffffffff") "[]"
    1292  		       ", prog_cnt=0}",
    1293  	},
    1294  	{ /* 4 */
    1295  		.data = { .BPF_PROG_QUERY_data = {
    1296  			.target_fd = 3141592653U,
    1297  			.attach_type = 0xfeedface,
    1298  			.query_flags = 0xdeadf00d,
    1299  			.attach_flags = 0xbeefcafe,
    1300  		} },
    1301  		.size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
    1302  		.init_fn = init_BPF_PROG_QUERY_attr4,
    1303  		.print_fn = print_BPF_PROG_QUERY_attr4,
    1304  	},
    1305  	{ /* 5 */
    1306  		.data = { .BPF_PROG_QUERY_data = {
    1307  			.target_fd = 3141592653U,
    1308  			.attach_type = 0xfeedface,
    1309  			.query_flags = 0xdeadf00d,
    1310  			.attach_flags = 0xbeefcafe,
    1311  		} },
    1312  		.size = offsetofend(struct BPF_PROG_QUERY_struct, prog_cnt),
    1313  		.init_fn = init_BPF_PROG_QUERY_attr5,
    1314  		.print_fn = print_BPF_PROG_QUERY_attr5,
    1315  	},
    1316  };
    1317  
    1318  
    1319  static void
    1320  init_BPF_RAW_TRACEPOINT_attr2(struct bpf_attr_check *check, size_t idx)
    1321  {
    1322  	/* TODO: test the 128 byte limit */
    1323  	static const char tp_name[] = "0123456789qwertyuiop0123456789qwe";
    1324  
    1325  	struct BPF_RAW_TRACEPOINT_OPEN_struct *attr =
    1326  		&check->data.BPF_RAW_TRACEPOINT_OPEN_data;
    1327  
    1328  	attr->name = (uintptr_t) tp_name;
    1329  }
    1330  
    1331  static struct bpf_attr_check BPF_RAW_TRACEPOINT_OPEN_checks[] = {
    1332  	{
    1333  		.data = { .BPF_RAW_TRACEPOINT_OPEN_data = { .name = 0 } },
    1334  		.size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
    1335  				    name),
    1336  		.str = "raw_tracepoint={name=NULL, prog_fd=0" FD0_PATH "}",
    1337  	},
    1338  	{ /* 1 */
    1339  		.data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
    1340  			.name = 0xffffffff00000000ULL,
    1341  			.prog_fd = 0xdeadbeef,
    1342  		} },
    1343  		.size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
    1344  				    prog_fd),
    1345  		.str = "raw_tracepoint="
    1346  		       "{name=" BIG_ADDR("0xffffffff00000000", "NULL")
    1347  		       ", prog_fd=-559038737}",
    1348  	},
    1349  	{
    1350  		.data = { .BPF_RAW_TRACEPOINT_OPEN_data = {
    1351  			.prog_fd = 0xdeadbeef,
    1352  		} },
    1353  		.size = offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct,
    1354  				    prog_fd),
    1355  		.init_fn = init_BPF_RAW_TRACEPOINT_attr2,
    1356  		.str = "raw_tracepoint="
    1357  		       "{name=\"0123456789qwertyuiop0123456789qw\"..."
    1358  		       ", prog_fd=-559038737}",
    1359  	}
    1360  };
    1361  
    1362  static void
    1363  init_BPF_BTF_LOAD_attr(struct bpf_attr_check *check, size_t idx)
    1364  {
    1365  	static const char sample_btf_data[] = "bPf\0daTum";
    1366  
    1367  	static char *btf_data;
    1368  	if (!btf_data)
    1369  		btf_data = tail_memdup(sample_btf_data,
    1370  				       sizeof(sample_btf_data) - 1);
    1371  
    1372  	struct BPF_BTF_LOAD_struct *attr = &check->data.BPF_BTF_LOAD_data;
    1373  	attr->btf = (uintptr_t) btf_data;
    1374  }
    1375  
    1376  static struct bpf_attr_check BPF_BTF_LOAD_checks[] = {
    1377  	{
    1378  		.data = { .BPF_BTF_LOAD_data = { .btf = 0 } },
    1379  		.size = offsetofend(struct BPF_BTF_LOAD_struct, btf),
    1380  		.str = "btf=NULL, btf_log_buf=NULL, btf_size=0"
    1381  		       ", btf_log_size=0, btf_log_level=0"
    1382  	},
    1383  	{ /* 1 */
    1384  		.data = { .BPF_BTF_LOAD_data = {
    1385  			.btf_log_buf = 0xfacefeeddeadbeefULL,
    1386  			.btf_size = 9,
    1387  			.btf_log_size = -1U,
    1388  			.btf_log_level = 42
    1389  		} },
    1390  		.size = offsetofend(struct BPF_BTF_LOAD_struct, btf_log_level),
    1391  		.init_fn = init_BPF_BTF_LOAD_attr,
    1392  		.str = "btf=\"bPf\\0daTum\""
    1393  		       ", btf_log_buf=0xfacefeeddeadbeef"
    1394  		       ", btf_size=9"
    1395  		       ", btf_log_size=4294967295"
    1396  		       ", btf_log_level=42"
    1397  	}
    1398  };
    1399  
    1400  static const struct bpf_attr_check BPF_BTF_GET_FD_BY_ID_checks[] = {
    1401  	{
    1402  		.data = { .BPF_BTF_GET_FD_BY_ID_data = { .btf_id = 0xdeadbeef } },
    1403  		.size = offsetofend(struct BPF_BTF_GET_FD_BY_ID_struct, btf_id),
    1404  		.str = "btf_id=3735928559"
    1405  	}
    1406  };
    1407  
    1408  static const struct bpf_attr_check BPF_TASK_FD_QUERY_checks[] = {
    1409  	{
    1410  		.data = { .BPF_TASK_FD_QUERY_data = { .pid = 1735928559 } },
    1411  		.size = offsetofend(struct BPF_TASK_FD_QUERY_struct, pid),
    1412  		.str = "task_fd_query={pid=1735928559, fd=0" FD0_PATH
    1413  		       ", flags=0, buf_len=0, buf=NULL, prog_id=0"
    1414  		       ", fd_type=BPF_FD_TYPE_RAW_TRACEPOINT"
    1415  		       ", probe_offset=0, probe_addr=0}"
    1416  	},
    1417  	{ /* 1 */
    1418  		.data = { .BPF_TASK_FD_QUERY_data = {
    1419  			.pid = 1405705229,
    1420  			.fd = 0xdeadbeef,
    1421  			.flags = 0xfacefeed,
    1422  			.buf_len = 0xdefaced,
    1423  			.buf = 0xfffffffffffffffe,
    1424  			.prog_id = 0xbadc0ded,
    1425  			.fd_type = 5,
    1426  			.probe_offset = 0xfac1fed2fac3fed4,
    1427  			.probe_addr = 0xfac5fed5fac7fed8
    1428  		} },
    1429  		.size = offsetofend(struct BPF_TASK_FD_QUERY_struct, probe_addr),
    1430  		.str = "task_fd_query={pid=1405705229"
    1431  		       ", fd=-559038737"
    1432  		       ", flags=4207869677"
    1433  		       ", buf_len=233811181"
    1434  		       ", buf=" BIG_ADDR("0xfffffffffffffffe", "0xfffffffe")
    1435  		       ", prog_id=3134983661"
    1436  		       ", fd_type=BPF_FD_TYPE_URETPROBE"
    1437  		       ", probe_offset=0xfac1fed2fac3fed4"
    1438  		       ", probe_addr=0xfac5fed5fac7fed8}"
    1439  	}
    1440  };
    1441  
    1442  static const struct bpf_attr_check BPF_MAP_LOOKUP_BATCH_checks[] = {
    1443  	{
    1444  		.data = { .BPF_MAP_LOOKUP_BATCH_data = { .map_fd = -1 } },
    1445  		.size = offsetofend(struct BPF_MAP_LOOKUP_BATCH_struct, map_fd ),
    1446  		.str = "batch={in_batch=NULL, out_batch=NULL, keys=NULL"
    1447  		       ", values=NULL, count=0, map_fd=-1, elem_flags=BPF_ANY"
    1448  		       ", flags=0}"
    1449  	},
    1450  	{
    1451  		.data = { .BPF_MAP_LOOKUP_BATCH_data = {
    1452  			.in_batch = 0xfacefeed,
    1453  			.out_batch = 0xbadc0ded,
    1454  			.keys = 0xdeadf00d,
    1455  			.values = 0xfffffffe,
    1456  			.count = 3,
    1457  			.map_fd = -1,
    1458  			.elem_flags = 4,
    1459  			.flags = 4
    1460  		} },
    1461  		.size = offsetofend(struct BPF_MAP_LOOKUP_BATCH_struct, flags),
    1462  		.str = "batch={in_batch=0xfacefeed, out_batch=0xbadc0ded"
    1463  		       ", keys=0xdeadf00d, values=0xfffffffe, count=3"
    1464  		       ", map_fd=-1, elem_flags=BPF_F_LOCK, flags=0x4}"
    1465  	}
    1466  };
    1467  
    1468  static const struct bpf_attr_check BPF_MAP_UPDATE_BATCH_checks[] = {
    1469  	{
    1470  		.data = { .BPF_MAP_UPDATE_BATCH_data = { .map_fd = -1 } },
    1471  		.size = offsetofend(struct BPF_MAP_UPDATE_BATCH_struct, map_fd ),
    1472  		.str = "batch={keys=NULL, values=NULL, count=0, map_fd=-1"
    1473  		       ", elem_flags=BPF_ANY, flags=0}"
    1474  	},
    1475  	{
    1476  		.data = { .BPF_MAP_UPDATE_BATCH_data = {
    1477  			.keys = 0xdeadf00d,
    1478  			.values = 0xfffffffe,
    1479  			.count = 3,
    1480  			.map_fd = -1,
    1481  			.elem_flags = 4,
    1482  			.flags = 4
    1483  		} },
    1484  		.size = offsetofend(struct BPF_MAP_UPDATE_BATCH_struct, flags),
    1485  		.str = "batch={keys=0xdeadf00d, values=0xfffffffe, count=3"
    1486  		       ", map_fd=-1, elem_flags=BPF_F_LOCK, flags=0x4}"
    1487  	}
    1488  };
    1489  
    1490  static const struct bpf_attr_check BPF_MAP_DELETE_BATCH_checks[] = {
    1491  	{
    1492  		.data = { .BPF_MAP_DELETE_BATCH_data = { .map_fd = -1 } },
    1493  		.size = offsetofend(struct BPF_MAP_DELETE_BATCH_struct, map_fd ),
    1494  		.str = "batch={keys=NULL, count=0, map_fd=-1"
    1495  		       ", elem_flags=BPF_ANY, flags=0}"
    1496  	},
    1497  	{
    1498  		.data = { .BPF_MAP_DELETE_BATCH_data = {
    1499  			.keys = 0xdeadf00d,
    1500  			.count = 3,
    1501  			.map_fd = -1,
    1502  			.elem_flags = 4,
    1503  			.flags = 4
    1504  		} },
    1505  		.size = offsetofend(struct BPF_MAP_DELETE_BATCH_struct, flags),
    1506  		.str = "batch={keys=0xdeadf00d, count=3, map_fd=-1"
    1507  		       ", elem_flags=BPF_F_LOCK, flags=0x4}"
    1508  	}
    1509  };
    1510  
    1511  static void
    1512  init_BPF_LINK_CREATE_attr1(struct bpf_attr_check *check, size_t idx)
    1513  {
    1514  	struct BPF_LINK_CREATE_struct *attr = &check->data.BPF_LINK_CREATE_data;
    1515  
    1516  	attr->attach_type = idx;
    1517  }
    1518  
    1519  static void
    1520  print_BPF_LINK_CREATE_attr1(const struct bpf_attr_check *check,
    1521  			    unsigned long addr, size_t idx)
    1522  {
    1523  	printf("link_create={prog_fd=-1, target_fd=-559038737"
    1524  	       ", attach_type=%s, flags=0x4}",
    1525  	       sprintxval(bpf_attach_type, idx, "BPF_???"));
    1526  }
    1527  
    1528  /* Keep sorted */
    1529  static const uint8_t special_attach_types[] =
    1530  	{ 0, BPF_TRACE_ITER, BPF_PERF_EVENT, BPF_TRACE_KPROBE_MULTI };
    1531  
    1532  static void
    1533  init_BPF_LINK_CREATE_attr2(struct bpf_attr_check *check, size_t idx)
    1534  {
    1535  	struct BPF_LINK_CREATE_struct *attr = &check->data.BPF_LINK_CREATE_data;
    1536  
    1537  	/* skip special_attach_types */
    1538  	for (size_t i = 0; i < ARRAY_SIZE(special_attach_types)
    1539  			   && idx >= special_attach_types[i]; i++, idx++);
    1540  
    1541  	attr->attach_type = idx;
    1542  
    1543  	check->data.char_data[19] = ' ';
    1544  	check->data.char_data[23] = 'O';
    1545  	check->data.char_data[27] = 'H';
    1546  	check->data.char_data[31] = ' ';
    1547  	check->data.char_data[35] = 'H';
    1548  	check->data.char_data[39] = 'A';
    1549  	check->data.char_data[43] = 'I';
    1550  	check->data.char_data[47] = '!';
    1551  }
    1552  
    1553  static void
    1554  print_BPF_LINK_CREATE_attr2(const struct bpf_attr_check *check,
    1555  			    unsigned long addr, size_t idx)
    1556  {
    1557  	/* skip special_attach_types */
    1558  	for (size_t i = 0; i < ARRAY_SIZE(special_attach_types)
    1559  			   && idx >= special_attach_types[i]; i++, idx++);
    1560  
    1561  	printf("link_create={prog_fd=-1, target_fd=-559038737"
    1562  	       ", attach_type=%s, flags=0xbadc0ded}, "
    1563  #if VERBOSE
    1564  	       "extra_data=\"\\x00\\x00\\x00\\x20\\x00\\x00\\x00\\x4f"
    1565  	       "\\x00\\x00\\x00\\x48\\x00\\x00\\x00\\x20\\x00\\x00\\x00\\x48"
    1566  	       "\\x00\\x00\\x00\\x41\\x00\\x00\\x00\\x49\\x00\\x00\\x00\\x21\""
    1567  	       " /* bytes 16..47 */"
    1568  #else
    1569  	       "..."
    1570  #endif
    1571  	       ,
    1572  	       sprintxval(bpf_attach_type, idx, "BPF_???"));
    1573  }
    1574  
    1575  static const int iter_info_data[] = { 0, 42, 314159265, 0xbadc0ded, -1 };
    1576  static int *iter_info_data_p;
    1577  
    1578  static void
    1579  init_BPF_LINK_CREATE_attr7(struct bpf_attr_check *check, size_t idx)
    1580  {
    1581  	struct BPF_LINK_CREATE_struct *attr = &check->data.BPF_LINK_CREATE_data;
    1582  
    1583  	close(iter_info_data[1]);
    1584  
    1585  	if (!iter_info_data_p) {
    1586  		iter_info_data_p = tail_memdup(iter_info_data,
    1587  					       sizeof(iter_info_data));
    1588  	}
    1589  
    1590  	attr->iter_info = (uintptr_t) iter_info_data_p;
    1591  	attr->iter_info_len = ARRAY_SIZE(iter_info_data) + idx;
    1592  }
    1593  
    1594  static void
    1595  print_BPF_LINK_CREATE_attr7(const struct bpf_attr_check *check,
    1596  			    unsigned long addr, size_t idx)
    1597  {
    1598  	printf("link_create={prog_fd=0" FD0_PATH ", target_fd=0" FD0_PATH
    1599  	       ", attach_type=BPF_TRACE_ITER, flags=0"
    1600  	       ", iter_info=[{map={map_fd=0" FD0_PATH "}}, {map={map_fd=42}}"
    1601  	       ", {map={map_fd=314159265}}, {map={map_fd=-1159983635}}"
    1602  	       ", {map={map_fd=-1}}");
    1603  	if (idx) {
    1604  		printf(", ... /* %p */",
    1605  		       iter_info_data_p + ARRAY_SIZE(iter_info_data));
    1606  	}
    1607  	printf("], iter_info_len=%zu}", ARRAY_SIZE(iter_info_data) + idx);
    1608  
    1609  }
    1610  
    1611  static const char *syms_data[] = { "foo", NULL, "OH\0HAI",
    1612  				   "abcdefghijklmnopqrstuvwxyz0123456789" };
    1613  static char **syms_data_p;
    1614  static const uint64_t addrs_data[] = { 0, 1, 0xbadc0ded,
    1615  				       0xfacefeeddeadc0deULL };
    1616  static uint64_t *addrs_data_p;
    1617  
    1618  static_assert(ARRAY_SIZE(syms_data) == ARRAY_SIZE(addrs_data),
    1619  	      "syms_data and addrs_data have to have the same element count");
    1620  
    1621  static void
    1622  init_BPF_LINK_CREATE_attr12(struct bpf_attr_check *check, size_t idx)
    1623  {
    1624  	struct BPF_LINK_CREATE_struct *attr = &check->data.BPF_LINK_CREATE_data;
    1625  
    1626  	if (!syms_data_p)
    1627  		syms_data_p = tail_memdup(syms_data, sizeof(syms_data));
    1628  	if (!addrs_data_p)
    1629  		addrs_data_p = tail_memdup(addrs_data, sizeof(addrs_data));
    1630  
    1631  	attr->kprobe_multi.cnt = ARRAY_SIZE(syms_data) + idx;
    1632  	attr->kprobe_multi.syms = (uintptr_t) syms_data_p;
    1633  	attr->kprobe_multi.addrs = (uintptr_t) addrs_data_p;
    1634  	attr->kprobe_multi.cookies = (uintptr_t) addrs_data_p;
    1635  }
    1636  
    1637  static void
    1638  print_BPF_LINK_CREATE_attr12(const struct bpf_attr_check *check,
    1639  			     unsigned long addr, size_t idx)
    1640  {
    1641  	printf("link_create={prog_fd=0" FD0_PATH ", target_fd=0" FD0_PATH
    1642  	       ", attach_type=BPF_TRACE_KPROBE_MULTI, flags=0"
    1643  	       ", kprobe_multi={flags=BPF_F_KPROBE_MULTI_RETURN|0xfacebeee"
    1644  	       ", cnt=%zu", ARRAY_SIZE(syms_data) + idx);
    1645  	printf(", syms=[\"foo\", NULL, \"OH\""
    1646  	       ", \"abcdefghijklmnopqrstuvwxyz012345\"...");
    1647  	if (idx)
    1648  		printf(", ... /* %p */", syms_data_p + ARRAY_SIZE(syms_data));
    1649  	for (size_t i = 0; i < 2; i++) {
    1650  		printf("], %s=[0, 0x1, 0xbadc0ded, 0xfacefeeddeadc0de",
    1651  		       i ? "cookies" : "addrs");
    1652  		if (idx) {
    1653  			printf(", ... /* %p */",
    1654  			       addrs_data_p + ARRAY_SIZE(addrs_data));
    1655  		}
    1656  	}
    1657  	printf("]}}");
    1658  }
    1659  
    1660  static struct bpf_attr_check BPF_LINK_CREATE_checks[] = {
    1661  	{ /* 0 */
    1662  		.data = { .BPF_LINK_CREATE_data = { .prog_fd = 0, .target_fd = 0 } },
    1663  		.size = offsetofend(struct BPF_LINK_CREATE_struct, target_fd),
    1664  		.str = "link_create={prog_fd=0" FD0_PATH ", target_fd=0" FD0_PATH
    1665  		       ", attach_type=BPF_CGROUP_INET_INGRESS, flags=0}"
    1666  	},
    1667  	{ /* 1 */
    1668  		.data = { .BPF_LINK_CREATE_data = {
    1669  			.prog_fd = -1,
    1670  			.target_fd = 0xdeadbeef,
    1671  			.flags = 4
    1672  		} },
    1673  		.size = offsetofend(struct BPF_LINK_CREATE_struct, flags),
    1674  		.iters = ARRAY_SIZE(bpf_attach_type_xdata),
    1675  		.init_fn = init_BPF_LINK_CREATE_attr1,
    1676  		.print_fn = print_BPF_LINK_CREATE_attr1,
    1677  	},
    1678  	{ /* 2 - all non-special attach_types */
    1679  		.data = { .BPF_LINK_CREATE_data = {
    1680  			.prog_fd = -1,
    1681  			.target_fd = 0xdeadbeef,
    1682  			.attach_type = 5,
    1683  			.flags = 0xbadc0ded
    1684  		} },
    1685  		.size = 48,
    1686  		.iters = ARRAY_SIZE(bpf_attach_type_xdata)
    1687  			 - ARRAY_SIZE(special_attach_types),
    1688  		.init_fn = init_BPF_LINK_CREATE_attr2,
    1689  		.print_fn = print_BPF_LINK_CREATE_attr2,
    1690  	},
    1691  
    1692  	{ /* 3 */
    1693  		.data = { .BPF_LINK_CREATE_data = {
    1694  			.attach_type = 0,
    1695  		} },
    1696  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1697  				    target_btf_id),
    1698  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1699  		       ", attach_type=BPF_CGROUP_INET_INGRESS, flags=0}"
    1700  	},
    1701  	{ /* 4 */
    1702  		.data = { .BPF_LINK_CREATE_data = {
    1703  			.attach_type = 0,
    1704  			.target_btf_id = 0xfacefeed,
    1705  		} },
    1706  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1707  				    target_btf_id),
    1708  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1709  		       ", attach_type=BPF_CGROUP_INET_INGRESS, flags=0"
    1710  		       ", target_btf_id=4207869677}"
    1711  	},
    1712  
    1713  	{ /* 5 */
    1714  		.data = { .BPF_LINK_CREATE_data = {
    1715  			.attach_type = 28,
    1716  		} },
    1717  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1718  				    iter_info_len),
    1719  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1720  		       ", attach_type=BPF_TRACE_ITER, flags=0"
    1721  		       ", iter_info=NULL, iter_info_len=0}"
    1722  	},
    1723  	{ /* 6 */
    1724  		.data = { .BPF_LINK_CREATE_data = {
    1725  			.attach_type = 28,
    1726  			.iter_info = 0xffffffff00000000,
    1727  			.iter_info_len = 0xdeadface,
    1728  		} },
    1729  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1730  				    iter_info_len),
    1731  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1732  		       ", attach_type=BPF_TRACE_ITER, flags=0"
    1733  		       ", iter_info=" BIG_ADDR("0xffffffff00000000", "NULL")
    1734  		       ", iter_info_len=3735943886}"
    1735  	},
    1736  	{ /* 7 */
    1737  		.data = { .BPF_LINK_CREATE_data = {
    1738  			.attach_type = 28,
    1739  		} },
    1740  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1741  				    iter_info_len),
    1742  		.iters = 2,
    1743  		.init_fn = init_BPF_LINK_CREATE_attr7,
    1744  		.print_fn = print_BPF_LINK_CREATE_attr7,
    1745  	},
    1746  
    1747  	{ /* 8 */
    1748  		.data = { .BPF_LINK_CREATE_data = {
    1749  			.attach_type = 41,
    1750  		} },
    1751  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1752  				    perf_event.bpf_cookie),
    1753  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1754  		       ", attach_type=BPF_PERF_EVENT, flags=0"
    1755  		       ", perf_event={bpf_cookie=0}}"
    1756  	},
    1757  	{ /* 9 */
    1758  		.data = { .BPF_LINK_CREATE_data = {
    1759  			.attach_type = 41,
    1760  			.perf_event = { .bpf_cookie = 0xdeadc0defacecafeULL },
    1761  		} },
    1762  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1763  				    perf_event.bpf_cookie),
    1764  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1765  		       ", attach_type=BPF_PERF_EVENT, flags=0"
    1766  		       ", perf_event={bpf_cookie=0xdeadc0defacecafe}}"
    1767  	},
    1768  
    1769  	{ /* 10 */
    1770  		.data = { .BPF_LINK_CREATE_data = {
    1771  			.attach_type = 42,
    1772  		} },
    1773  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1774  				    kprobe_multi.cookies),
    1775  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1776  		       ", attach_type=BPF_TRACE_KPROBE_MULTI, flags=0"
    1777  		       ", kprobe_multi={flags=0, cnt=0, syms=NULL, addrs=NULL"
    1778  		       ", cookies=NULL}}"
    1779  	},
    1780  	{ /* 11 */
    1781  		.data = { .BPF_LINK_CREATE_data = {
    1782  			.attach_type = 42,
    1783  			.kprobe_multi = {
    1784  				.flags = 0xdeadc0de,
    1785  				.cnt = 0xbadfaced,
    1786  				.syms = 0xffffffff00000000,
    1787  				.addrs = 0xffffffff00000000,
    1788  				.cookies = 0xffffffff00000000,
    1789  			},
    1790  		} },
    1791  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1792  				    kprobe_multi.cookies),
    1793  		.str = "link_create={prog_fd=0" FD0_PATH", target_fd=0" FD0_PATH
    1794  		       ", attach_type=BPF_TRACE_KPROBE_MULTI, flags=0"
    1795  		       ", kprobe_multi={flags=0xdeadc0de /* BPF_F_??? */"
    1796  		       ", cnt=3135220973"
    1797  		       ", syms=" BIG_ADDR("0xffffffff00000000", "NULL")
    1798  		       ", addrs=" BIG_ADDR("0xffffffff00000000", "NULL")
    1799  		       ", cookies=" BIG_ADDR("0xffffffff00000000", "NULL") "}}"
    1800  	},
    1801  	/*
    1802  	 * Note that here we rely on the fact that this attach_type has the
    1803  	 * largest de-facto attr_size to get the additional checks performed
    1804  	 * with the last check passed.
    1805  	 */
    1806  	{ /* 12 */
    1807  		.data = { .BPF_LINK_CREATE_data = {
    1808  			.attach_type = 42,
    1809  			.kprobe_multi = {
    1810  				.flags = 0xfacebeef,
    1811  			}
    1812  		} },
    1813  		.size = offsetofend(struct BPF_LINK_CREATE_struct,
    1814  				    kprobe_multi.cookies),
    1815  		.iters = 2,
    1816  		.init_fn = init_BPF_LINK_CREATE_attr12,
    1817  		.print_fn = print_BPF_LINK_CREATE_attr12,
    1818  	},
    1819  };
    1820  
    1821  static const struct bpf_attr_check BPF_LINK_UPDATE_checks[] = {
    1822  	{
    1823  		.data = { .BPF_LINK_UPDATE_data = {
    1824  			.link_fd = -1,
    1825  			.new_prog_fd = -2
    1826  		} },
    1827  		.size = offsetofend(struct BPF_LINK_UPDATE_struct, old_prog_fd),
    1828  		.str = "link_update={link_fd=-1, new_prog_fd=-2, flags=0}"
    1829  	},
    1830  	{
    1831  		.data = { .BPF_LINK_UPDATE_data = {
    1832  			.link_fd = -1,
    1833  			.new_prog_fd = 0xdeadbeef,
    1834  			.flags = 4,
    1835  			.old_prog_fd = 0xdeadf00d
    1836  		} },
    1837  		.size = offsetofend(struct BPF_LINK_UPDATE_struct, old_prog_fd),
    1838  		.str = "link_update={link_fd=-1, new_prog_fd=-559038737"
    1839  		       ", flags=BPF_F_REPLACE, old_prog_fd=-559026163}"
    1840  	}
    1841  };
    1842  
    1843  static const struct bpf_attr_check BPF_LINK_GET_FD_BY_ID_checks[] = {
    1844  	{
    1845  		.data = { .BPF_LINK_GET_FD_BY_ID_data = { .link_id = 0xdeadbeef } },
    1846  		.size = offsetofend(struct BPF_LINK_GET_FD_BY_ID_struct, link_id),
    1847  		.str = "link_id=3735928559"
    1848  	}
    1849  };
    1850  
    1851  static const struct bpf_attr_check BPF_ENABLE_STATS_checks[] = {
    1852  	{
    1853  		.data = { .BPF_ENABLE_STATS_data = { .type = 0 } },
    1854  		.size = offsetofend(struct BPF_ENABLE_STATS_struct, type),
    1855  		.str = "enable_stats={type=BPF_STATS_RUN_TIME}"
    1856  	},
    1857  	{
    1858  		.data = { .BPF_ENABLE_STATS_data = { .type = 1 } },
    1859  		.size = offsetofend(struct BPF_ENABLE_STATS_struct, type),
    1860  		.str = "enable_stats={type=0x1 /* BPF_STATS_??? */}"
    1861  	}
    1862  };
    1863  
    1864  static const struct bpf_attr_check BPF_ITER_CREATE_checks[] = {
    1865  	{
    1866  		.data = { .BPF_ITER_CREATE_data = {
    1867  			.link_fd = -1,
    1868  			.flags = 0
    1869  		} },
    1870  		.size = offsetofend(struct BPF_ITER_CREATE_struct, flags),
    1871  		.str = "iter_create={link_fd=-1, flags=0}"
    1872  	},
    1873  	{
    1874  		.data = { .BPF_ITER_CREATE_data = {
    1875  			.link_fd = -1,
    1876  			.flags = -1U,
    1877  		} },
    1878  		.size = offsetofend(struct BPF_ITER_CREATE_struct, flags),
    1879  		.str = "iter_create={link_fd=-1, flags=0xffffffff}"
    1880  	}
    1881  };
    1882  
    1883  static const struct bpf_attr_check BPF_LINK_DETACH_checks[] = {
    1884  	{
    1885  		.data = { .BPF_LINK_DETACH_data = { .link_fd = -1 } },
    1886  		.size = offsetofend(struct BPF_LINK_DETACH_struct, link_fd),
    1887  		.str = "link_detach={link_fd=-1}"
    1888  	}
    1889  };
    1890  
    1891  static const struct bpf_attr_check BPF_PROG_BIND_MAP_checks[] = {
    1892  	{
    1893  		.data = { .BPF_PROG_BIND_MAP_data = {
    1894  			.prog_fd = -1,
    1895  			.map_fd = -2,
    1896  			.flags = 0
    1897  		} },
    1898  		.size = offsetofend(struct BPF_PROG_BIND_MAP_struct, flags),
    1899  		.str = "prog_bind_map={prog_fd=-1, map_fd=-2, flags=0}"
    1900  	},
    1901  	{
    1902  		.data = { .BPF_PROG_BIND_MAP_data = {
    1903  			.prog_fd = -1,
    1904  			.map_fd = -2,
    1905  			.flags = -1U,
    1906  		} },
    1907  		.size = offsetofend(struct BPF_PROG_BIND_MAP_struct, flags),
    1908  		.str = "prog_bind_map={prog_fd=-1, map_fd=-2, flags=0xffffffff}"
    1909  	}
    1910  };
    1911  
    1912  
    1913  #define CHK(cmd_) \
    1914  	{ \
    1915  		cmd_, #cmd_, \
    1916  		cmd_##_checks, ARRAY_SIZE(cmd_##_checks), \
    1917  	} \
    1918  	/* End of CHK definition */
    1919  
    1920  int
    1921  main(void)
    1922  {
    1923  	static const struct bpf_check checks[] = {
    1924  		CHK(BPF_MAP_CREATE),
    1925  		CHK(BPF_MAP_LOOKUP_ELEM),
    1926  		CHK(BPF_MAP_UPDATE_ELEM),
    1927  		CHK(BPF_MAP_DELETE_ELEM),
    1928  		CHK(BPF_MAP_GET_NEXT_KEY),
    1929  		CHK(BPF_PROG_LOAD),
    1930  		CHK(BPF_OBJ_PIN),
    1931  		CHK(BPF_OBJ_GET),
    1932  		CHK(BPF_PROG_ATTACH),
    1933  		CHK(BPF_PROG_DETACH),
    1934  		CHK(BPF_PROG_TEST_RUN),
    1935  		CHK(BPF_PROG_GET_NEXT_ID),
    1936  		CHK(BPF_MAP_GET_NEXT_ID),
    1937  		CHK(BPF_PROG_GET_FD_BY_ID),
    1938  		CHK(BPF_MAP_GET_FD_BY_ID),
    1939  		CHK(BPF_OBJ_GET_INFO_BY_FD),
    1940  		CHK(BPF_PROG_QUERY),
    1941  		CHK(BPF_RAW_TRACEPOINT_OPEN),
    1942  		CHK(BPF_BTF_LOAD),
    1943  		CHK(BPF_BTF_GET_FD_BY_ID),
    1944  		CHK(BPF_TASK_FD_QUERY),
    1945  		CHK(BPF_MAP_LOOKUP_AND_DELETE_ELEM),
    1946  		CHK(BPF_MAP_FREEZE),
    1947  		CHK(BPF_BTF_GET_NEXT_ID),
    1948  		CHK(BPF_MAP_LOOKUP_BATCH),
    1949  		CHK(BPF_MAP_UPDATE_BATCH),
    1950  		CHK(BPF_MAP_DELETE_BATCH),
    1951  		CHK(BPF_LINK_CREATE),
    1952  		CHK(BPF_LINK_UPDATE),
    1953  		CHK(BPF_LINK_GET_NEXT_ID),
    1954  		CHK(BPF_LINK_GET_FD_BY_ID),
    1955  		CHK(BPF_ENABLE_STATS),
    1956  		CHK(BPF_ITER_CREATE),
    1957  		CHK(BPF_LINK_DETACH),
    1958  		CHK(BPF_PROG_BIND_MAP),
    1959  	};
    1960  
    1961  	page_size = get_page_size();
    1962  	end_of_page = (unsigned long) tail_alloc(1) + 1;
    1963  
    1964  	at_fdcwd_str =
    1965  #ifdef YFLAG
    1966  		xasprintf("AT_FDCWD<%s>", get_fd_path(get_dir_fd(".")));
    1967  #else
    1968  		"AT_FDCWD";
    1969  #endif
    1970  
    1971  	for (size_t i = 0; i < ARRAY_SIZE(checks); i++)
    1972  		test_bpf(checks + i);
    1973  
    1974  	sys_bpf(0xfacefeed, 0, (kernel_ulong_t) 0xfacefeedbadc0dedULL);
    1975  	printf("bpf(0xfacefeed /* BPF_??? */, NULL, %u) = %s\n",
    1976  	       0xbadc0dedu, errstr);
    1977  
    1978  	sys_bpf(0xfacefeed, end_of_page, 40);
    1979  	printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
    1980  	       end_of_page, errstr);
    1981  
    1982  	puts("+++ exited with 0 +++");
    1983  	return 0;
    1984  }