int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	const int fd = create_nl_socket(NETLINK_ROUTE);
	void *nlh0 = tail_alloc(NLMSG_SPACE(hdrlen));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	const uint32_t num = 0xabacdbcd;
	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
				  init_ifinfomsg, print_ifinfomsg,
				  IFLA_PORT_VF, pattern, num,
				  printf("%u", num));

#ifdef HAVE_STRUCT_IFLA_PORT_VSI
	static const struct ifla_port_vsi vsi = {
		.vsi_mgr_id = 0xab,
		.vsi_type_id = "abc",
		.vsi_type_version = 0xef
	};
	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
				  init_ifinfomsg, print_ifinfomsg,
				  IFLA_PORT_VSI_TYPE, pattern, vsi,
				  PRINT_FIELD_U("{", vsi, vsi_mgr_id);
				  printf(", vsi_type_id=\"\\x61\\x62\\x63\"");
				  PRINT_FIELD_U(", ", vsi, vsi_type_version);
				  printf("}"));
#endif

	puts("+++ exited with 0 +++");
	return 0;
}
int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	const int fd = create_nl_socket(NETLINK_ROUTE);

	const unsigned int hdrlen = sizeof(struct netconfmsg);
	void *nlh0 = tail_alloc(NLMSG_SPACE(hdrlen));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
	char nla_type_str[256];
	sprintf(nla_type_str, "%#x /* NETCONFA_??? */", nla_type);
	TEST_NLATTR_(fd, nlh0, hdrlen,
		     init_netconfmsg, print_netconfmsg,
		     nla_type, nla_type_str,
		     4, pattern, 4,
		     print_quoted_hex(pattern, 4));

	puts("+++ exited with 0 +++");
	return 0;
}
int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	const int fd = create_nl_socket(NETLINK_ROUTE);
	const unsigned int hdrlen = sizeof(struct ndmsg);
	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
				   NLA_HDRLEN + sizeof(struct nda_cacheinfo));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
	char nla_type_str[256];
	sprintf(nla_type_str, "%#x /* NDA_??? */", nla_type);
	TEST_NLATTR_(fd, nlh0, hdrlen,
		     init_ndmsg, print_ndmsg,
		     nla_type, nla_type_str,
		     4, pattern, 4,
		     print_quoted_hex(pattern, 4));

	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ndmsg, print_ndmsg,
		    NDA_DST, 4, pattern, 4,
		    print_quoted_hex(pattern, 4));

	static const struct nda_cacheinfo ci = {
		.ndm_confirmed = 0xabcdedad,
		.ndm_used = 0xbcdaedad,
		.ndm_updated = 0xcdbadeda,
		.ndm_refcnt = 0xdeadbeda
	};

	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
			   init_ndmsg, print_ndmsg,
			   NDA_CACHEINFO, pattern, ci,
			   PRINT_FIELD_U("{", ci, ndm_confirmed);
			   PRINT_FIELD_U(", ", ci, ndm_used);
			   PRINT_FIELD_U(", ", ci, ndm_updated);
			   PRINT_FIELD_U(", ", ci, ndm_refcnt);
			   printf("}"));

	const uint16_t port = 0xabcd;
	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
			   init_ndmsg, print_ndmsg,
			   NDA_PORT, pattern, port,
			   printf("htons(%u)", ntohs(port)));

	puts("+++ exited with 0 +++");
	return 0;
}
int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	const uint32_t ifindex = ifindex_lo();
	const uint8_t type = MDB_RTR_TYPE_DISABLED;
	static const struct nlattr nla = {
		.nla_len = NLA_HDRLEN + sizeof(type),
		.nla_type = MDBA_ROUTER_PATTR_TYPE
	};
	char buf[NLMSG_ALIGN(ifindex) + NLA_HDRLEN + sizeof(type)];

	const int fd = create_nl_socket(NETLINK_ROUTE);

	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
				   NLA_HDRLEN + sizeof(buf));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
				  init_br_port_msg, print_br_port_msg,
				  MDBA_ROUTER_PORT, pattern, ifindex,
				  printf(IFINDEX_LO_STR));

	memcpy(buf, &ifindex, sizeof(ifindex));
	memcpy(buf + NLMSG_ALIGN(ifindex), &nla, sizeof(nla));
	memcpy(buf + NLMSG_ALIGN(ifindex) + NLA_HDRLEN, &type, sizeof(type));
	TEST_NLATTR(fd, nlh0 - NLA_HDRLEN, hdrlen + NLA_HDRLEN,
		    init_br_port_msg, print_br_port_msg,
		    MDBA_ROUTER_PORT, sizeof(buf), buf, sizeof(buf),
		    printf(IFINDEX_LO_STR
			   ", {{nla_len=%u, nla_type=MDBA_ROUTER_PATTR_TYPE}"
			   ", MDB_RTR_TYPE_DISABLED}}",
			   nla.nla_len));

	puts("+++ exited with 0 +++");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("HAVE_STRUCT_BR_PORT_MSG")
Beispiel #5
0
int
main(void)
{
	static const kernel_ulong_t unknown_perf_cmd =
		(kernel_ulong_t) 0xbadc0dedfeed24edULL;
	static const kernel_ulong_t magic =
		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
	static const uint64_t magic64 = 0xfacefeeddeadc0deULL;
	static const char str[] = STR16 STR16 STR16 STR16;

	static struct {
		unsigned int cmd;
		const char *str;
	} flag_iocs[] = {
		{ ARG_STR(PERF_EVENT_IOC_ENABLE) },
		{ ARG_STR(PERF_EVENT_IOC_DISABLE) },
		{ ARG_STR(PERF_EVENT_IOC_RESET) },
	};

	TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_ptr);
	uint64_t *const u64_efault = u64_ptr + 1;
	uint32_t *const u32_arr = tail_alloc(sizeof(uint32_t) * 4);
	uint32_t *const u32_efault = u32_arr + 4;
	char *const str_ptr = tail_memdup(str, sizeof(str));
	char *const str_efault = str_ptr + sizeof(str);
	TAIL_ALLOC_OBJECT_CONST_PTR(struct perf_event_attr, pea_ptr);

	*u64_ptr = magic64;
	fill_memory_ex(pea_ptr, sizeof(*pea_ptr), 0xaa, 0x55);

	/* Unknown perf commands */
	sys_ioctl(-1, unknown_perf_cmd, magic);
	printf("ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE%s, 0x24, %#x, %#x), "
	       "%#lx) = -1 EBADF (%m)\n",
	       _IOC_DIR((unsigned int) unknown_perf_cmd) & _IOC_NONE ?
	       "|_IOC_NONE" : "",
	       _IOC_NR((unsigned int) unknown_perf_cmd),
	       _IOC_SIZE((unsigned int) unknown_perf_cmd),
	       (unsigned long) magic);

	sys_ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1, magic);
	printf("ioctl(-1, _IOC(_IOC_WRITE, 0x24, %#x, %#x), %#lx)"
	       " = -1 EBADF (%m)\n",
	       (unsigned int) _IOC_NR(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
	       (unsigned int) _IOC_SIZE(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
	       (unsigned long) magic);

	/* PERF_EVENT_IOC_{ENABLE,DISABLE,RESET} */
	for (unsigned i = 0; i < ARRAY_SIZE(flag_iocs); i++) {
		ioctl(-1, flag_iocs[i].cmd, 0);
		printf("ioctl(-1, %s, 0) = -1 EBADF (%m)\n", flag_iocs[i].str);

		ioctl(-1, flag_iocs[i].cmd, 1);
		printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP) = -1 EBADF (%m)\n",
		       flag_iocs[i].str);

		ioctl(-1, flag_iocs[i].cmd, 2);
		printf("ioctl(-1, %s, 0x2 /* PERF_IOC_FLAG_??? */) "
		       "= -1 EBADF (%m)\n",
		       flag_iocs[i].str);

		sys_ioctl(-1, flag_iocs[i].cmd, magic);
		printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP|%#x) "
		       "= -1 EBADF (%m)\n",
		       flag_iocs[i].str, (unsigned int) magic & ~1U);
	}

	/* PERF_EVENT_IOC_REFRESH */
	sys_ioctl(-1, PERF_EVENT_IOC_REFRESH, magic);
	printf("ioctl(-1, PERF_EVENT_IOC_REFRESH, %d) = -1 EBADF (%m)\n",
	       (int) magic);

	/* PERF_EVENT_IOC_PERIOD */
	ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL);
	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL) = -1 EBADF (%m)\n");

	ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_efault);
	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, %p) = -1 EBADF (%m)\n",
	      u64_efault);

	ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_ptr);
	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, [%" PRIu64 "])"
	       " = -1 EBADF (%m)\n",
	       magic64);

	/* PERF_EVENT_IOC_SET_OUTPUT */
	sys_ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, magic);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, %d) = -1 EBADF (%m)\n",
	       (int) magic);

	/* PERF_EVENT_IOC_SET_FILTER */
	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL) = -1 EBADF (%m)\n");

	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_efault);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p) = -1 EBADF (%m)\n",
	       str_efault);

	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\"...)"
	       " = -1 EBADF (%m)\n",
	       str_ptr);

	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\")"
	       " = -1 EBADF (%m)\n",
	       str_ptr + 40);

	str_ptr[sizeof(str) - 1] = '0';
	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p)"
	       " = -1 EBADF (%m)\n",
	       str_ptr + 40);

	/* PERF_EVENT_IOC_ID */
	ioctl(-1, PERF_EVENT_IOC_ID, NULL);
	printf("ioctl(-1, PERF_EVENT_IOC_ID, NULL) = -1 EBADF (%m)\n");

	ioctl(-1, PERF_EVENT_IOC_ID, u64_efault);
	printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
	      u64_efault);

	ioctl(-1, PERF_EVENT_IOC_ID, u64_ptr);
	printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
	       u64_ptr);

	/* PERF_EVENT_IOC_SET_BPF */
	sys_ioctl(-1, PERF_EVENT_IOC_SET_BPF, magic);
	printf("ioctl(-1, PERF_EVENT_IOC_SET_BPF, %d) = -1 EBADF (%m)\n",
	       (int) magic);

	/* PERF_EVENT_IOC_PAUSE_OUTPUT */
	sys_ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, magic);
	printf("ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, %lu) = -1 EBADF (%m)\n",
	       (unsigned long) magic);

	/* PERF_EVENT_IOC_QUERY_BPF */
	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL);
	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL) = -1 EBADF (%m)\n");

	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_efault);
	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, %p) = -1 EBADF (%m)\n",
	       u32_efault);

	u32_arr[0] = 0xbadc0ded;
	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr);
	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661, ...})"
	       " = -1 EBADF (%m)\n");

	/* PERF_EVENT_IOC_MODIFY_ATTRIBUTES */
	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL);
	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL)"
	       " = -1 EBADF (%m)\n");

	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr + 1);
	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, %p)"
	       " = -1 EBADF (%m)\n",
	       pea_ptr + 1);

	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES"
	       ", {type=%#x /* PERF_TYPE_??? */"
	       ", size=%#x /* PERF_ATTR_SIZE_??? */"
	       ", config=%#llx, ...}) = -1 EBADF (%m)\n",
	       (unsigned int) pea_ptr->type,
	       (unsigned int) pea_ptr->size,
	       (unsigned long long) pea_ptr->config);
	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr);

	puts("+++ exited with 0 +++");
	return 0;
}
Beispiel #6
0
static void
test_bpf(const struct bpf_check *cmd_check)
{
	const struct bpf_attr_check *check = 0;
	const union bpf_attr_data *data = 0;
	unsigned int offset = 0;

	/* zero addr */
	sys_bpf(cmd_check->cmd, 0, long_bits | sizeof(union bpf_attr_data));
	printf("bpf(%s, NULL, %u) = %s\n",
	       cmd_check->cmd_str, sizeof_attr, errstr);

	/* zero size */
	unsigned long addr = end_of_page - sizeof_attr;
	sys_bpf(cmd_check->cmd, addr, long_bits);
	printf("bpf(%s, %#lx, 0) = %s\n",
	       cmd_check->cmd_str, addr, errstr);

	for (size_t i = 0; i < cmd_check->count; i++) {
		check = &cmd_check->checks[i];
		if (check->init_fn)
			check->init_fn((struct bpf_attr_check *) check);
		data = &check->data;
		offset = check->size;

		addr = end_of_page - offset;
		memcpy((void *) addr, data, offset);

		/* starting piece of bpf_attr_data */
		sys_bpf(cmd_check->cmd, addr, offset);
		printf("bpf(%s, {", cmd_check->cmd_str);
		print_bpf_attr(check, addr);
		printf("}, %u) = %s\n", offset, errstr);

		/* short read of the starting piece */
		sys_bpf(cmd_check->cmd, addr + 1, offset);
		printf("bpf(%s, %#lx, %u) = %s\n",
		       cmd_check->cmd_str, addr + 1, offset, errstr);
	}

	if (offset < sizeof_attr) {
		/* short read of the whole bpf_attr_data */
		memcpy((void *) end_of_page - sizeof_attr + 1, data, offset);
		addr = end_of_page - sizeof_attr + 1;
		memset((void *) addr + offset, 0, sizeof_attr - offset - 1);
		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
		printf("bpf(%s, %#lx, %u) = %s\n",
		       cmd_check->cmd_str, addr, sizeof_attr, errstr);

		/* the whole bpf_attr_data */
		memcpy((void *) end_of_page - sizeof_attr, data, offset);
		addr = end_of_page - sizeof_attr;
		memset((void *) addr + offset, 0, sizeof_attr - offset);
		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
		printf("bpf(%s, {", cmd_check->cmd_str);
		print_bpf_attr(check, addr);
		printf("}, %u) = %s\n", sizeof_attr, errstr);

		/* non-zero bytes after the relevant part */
		fill_memory_ex((void *) addr + offset,
			       sizeof_attr - offset, '0', 10);
		sys_bpf(cmd_check->cmd, addr, sizeof_attr);
		printf("bpf(%s, {", cmd_check->cmd_str);
		print_bpf_attr(check, addr);
		printf(", ");
		print_extra_data((char *) addr, offset,
				 sizeof_attr - offset);
		printf("}, %u) = %s\n", sizeof_attr, errstr);
	}

	/* short read of the whole page */
	memcpy((void *) end_of_page - page_size + 1, data, offset);
	addr = end_of_page - page_size + 1;
	memset((void *) addr + offset, 0, page_size - offset - 1);
	sys_bpf(cmd_check->cmd, addr, page_size);
	printf("bpf(%s, %#lx, %u) = %s\n",
	       cmd_check->cmd_str, addr, page_size, errstr);

	/* the whole page */
	memcpy((void *) end_of_page - page_size, data, offset);
	addr = end_of_page - page_size;
	memset((void *) addr + offset, 0, page_size - offset);
	sys_bpf(cmd_check->cmd, addr, page_size);
	printf("bpf(%s, {", cmd_check->cmd_str);
	print_bpf_attr(check, addr);
	printf("}, %u) = %s\n", page_size, errstr);

	/* non-zero bytes after the whole bpf_attr_data */
	fill_memory_ex((void *) addr + offset,
		       page_size - offset, '0', 10);
	sys_bpf(cmd_check->cmd, addr, page_size);
	printf("bpf(%s, {", cmd_check->cmd_str);
	print_bpf_attr(check, addr);
	printf(", ");
	print_extra_data((char *) addr, offset,
			 page_size - offset);
	printf("}, %u) = %s\n", page_size, errstr);

	/* more than a page */
	sys_bpf(cmd_check->cmd, addr, page_size + 1);
	printf("bpf(%s, %#lx, %u) = %s\n",
	       cmd_check->cmd_str, addr, page_size + 1, errstr);
}
Beispiel #7
0
int
main(void)
{
	char bogus_special_str[sizeof(void *) * 2 + sizeof("0x")];
	char bogus_addr_str[sizeof(void *) * 2 + sizeof("0x")];
	char unterminated_str[sizeof(void *) * 2 + sizeof("0x")];

	long rc;
	struct fs_disk_quota *xdq = tail_alloc(sizeof(*xdq));
	struct fs_quota_stat *xqstat = tail_alloc(sizeof(*xqstat));
	struct fs_quota_statv *xqstatv = tail_alloc(sizeof(*xqstatv));
	uint32_t *flags = tail_alloc(sizeof(*flags));
	char *unterminated = tail_memdup(unterminated_data,
		sizeof(unterminated_data));

	snprintf(bogus_special_str, sizeof(bogus_special_str), "%p",
		 bogus_special);
	snprintf(bogus_addr_str, sizeof(bogus_addr_str), "%p",
		 bogus_addr);
	snprintf(unterminated_str, sizeof(unterminated_str), "%p",
		 unterminated);


	/* Q_XQUOTAON */

	*flags = 0xdeadbeef;

	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    ARG_STR(QCMD(Q_XQUOTAON, USRQUOTA)),
		    ARG_STR("/dev/bogus/"), flags,
		    "[XFS_QUOTA_UDQ_ACCT|XFS_QUOTA_UDQ_ENFD"
		    "|XFS_QUOTA_GDQ_ACCT|XFS_QUOTA_GDQ_ENFD"
		    "|XFS_QUOTA_PDQ_ENFD|0xdeadbec0]");

	rc = syscall(__NR_quotactl, QCMD(Q_XQUOTAON, 0xfacefeed), bogus_dev,
		     bogus_id, bogus_addr);
	printf("quotactl(QCMD(Q_XQUOTAON, %#x /* ???QUOTA */)"
	       ", %s, %p) = %s\n",
	       QCMD_TYPE(QCMD(Q_XQUOTAON, 0xfacefeed)),
	       bogus_dev_str, bogus_addr, sprintrc(rc));


	/* Q_XQUOTAOFF */

	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    ARG_STR(QCMD(Q_XQUOTAOFF, USRQUOTA)),
		    bogus_special, bogus_special_str,
		    bogus_addr, bogus_addr_str);
	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    ARG_STR(QCMD(Q_XQUOTAOFF, GRPQUOTA)),
		    ARG_STR("/dev/bogus/"),
		    ARG_STR(NULL));
	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    QCMD(Q_XQUOTAOFF, 3),
		    "QCMD(Q_XQUOTAOFF, 0x3 /* ???QUOTA */)",
		    ARG_STR("/dev/bogus/"), flags,
		    "[XFS_QUOTA_UDQ_ACCT|XFS_QUOTA_UDQ_ENFD"
		    "|XFS_QUOTA_GDQ_ACCT|XFS_QUOTA_GDQ_ENFD"
		    "|XFS_QUOTA_PDQ_ENFD|0xdeadbec0]");


	/* Q_XGETQUOTA */

	/* Trying our best to get successful result */
	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, USRQUOTA)),
		    ARG_STR("/dev/sda1"), getuid(), xdq, print_xdisk_quota,
		    (intptr_t) 1);

	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, GRPQUOTA)),
		    ARG_STR(NULL), -1, xdq, print_xdisk_quota, (intptr_t) 2);


	/* Q_XGETNEXTQUOTA */

	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XGETNEXTQUOTA, USRQUOTA)),
		    ARG_STR("/dev/sda1"), 0, xdq, print_xdisk_quota,
		    (intptr_t) 1);


	/* Q_XSETQLIM */

	check_quota(CQF_NONE, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
		    bogus_special, bogus_special_str, 0, bogus_addr);

	fill_memory_ex((char *) xdq, sizeof(*xdq), 0x8e);

	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
		    bogus_dev, bogus_dev_str, 3141592653U,
		    xdq, print_xdisk_quota, (intptr_t) 0);


	/* Q_XGETQSTAT */

	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
		    ARG_STR("/dev/sda1"), xqstat, print_xquota_stat, (intptr_t) 1);

	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
		    ARG_STR(QCMD(Q_XGETQSTATV, PRJQUOTA)),
		    unterminated, unterminated_str,
		    xqstat + 1, print_xquota_stat, (intptr_t) 2);


	/* Q_XGETQSTATV */

	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
		    ARG_STR("/dev/sda1"), xqstatv, print_xquota_statv, 1);

	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
		    ARG_STR(QCMD(Q_XGETQSTATV, GRPQUOTA)),
		    ARG_STR(NULL), xqstatv, print_xquota_statv, (intptr_t) 2);


	/* Q_XQUOTARM */

	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    ARG_STR(QCMD(Q_XQUOTARM, PRJQUOTA)),
		    bogus_special, bogus_special_str, ARG_STR(NULL));
	check_quota(CQF_ID_SKIP,
		    ARG_STR(QCMD(Q_XQUOTARM, USRQUOTA)),
		    unterminated, unterminated_str, flags + 1);

	*flags = 0xdeadbeef;
	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
		    ARG_STR(QCMD(Q_XQUOTARM, GRPQUOTA)),
		    ARG_STR(NULL), flags,
		    "[XFS_USER_QUOTA|XFS_PROJ_QUOTA"
		    "|XFS_GROUP_QUOTA|0xdeadbee8]");


	/* Q_XQUOTASYNC */

	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
		    ARG_STR(QCMD(Q_XQUOTASYNC, USRQUOTA)),
		    bogus_special, bogus_special_str);
	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
		    QCMD(Q_XQUOTASYNC, 0xfff),
		    "QCMD(Q_XQUOTASYNC, 0xff /* ???QUOTA */)",
		    ARG_STR(NULL));

	puts("+++ exited with 0 +++");

	return 0;
}
int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	static const struct rtnl_link_stats st = {
		.rx_packets = 0xabcdefac,
		.tx_packets = 0xbcdacdab,
		.rx_bytes = 0xcdbafaab,
		.tx_bytes = 0xdafabadb,
		.rx_errors = 0xeabcdaeb,
		.tx_errors = 0xfefabeab,
		.rx_dropped = 0xadbafafb,
		.tx_dropped = 0xbdffabda,
		.multicast = 0xcdabdfea,
		.collisions = 0xefadbaeb,
		.rx_length_errors = 0xfabffabd,
		.rx_over_errors = 0xafbafabc,
		.rx_crc_errors = 0xbfdabdad,
		.rx_frame_errors = 0xcfdabfad,
		.rx_fifo_errors = 0xddfdebad,
		.rx_missed_errors = 0xefabdcba,
		.tx_aborted_errors = 0xefdadbfa,
		.tx_carrier_errors = 0xfaefbada,
		.tx_fifo_errors = 0xaebdffab,
		.tx_heartbeat_errors = 0xbadebaaf,
		.tx_window_errors = 0xcdafbada,
		.rx_compressed = 0xdeffadbd,
		.tx_compressed = 0xefdadfab
	};
	const int fd = create_nl_socket(NETLINK_ROUTE);
	const unsigned int hdrlen = sizeof(struct ifinfomsg);
	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
				   NLA_HDRLEN + sizeof(st));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
	char nla_type_str[256];
	sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type);
	TEST_NLATTR_(fd, nlh0, hdrlen,
		     init_ifinfomsg, print_ifinfomsg,
		     nla_type, nla_type_str,
		     4, pattern, 4,
		     print_quoted_hex(pattern, 4));

	const int32_t netnsid = 0xacbdabda;
	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
			   init_ifinfomsg, print_ifinfomsg,
			   IFLA_LINK_NETNSID, pattern, netnsid,
			   printf("%d", netnsid));

	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
			   init_ifinfomsg, print_ifinfomsg,
			   IFLA_STATS, pattern, st,
			   PRINT_FIELD_U("{", st, rx_packets);
			   PRINT_FIELD_U(", ", st, tx_packets);
			   PRINT_FIELD_U(", ", st, rx_bytes);
			   PRINT_FIELD_U(", ", st, tx_bytes);
			   PRINT_FIELD_U(", ", st, rx_errors);
			   PRINT_FIELD_U(", ", st, tx_errors);
			   PRINT_FIELD_U(", ", st, rx_dropped);
			   PRINT_FIELD_U(", ", st, tx_dropped);
			   PRINT_FIELD_U(", ", st, multicast);
			   PRINT_FIELD_U(", ", st, collisions);
			   PRINT_FIELD_U(", ", st, rx_length_errors);
			   PRINT_FIELD_U(", ", st, rx_over_errors);
			   PRINT_FIELD_U(", ", st, rx_crc_errors);
			   PRINT_FIELD_U(", ", st, rx_frame_errors);
			   PRINT_FIELD_U(", ", st, rx_fifo_errors);
			   PRINT_FIELD_U(", ", st, rx_missed_errors);
			   PRINT_FIELD_U(", ", st, tx_aborted_errors);
			   PRINT_FIELD_U(", ", st, tx_carrier_errors);
			   PRINT_FIELD_U(", ", st, tx_fifo_errors);
			   PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
			   PRINT_FIELD_U(", ", st, tx_window_errors);
			   PRINT_FIELD_U(", ", st, rx_compressed);
			   PRINT_FIELD_U(", ", st, tx_compressed);
#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
			   PRINT_FIELD_U(", ", st, rx_nohandler);
#endif
			   printf("}"));

#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
	const unsigned int sizeof_stats =
		offsetofend(struct rtnl_link_stats, tx_compressed);
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_STATS, sizeof_stats, &st, sizeof_stats,
		    PRINT_FIELD_U("{", st, rx_packets);
		    PRINT_FIELD_U(", ", st, tx_packets);
		    PRINT_FIELD_U(", ", st, rx_bytes);
		    PRINT_FIELD_U(", ", st, tx_bytes);
		    PRINT_FIELD_U(", ", st, rx_errors);
		    PRINT_FIELD_U(", ", st, tx_errors);
		    PRINT_FIELD_U(", ", st, rx_dropped);
		    PRINT_FIELD_U(", ", st, tx_dropped);
		    PRINT_FIELD_U(", ", st, multicast);
		    PRINT_FIELD_U(", ", st, collisions);
		    PRINT_FIELD_U(", ", st, rx_length_errors);
		    PRINT_FIELD_U(", ", st, rx_over_errors);
		    PRINT_FIELD_U(", ", st, rx_crc_errors);
		    PRINT_FIELD_U(", ", st, rx_frame_errors);
		    PRINT_FIELD_U(", ", st, rx_fifo_errors);
		    PRINT_FIELD_U(", ", st, rx_missed_errors);
		    PRINT_FIELD_U(", ", st, tx_aborted_errors);
		    PRINT_FIELD_U(", ", st, tx_carrier_errors);
		    PRINT_FIELD_U(", ", st, tx_fifo_errors);
		    PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
		    PRINT_FIELD_U(", ", st, tx_window_errors);
		    PRINT_FIELD_U(", ", st, rx_compressed);
		    PRINT_FIELD_U(", ", st, tx_compressed);
		    printf("}"));
#endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */

	static const struct rtnl_link_ifmap map = {
		.mem_start = 0xadcbefedefbcdedb,
		.mem_end = 0xefcbeabdecdcdefa,
		.base_addr = 0xaddbeabdfaacdbae,
		.irq = 0xefaf,
		.dma = 0xab,
		.port = 0xcd
	};
	const unsigned int sizeof_ifmap =
		offsetofend(struct rtnl_link_ifmap, port);
	const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN
				  ? DEFAULT_STRLEN
				  : (int) sizeof_ifmap - 1;
	/* len < sizeof_ifmap */
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_MAP, plen, pattern, plen,
		    print_quoted_hex(pattern, plen));

	/* short read of sizeof_ifmap */
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1,
		    printf("%p", RTA_DATA(TEST_NLATTR_nla)));

	/* sizeof_ifmap */
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap,
		    PRINT_FIELD_X("{", map, mem_start);
		    PRINT_FIELD_X(", ", map, mem_end);
		    PRINT_FIELD_X(", ", map, base_addr);
		    PRINT_FIELD_U(", ", map, irq);
		    PRINT_FIELD_U(", ", map, dma);
		    PRINT_FIELD_U(", ", map, port);
		    printf("}"));

#ifdef HAVE_STRUCT_RTNL_LINK_STATS64
	static const struct rtnl_link_stats64 st64 = {
		.rx_packets = 0xadcbefedefbcdedb,
		.tx_packets = 0xbdabdedabdcdeabd,
		.rx_bytes = 0xcdbaefbaeadfabec,
		.tx_bytes = 0xdbaedbafabbeacdb,
		.rx_errors = 0xefabfdaefabaefab,
		.tx_errors = 0xfaebfabfabbaeabf,
		.rx_dropped = 0xacdbaedbadbabeba,
		.tx_dropped = 0xbcdeffebdabeadbe,
		.multicast = 0xeeffbaeabaeffabe,
		.collisions = 0xffbaefcefbafacef,
		.rx_length_errors = 0xaabbdeabceffdecb,
		.rx_over_errors = 0xbbdcdadebadeaeed,
		.rx_crc_errors= 0xccdeabecefaedbef,
		.rx_frame_errors = 0xddbedaedebcedaef,
		.rx_fifo_errors = 0xeffbadefafdaeaab,
		.rx_missed_errors = 0xfefaebccceadeecd,
		.tx_aborted_errors = 0xabcdadefcdadef,
		.tx_carrier_errors = 0xbccdafaeeaaefe,
		.tx_fifo_errors = 0xcddefdbedeadce,
		.tx_heartbeat_errors = 0xedaededdadcdea,
		.tx_window_errors = 0xfdacdeaccedcda,
		.rx_compressed = 0xacdbbcacdbccef,
		.tx_compressed = 0xbcdadefcdedfea
	};
	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
			   init_ifinfomsg, print_ifinfomsg,
			   IFLA_STATS64, pattern, st64,
			   PRINT_FIELD_U("{", st64, rx_packets);
			   PRINT_FIELD_U(", ", st64, tx_packets);
			   PRINT_FIELD_U(", ", st64, rx_bytes);
			   PRINT_FIELD_U(", ", st64, tx_bytes);
			   PRINT_FIELD_U(", ", st64, rx_errors);
			   PRINT_FIELD_U(", ", st64, tx_errors);
			   PRINT_FIELD_U(", ", st64, rx_dropped);
			   PRINT_FIELD_U(", ", st64, tx_dropped);
			   PRINT_FIELD_U(", ", st64, multicast);
			   PRINT_FIELD_U(", ", st64, collisions);
			   PRINT_FIELD_U(", ", st64, rx_length_errors);
			   PRINT_FIELD_U(", ", st64, rx_over_errors);
			   PRINT_FIELD_U(", ", st64, rx_crc_errors);
			   PRINT_FIELD_U(", ", st64, rx_frame_errors);
			   PRINT_FIELD_U(", ", st64, rx_fifo_errors);
			   PRINT_FIELD_U(", ", st64, rx_missed_errors);
			   PRINT_FIELD_U(", ", st64, tx_aborted_errors);
			   PRINT_FIELD_U(", ", st64, tx_carrier_errors);
			   PRINT_FIELD_U(", ", st64, tx_fifo_errors);
			   PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
			   PRINT_FIELD_U(", ", st64, tx_window_errors);
			   PRINT_FIELD_U(", ", st64, rx_compressed);
			   PRINT_FIELD_U(", ", st64, tx_compressed);
#ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
			   PRINT_FIELD_U(", ", st64, rx_nohandler);
#endif
			   printf("}"));

#ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
	const unsigned int sizeof_stats64 =
		offsetofend(struct rtnl_link_stats64, tx_compressed);
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64,
		    PRINT_FIELD_U("{", st64, rx_packets);
		    PRINT_FIELD_U(", ", st64, tx_packets);
		    PRINT_FIELD_U(", ", st64, rx_bytes);
		    PRINT_FIELD_U(", ", st64, tx_bytes);
		    PRINT_FIELD_U(", ", st64, rx_errors);
		    PRINT_FIELD_U(", ", st64, tx_errors);
		    PRINT_FIELD_U(", ", st64, rx_dropped);
		    PRINT_FIELD_U(", ", st64, tx_dropped);
		    PRINT_FIELD_U(", ", st64, multicast);
		    PRINT_FIELD_U(", ", st64, collisions);
		    PRINT_FIELD_U(", ", st64, rx_length_errors);
		    PRINT_FIELD_U(", ", st64, rx_over_errors);
		    PRINT_FIELD_U(", ", st64, rx_crc_errors);
		    PRINT_FIELD_U(", ", st64, rx_frame_errors);
		    PRINT_FIELD_U(", ", st64, rx_fifo_errors);
		    PRINT_FIELD_U(", ", st64, rx_missed_errors);
		    PRINT_FIELD_U(", ", st64, tx_aborted_errors);
		    PRINT_FIELD_U(", ", st64, tx_carrier_errors);
		    PRINT_FIELD_U(", ", st64, tx_fifo_errors);
		    PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
		    PRINT_FIELD_U(", ", st64, tx_window_errors);
		    PRINT_FIELD_U(", ", st64, rx_compressed);
		    PRINT_FIELD_U(", ", st64, tx_compressed);
		    printf("}"));
#endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */
#endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */

	struct nlattr nla = {
		.nla_len = sizeof(nla),
		.nla_type = IFLA_INFO_KIND,
	};
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla),
		    printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}",
			   nla.nla_len));

	nla.nla_type = IFLA_VF_PORT;
	TEST_NLATTR(fd, nlh0, hdrlen,
		    init_ifinfomsg, print_ifinfomsg,
		    IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla),
		    printf("{nla_len=%u, nla_type=IFLA_VF_PORT}",
			   nla.nla_len));

	static const struct {
		uint32_t val;
		const char *str;
	} ifla_events[] = {
		{ 0, "IFLA_EVENT_NONE" },
		{ 6, "IFLA_EVENT_BONDING_OPTIONS" },
		{ ARG_STR(0x7) " /* IFLA_EVENT_??? */" },
		{ ARG_STR(0xdeadfeed) " /* IFLA_EVENT_??? */" },
	};
	for (size_t i = 0; i < ARRAY_SIZE(ifla_events); i++) {
		TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
				   init_ifinfomsg, print_ifinfomsg,
				   IFLA_EVENT, pattern, ifla_events[i].val,
				   printf("%s", ifla_events[i].str));
	}

	puts("+++ exited with 0 +++");
	return 0;
}
int
main(void)
{
	skip_if_unavailable("/proc/self/fd/");

	const int fd = create_nl_socket(NETLINK_ROUTE);

	void *nlh0 = tail_alloc(NLMSG_SPACE(hdrlen));

	static char pattern[4096];
	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);

	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
	char nla_type_str[256];
	sprintf(nla_type_str, "%#x /* MDBA_MDB_ENTRY_??? */", nla_type);
	TEST_NLATTR_(fd, nlh0 - NLA_HDRLEN * 2, hdrlen + NLA_HDRLEN * 2,
		     init_br_port_msg, print_br_port_msg,
		     nla_type, nla_type_str,
		     4, pattern, 4,
		     print_quoted_hex(pattern, 4);
		     printf("}}"));

# ifdef HAVE_STRUCT_BR_MDB_ENTRY
	struct br_mdb_entry entry = {
		.ifindex = ifindex_lo(),
		.state = MDB_TEMPORARY,
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
		.flags = MDB_FLAGS_OFFLOAD,
#  endif
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
		.vid = 0xcdef,
#  endif
		.addr = {
			.proto = htons(AF_UNSPEC)
		}
	};

	memcpy(&entry.addr.u, pattern, sizeof(entry.addr.u));
	TEST_NESTED_NLATTR_OBJECT_EX(fd, nlh0, hdrlen,
				     init_br_port_msg, print_br_port_msg,
				     MDBA_MDB_ENTRY_INFO, pattern, entry, 2,
				     printf("{ifindex=" IFINDEX_LO_STR);
				     printf(", state=MDB_TEMPORARY");
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
				     printf(", flags=MDB_FLAGS_OFFLOAD");
#  endif
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
				     PRINT_FIELD_U(", ", entry, vid);
#  endif
				     printf(", addr={u=");
				     print_quoted_hex(&entry.addr.u,
						      sizeof(entry.addr.u));
				     printf(", proto=htons(AF_UNSPEC)}}"));

	static const struct nlattr nla = {
		.nla_len = sizeof(nla),
		.nla_type = MDBA_MDB_EATTR_TIMER
	};
	char buf[NLMSG_ALIGN(sizeof(entry)) + sizeof(nla)];
	memcpy(buf, &entry, sizeof(entry));
	memcpy(buf + NLMSG_ALIGN(sizeof(entry)), &nla, sizeof(nla));
	TEST_NLATTR(fd, nlh0 - NLA_HDRLEN * 2, hdrlen + NLA_HDRLEN * 2,
		    init_br_port_msg, print_br_port_msg,
		    MDBA_MDB_ENTRY_INFO, sizeof(buf), buf, sizeof(buf),
		    printf("{ifindex=" IFINDEX_LO_STR);
		    printf(", state=MDB_TEMPORARY");
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
		    printf(", flags=MDB_FLAGS_OFFLOAD");
#  endif
#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
		    PRINT_FIELD_U(", ", entry, vid);
#  endif
		    printf(", addr={u=");
		    print_quoted_hex(&entry.addr.u, sizeof(entry.addr.u));
		    printf(", proto=htons(AF_UNSPEC)}}"
			   ", {nla_len=%u, nla_type=MDBA_MDB_EATTR_TIMER}}}",
			   nla.nla_len));
# endif /* HAVE_STRUCT_BR_MDB_ENTRY */

	puts("+++ exited with 0 +++");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("HAVE_STRUCT_BR_PORT_MSG")
Beispiel #10
0
int
main(void)
{
	char ** const tail_argv = tail_memdup(argv, sizeof(argv));
	char ** const tail_envp = tail_memdup(envp, sizeof(envp));

	execve(FILENAME, tail_argv, tail_envp);
	printf("execve(\"%s\""
	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
#if VERBOSE
	       ", [\"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
#else
	       ", %p /* 5 vars, unterminated */"
#endif
	       ") = -1 ENOENT (%m)\n",
	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
	       argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
#if VERBOSE
	       , q_envp[0], q_envp[1], envp[2], envp[3], envp[4],
	       (char *) tail_envp + sizeof(envp)
#else
	       , tail_envp
#endif
	       );

	tail_argv[ARRAY_SIZE(q_argv)] = NULL;
	tail_envp[ARRAY_SIZE(q_envp)] = NULL;

	execve(FILENAME, tail_argv, tail_envp);
	printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
#if VERBOSE
	       ", [\"%s\", \"%s\"]"
#else
	       ", %p /* 2 vars */"
#endif
	       ") = -1 ENOENT (%m)\n",
	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
#if VERBOSE
	       , q_envp[0], q_envp[1]
#else
	       , tail_envp
#endif
	       );

	execve(FILENAME, tail_argv + 2, tail_envp + 1);
	printf("execve(\"%s\", [\"%s\"]"
#if VERBOSE
	       ", [\"%s\"]"
#else
	       ", %p /* 1 var */"
#endif
	       ") = -1 ENOENT (%m)\n",
	       Q_FILENAME, q_argv[2]
#if VERBOSE
	       , q_envp[1]
#else
	       , tail_envp + 1
#endif
	       );

	TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty);
	char **const efault = empty + 1;
	*empty = NULL;

	execve(FILENAME, empty, empty);
	printf("execve(\"%s\", []"
#if VERBOSE
	       ", []"
#else
	       ", %p /* 0 vars */"
#endif
	       ") = -1 ENOENT (%m)\n", Q_FILENAME
#if !VERBOSE
	       , empty
#endif
	       );

	char *const str_a = tail_alloc(DEFAULT_STRLEN + 2);
	fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10);
	str_a[DEFAULT_STRLEN + 1] = '\0';

	char *const str_b = tail_alloc(DEFAULT_STRLEN + 2);
	fill_memory_ex(str_b, DEFAULT_STRLEN + 1, '_', 32);
	str_b[DEFAULT_STRLEN + 1] = '\0';

	char **const a = tail_alloc(sizeof(*a) * (DEFAULT_STRLEN + 2));
	char **const b = tail_alloc(sizeof(*b) * (DEFAULT_STRLEN + 2));
	unsigned int i;
	for (i = 0; i <= DEFAULT_STRLEN; ++i) {
		a[i] = &str_a[i];
		b[i] = &str_b[i];
	}
	a[i] = b[i] = NULL;

	execve(FILENAME, a, b);
	printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
	for (i = 1; i < DEFAULT_STRLEN; ++i)
		printf(", \"%s\"", a[i]);
#if VERBOSE
	printf(", \"%s\"", a[i]);
#else
	printf(", ...");
#endif
#if VERBOSE
	printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]);
	for (i = 1; i <= DEFAULT_STRLEN; ++i)
		printf(", \"%s\"", b[i]);
	printf("]");
#else
	printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1);
#endif
	printf(") = -1 ENOENT (%m)\n");

	execve(FILENAME, a + 1, b + 1);
	printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
	for (i = 2; i <= DEFAULT_STRLEN; ++i)
		printf(", \"%s\"", a[i]);
#if VERBOSE
	printf("], [\"%s\"", b[1]);
	for (i = 2; i <= DEFAULT_STRLEN; ++i)
		printf(", \"%s\"", b[i]);
	printf("]");
#else
	printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN);
#endif
	printf(") = -1 ENOENT (%m)\n");

	execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
	printf("execve(\"%s\", NULL, %p) = -1 ENOENT (%m)\n",
	       Q_FILENAME, efault);

	execve(FILENAME, efault, NULL);
	printf("execve(\"%s\", %p, NULL) = -1 ENOENT (%m)\n",
	       Q_FILENAME, efault);

	return 0;
}
int
main(void)
{
	static const kernel_ulong_t bogus_zero =
		(kernel_ulong_t) 0x8765432100000000ULL;
	static const kernel_ulong_t bogus_oflags =
		(kernel_ulong_t) 0xdefaced100000003ULL;
	static const kernel_ulong_t bogus_mode =
		(kernel_ulong_t) 0xdec0deadfacefeedULL;
	static const kernel_ulong_t bogus_fd =
		(kernel_ulong_t) 0xfeedfacedeadba5eULL;
	static const kernel_ulong_t bogus_zero_size =
		(sizeof(kernel_ulong_t) > sizeof(int)) ? (kernel_ulong_t) 0 :
			(kernel_ulong_t) 0xface1e5500000000ULL;
	static const kernel_ulong_t bogus_size =
		(kernel_ulong_t) 0xbadc0dedda7a1057ULL;
	static const kernel_ulong_t bogus_prio =
		(kernel_ulong_t) 0xdec0ded1defaced3ULL;
	static const struct timespec bogus_tmout_data = {
		.tv_sec = (time_t) 0xdeadfacebeeff00dLL,
		.tv_nsec = (long) 0xfacefee1deadfeedLL,
	};
	static const struct timespec future_tmout_data = {
		.tv_sec = (time_t) 0x7ea1fade7e57faceLL,
		.tv_nsec = 999999999,
	};
	struct_sigevent bogus_sev_data = {
		.sigev_notify = 0xdefaced,
		.sigev_signo = 0xfacefeed,
		.sigev_value.sival_ptr = (unsigned long) 0xdeadbeefbadc0dedULL
	};

	const char *errstr;
	long rc;
	kernel_long_t *bogus_attrs = tail_alloc(sizeof(*bogus_attrs) *
		NUM_ATTRS);
	char *msg = tail_alloc(MSG_SIZE);
	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned, bogus_prio_ptr);
	struct timespec *bogus_tmout = tail_memdup(&bogus_tmout_data,
		sizeof(*bogus_tmout));
	struct timespec *future_tmout = tail_memdup(&future_tmout_data,
		sizeof(*future_tmout));
	struct_sigevent *bogus_sev = tail_memdup(&bogus_sev_data,
		sizeof(*bogus_sev));
	int fd = -1;


	fill_memory_ex(msg, MSG_SIZE, MSG_START, MSG_SIZE);
	fill_memory_ex(bogus_attrs, sizeof(*bogus_attrs) * NUM_ATTRS,
		       0xbb, 0x70);


	/* mq_open */

	/* Zero values, non-O_CREAT mode */
	rc = syscall(__NR_mq_open, NULL, bogus_zero, bogus_mode, NULL);
	printf("mq_open(NULL, O_RDONLY) = %s\n", sprintrc(rc));

	/* O_CREAT parsing, other flags, bogs values */
	rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode,
		     NULL);
	printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, NULL) = %s\n",
	       msg, (unsigned short) bogus_mode, sprintrc(rc));

	/* Partially invalid attributes structure */
	rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode,
		     bogus_attrs + 1);
	printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, %p) = %s\n",
	       msg, (unsigned short) bogus_mode, bogus_attrs + 1, sprintrc(rc));

	/* Valid attributes structure */
	rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode,
		     bogus_attrs);
	printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, {mq_flags=%#llx"
	       ", mq_maxmsg=%lld, mq_msgsize=%lld, mq_curmsgs=%lld}) = %s\n",
	       msg, (unsigned short) bogus_mode,
	       (unsigned long long) (kernel_ulong_t) bogus_attrs[0],
	       (long long) bogus_attrs[1],
	       (long long) bogus_attrs[2],
	       (long long) bogus_attrs[3], sprintrc(rc));


	/* mq_timedsend */

	/* Zero values*/
	rc = syscall(__NR_mq_timedsend, bogus_zero, NULL, bogus_zero_size,
		     bogus_zero, NULL);
	printf("mq_timedsend(0, NULL, 0, 0, NULL) = %s\n", sprintrc(rc));

	/* Invalid pointers */
	rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE, bogus_size,
		     bogus_prio, bogus_tmout + 1);
	printf("mq_timedsend(%d, %p, %llu, %u, %p) = %s\n",
	       (int) bogus_fd, msg + MSG_SIZE, (unsigned long long) bogus_size,
	       (unsigned) bogus_prio, bogus_tmout + 1, sprintrc(rc));

	/* Partially invalid message (memory only partially available) */
	rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE - MSG_CUT,
		     MSG_SIZE, bogus_prio, bogus_tmout);
	printf("mq_timedsend(%d, %p, %llu, %u, {tv_sec=%lld, tv_nsec=%llu})"
	       " = %s\n",
	       (int) bogus_fd, msg + MSG_SIZE - MSG_CUT,
	       (unsigned long long) MSG_SIZE, (unsigned) bogus_prio,
	       (long long) bogus_tmout->tv_sec,
	       zero_extend_signed_to_ull(bogus_tmout->tv_nsec), sprintrc(rc));

	/* Fully valid message, uncut */
	rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE - MSG_CUT,
		     MSG_CUT, bogus_prio, bogus_tmout);
	errstr = sprintrc(rc);
	printf("mq_timedsend(%d, ", (int) bogus_fd);
	printstr(MSG_START + MSG_SIZE - MSG_CUT, MSG_CUT);
	printf(", %llu, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
	       (unsigned long long) MSG_CUT, (unsigned) bogus_prio,
	       (long long) bogus_tmout->tv_sec,
	       zero_extend_signed_to_ull(bogus_tmout->tv_nsec), errstr);

	/* Partially invalid message, cut at maxstrlen */
	rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_CUT, MSG_SIZE,
		     bogus_prio, bogus_tmout);
	errstr = sprintrc(rc);
	printf("mq_timedsend(%d, ", (int) bogus_fd);
	printstr(MSG_START + MSG_CUT, MSG_MAX_UNCUT);
	printf("..., %llu, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
	       (unsigned long long) MSG_SIZE, (unsigned) bogus_prio,
	       (long long) bogus_tmout->tv_sec,
	       zero_extend_signed_to_ull(bogus_tmout->tv_nsec), errstr);


	/* mq_timedreceive */

	/* Zero values */
	rc = syscall(__NR_mq_timedreceive, bogus_zero, NULL, bogus_zero_size,
		     NULL, NULL);
	printf("mq_timedreceive(0, NULL, 0, NULL, NULL) = %s\n", sprintrc(rc));

	/* Invalid addresses */
	rc = syscall(__NR_mq_timedreceive, bogus_fd, msg + MSG_SIZE, bogus_size,
		     bogus_prio_ptr + 1, bogus_tmout + 1);
	printf("mq_timedreceive(%d, %p, %llu, %p, %p) = %s\n",
	       (int) bogus_fd, msg + MSG_SIZE, (unsigned long long) bogus_size,
	       bogus_prio_ptr + 1, bogus_tmout + 1, sprintrc(rc));

	/* Invalid fd, valid msg pointer */
	rc = syscall(__NR_mq_timedreceive, bogus_fd, msg, bogus_size,
		     bogus_prio_ptr, bogus_tmout);
	printf("mq_timedreceive(%d, %p, %llu, %p, {tv_sec=%lld, tv_nsec=%llu}) "
	       "= %s\n",
	       (int) bogus_fd, msg, (unsigned long long) bogus_size,
	       bogus_prio_ptr, (long long) bogus_tmout->tv_sec,
	       zero_extend_signed_to_ull(bogus_tmout->tv_nsec), sprintrc(rc));


	/* mq_notify */

	/* Zero values */
	rc = syscall(__NR_mq_notify, bogus_zero, NULL);
	printf("mq_notify(0, NULL) = %s\n", sprintrc(rc));

	/* Invalid pointer */
	rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev + 1);
	printf("mq_notify(%d, %p) = %s\n",
	       (int) bogus_fd, bogus_sev + 1, sprintrc(rc));

	/* Invalid SIGEV_* */
	rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev);
	printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}"
	       ", sigev_signo=%u, sigev_notify=%#x /* SIGEV_??? */}) = %s\n",
	       (int) bogus_fd, bogus_sev->sigev_value.sival_int,
	       bogus_sev->sigev_value.sival_ptr,
	       bogus_sev->sigev_signo, bogus_sev->sigev_notify,
	       sprintrc(rc));

	/* SIGEV_NONE */
	bogus_sev->sigev_notify = SIGEV_NONE;
	rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev);
	printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}"
	       ", sigev_signo=%u, sigev_notify=SIGEV_NONE}) = %s\n",
	       (int) bogus_fd, bogus_sev->sigev_value.sival_int,
	       bogus_sev->sigev_value.sival_ptr,
	       bogus_sev->sigev_signo, sprintrc(rc));

	/* SIGEV_SIGNAL */
	bogus_sev->sigev_notify = SIGEV_SIGNAL;
	bogus_sev->sigev_signo = SIGALRM;
	rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev);
	printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}"
	       ", sigev_signo=SIGALRM, sigev_notify=SIGEV_SIGNAL}) = %s\n",
	       (int) bogus_fd, bogus_sev->sigev_value.sival_int,
	       bogus_sev->sigev_value.sival_ptr, sprintrc(rc));

	/* SIGEV_THREAD */
	bogus_sev->sigev_notify = SIGEV_THREAD;
	bogus_sev->sigev_un.sigev_thread.function =
		(unsigned long) 0xdeadbeefbadc0dedULL;
	bogus_sev->sigev_un.sigev_thread.attribute =
		(unsigned long) 0xcafef00dfacefeedULL;
	rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev);
	printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}"
	       ", sigev_signo=SIGALRM, sigev_notify=SIGEV_THREAD"
	       ", sigev_notify_function=%#lx, sigev_notify_attributes=%#lx})"
	       " = %s\n",
	       (int) bogus_fd, bogus_sev->sigev_value.sival_int,
	       bogus_sev->sigev_value.sival_ptr,
	       bogus_sev->sigev_un.sigev_thread.function,
	       bogus_sev->sigev_un.sigev_thread.attribute, sprintrc(rc));

	/* mq_unlink */

	/* Zero values */
	rc = syscall(__NR_mq_unlink, NULL);
	printf("mq_unlink(NULL) = %s\n", sprintrc(rc));

	/* Invalid ptr */
	rc = syscall(__NR_mq_unlink, msg + MSG_SIZE);
	printf("mq_unlink(%p) = %s\n", msg + MSG_SIZE, sprintrc(rc));

	/* Long unterminated string */
	rc = syscall(__NR_mq_unlink, msg);
	errstr = sprintrc(rc);
	printf("mq_unlink(%p) = %s\n", msg, errstr);


	/* Sending and receiving test */

	if (asprintf(&mq_name, "strace-mq_sendrecv-%u.sample", getpid()) < 0)
		perror_msg_and_fail("asprintf");

# if DUMPIO_READ || DUMPIO_WRITE
	close(0);
# endif
	bogus_attrs[1] = 2;
	bogus_attrs[2] = MSG_SIZE;
	fd = rc = syscall(__NR_mq_open, mq_name,
			  O_CREAT|O_RDWR|O_NONBLOCK, S_IRWXU, bogus_attrs);
	errstr = sprintrc(rc);
	if (rc < 0)
		perror_msg_and_skip("mq_open");
	else
		atexit(cleanup);
# if DUMPIO_READ || DUMPIO_WRITE
	if (fd != 0)
		error_msg_and_skip("mq_open returned fd other than 0");
# endif
	fill_memory_ex(bogus_attrs, sizeof(*bogus_attrs) * NUM_ATTRS,
		       0xbb, 0x70);
	printf("mq_open(\"%s\", O_RDWR|O_CREAT|O_NONBLOCK, 0700"
	       ", {mq_flags=%#llx, mq_maxmsg=2, mq_msgsize=%u"
	       ", mq_curmsgs=%lld}) = %s\n",
	       mq_name, (unsigned long long) (kernel_ulong_t) bogus_attrs[0],
	       MSG_SIZE, (long long) bogus_attrs[3], errstr);

	rc = syscall(__NR_mq_getsetattr, fd, NULL, bogus_attrs);
	if (rc < 0)
		perror_msg_and_skip("mq_getsetattr");
	if ((bogus_attrs[1] < 2) || (bogus_attrs[2] < MSG_SIZE))
		error_msg_and_skip("mq too small");

	do_send(fd, msg, MSG_CUT, future_tmout, false);
	do_send(fd, msg, MSG_SIZE, future_tmout, true);

	memset(msg, '\0', MSG_SIZE);
	do_recv(fd, msg, MSG_CUT, future_tmout, false);

	memset(msg, '\0', MSG_SIZE);
	do_recv(fd, msg, MSG_SIZE, future_tmout, true);

	return 0;
}

#else

SKIP_MAIN_UNDEFINED("__NR_mq_open && __NR_mq_timedsend && "
	"__NR_mq_timedreceive && __NR_mq_notify && __NR_mq_unlink");