示例#1
0
static int kdbus_clone_userns_test(const char *bus,
				   const char *name,
				   struct kdbus_conn **conn_db,
				   int expected_status)
{
	pid_t pid;
	int ret = 0;
	int status;

	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, -errno);

	if (pid == 0) {
		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
		if (ret < 0)
			_exit(EXIT_FAILURE);

		ret = __kdbus_clone_userns_test(bus, name, conn_db,
						expected_status);
		_exit(ret);
	}

	/*
	 * Receive in the original (root privileged) user namespace,
	 * must fail with -ETIMEDOUT.
	 */
	ret = kdbus_msg_recv_poll(conn_db[0], 100, NULL, NULL);
	ASSERT_RETURN_VAL(ret == -ETIMEDOUT, ret);

	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
}
示例#2
0
static void *run_thread_reply(void *data)
{
	int ret;
	unsigned long status = TEST_OK;

	ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL);
	if (ret < 0)
		goto exit_thread;

	kdbus_printf("Thread received message, sending reply ...\n");

	/* using an unknown cookie must fail */
	ret = kdbus_msg_send_reply(conn_a, ~cookie, conn_b->id);
	if (ret != -EPERM) {
		status = TEST_ERR;
		goto exit_thread;
	}

	ret = kdbus_msg_send_reply(conn_a, cookie, conn_b->id);
	if (ret != 0) {
		status = TEST_ERR;
		goto exit_thread;
	}

exit_thread:
	pthread_exit(NULL);
	return (void *) status;
}
示例#3
0
static void *kdbus_recv_echo(void *ptr)
{
	int ret;
	struct kdbus_conn *conn = ptr;

	ret = kdbus_msg_recv_poll(conn, 200, NULL, NULL);

	return (void *)(long)ret;
}
示例#4
0
int kdbus_test_message_basic(struct kdbus_test_env *env)
{
	struct kdbus_conn *conn;
	struct kdbus_conn *sender;
	struct kdbus_msg *msg;
	uint64_t cookie = 0x1234abcd5678eeff;
	uint64_t offset;
	int ret;

	sender = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(sender != NULL);

	/* create a 2nd connection */
	conn = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(conn != NULL);

	ret = kdbus_add_match_empty(conn);
	ASSERT_RETURN(ret == 0);

	ret = kdbus_add_match_empty(sender);
	ASSERT_RETURN(ret == 0);

	/* send over 1st connection */
	ret = kdbus_msg_send(sender, NULL, cookie, 0, 0, 0,
			     KDBUS_DST_ID_BROADCAST);
	ASSERT_RETURN(ret == 0);

	/* Make sure that we do not get our own broadcasts */
	ret = kdbus_msg_recv(sender, NULL, NULL);
	ASSERT_RETURN(ret == -EAGAIN);

	/* ... and receive on the 2nd */
	ret = kdbus_msg_recv_poll(conn, 100, &msg, &offset);
	ASSERT_RETURN(ret == 0);
	ASSERT_RETURN(msg->cookie == cookie);

	kdbus_msg_free(msg);

	ret = kdbus_free(conn, offset);
	ASSERT_RETURN(ret == 0);

	kdbus_conn_free(sender);
	kdbus_conn_free(conn);

	return TEST_OK;
}
示例#5
0
static int no_cancel_sync(struct kdbus_conn *conn_src,
			  struct kdbus_conn *conn_dst)
{
	pid_t pid;
	int cancel_fd;
	int ret, status;
	struct kdbus_msg *msg = NULL;

	/* pass eventfd, but never signal it so it shouldn't have any effect */

	cancel_fd = eventfd(0, 0);
	ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd);

	cookie++;
	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, pid);

	if (pid == 0) {
		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
					  KDBUS_MSG_EXPECT_REPLY,
					  100000000ULL, 0, conn_src->id,
					  cancel_fd);
		ASSERT_EXIT(ret == 0);

		_exit(EXIT_SUCCESS);
	}

	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
	ASSERT_RETURN_VAL(ret == 0 && msg->cookie == cookie, -1);

	kdbus_msg_free(msg);

	ret = kdbus_msg_send_reply(conn_src, cookie, conn_dst->id);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	if (WIFSIGNALED(status))
		return -1;

	return (status == EXIT_SUCCESS) ? 0 : -1;
}
示例#6
0
static int cancel_fd_sync(struct kdbus_conn *conn_src,
			  struct kdbus_conn *conn_dst)
{
	pid_t pid;
	int cancel_fd;
	int ret, status;
	uint64_t counter = 1;
	struct kdbus_msg *msg = NULL;

	cancel_fd = eventfd(0, 0);
	ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd);

	cookie++;
	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, pid);

	if (pid == 0) {
		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
					  KDBUS_MSG_EXPECT_REPLY,
					  100000000ULL, 0, conn_src->id,
					  cancel_fd);
		ASSERT_EXIT(ret == -ECANCELED);

		_exit(EXIT_SUCCESS);
	}

	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);

	kdbus_msg_free(msg);

	ret = write(cancel_fd, &counter, sizeof(counter));
	ASSERT_RETURN(ret == sizeof(counter));

	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	if (WIFSIGNALED(status))
		return TEST_ERR;

	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
}
示例#7
0
static int kdbus_fork_test_by_id(const char *bus,
				 struct kdbus_conn **conn_db,
				 int parent_status, int child_status)
{
	int ret;
	pid_t pid;
	uint64_t cookie = 0x9876ecba;
	struct kdbus_msg *msg = NULL;
	uint64_t offset = 0;
	int status = 0;

	/*
	 * If the child_status is not EXIT_SUCCESS, then we expect
	 * that sending from the child will fail, thus receiving
	 * from parent must error with -ETIMEDOUT, and vice versa.
	 */
	bool parent_timedout = !!child_status;
	bool child_timedout = !!parent_status;

	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, pid);

	if (pid == 0) {
		struct kdbus_conn *conn_src;

		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
		ASSERT_EXIT(ret == 0);

		ret = drop_privileges(65534, 65534);
		ASSERT_EXIT(ret == 0);

		conn_src = kdbus_hello(bus, 0, NULL, 0);
		ASSERT_EXIT(conn_src);

		ret = kdbus_add_match_empty(conn_src);
		ASSERT_EXIT(ret == 0);

		/*
		 * child_status is always checked against send
		 * operations, in case it fails always return
		 * EXIT_FAILURE.
		 */
		ret = kdbus_msg_send(conn_src, NULL, cookie,
				     0, 0, 0, conn_db[0]->id);
		ASSERT_EXIT(ret == child_status);

		ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL);

		kdbus_conn_free(conn_src);

		/*
		 * Child kdbus_msg_recv_poll() should timeout since
		 * the parent_status was set to a non EXIT_SUCCESS
		 * value.
		 */
		if (child_timedout)
			_exit(ret == -ETIMEDOUT ? EXIT_SUCCESS : EXIT_FAILURE);

		_exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
	}

	ret = kdbus_msg_recv_poll(conn_db[0], 100, &msg, &offset);
	/*
	 * If parent_timedout is set then this should fail with
	 * -ETIMEDOUT since the child_status was set to a non
	 * EXIT_SUCCESS value. Otherwise, assume
	 * that kdbus_msg_recv_poll() has succeeded.
	 */
	if (parent_timedout) {
		ASSERT_RETURN_VAL(ret == -ETIMEDOUT, TEST_ERR);

		/* timedout no need to continue, we don't have the
		 * child connection ID, so just terminate. */
		goto out;
	} else {
		ASSERT_RETURN_VAL(ret == 0, ret);
	}

	ret = kdbus_msg_send(conn_db[0], NULL, ++cookie,
			     0, 0, 0, msg->src_id);
	/*
	 * parent_status is checked against send operations,
	 * on failures always return TEST_ERR.
	 */
	ASSERT_RETURN_VAL(ret == parent_status, TEST_ERR);

	kdbus_msg_free(msg);
	kdbus_free(conn_db[0], offset);

out:
	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
}
示例#8
0
		cookie++;
		ret = kdbus_msg_send(userns_conn, NULL, cookie,
				     0, 0, 0, conn->id);
		ASSERT_EXIT(ret == 0);

		/* Parent did send */
		ret = eventfd_read(signal_fd, &event_status);
		ASSERT_RETURN(ret >= 0 && event_status == 1);

		/*
		 * Receive from privileged connection
		 */
		kdbus_printf("Privileged → unprivileged/privileged "
			     "in its userns "
			     "(different userns and pidns):\n");
		ret = kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL);
		ASSERT_EXIT(ret == 0);
		ASSERT_EXIT(msg->dst_id == userns_conn->id);

		item = kdbus_get_item(msg, KDBUS_ITEM_CAPS);
		ASSERT_EXIT(item);

		/* uid/gid not mapped, so we have unpriv cached creds */
		ret = kdbus_match_kdbus_creds(msg, &unmapped_creds);
		ASSERT_EXIT(ret == 0);

		/*
		 * Diffent pid namepsaces. This is the child pidns
		 * so it should not see its parent kdbus_pids
		 */
		ret = kdbus_match_kdbus_pids(msg, &unmapped_pids);
示例#9
0
static void *run_thread_byebye(void *data)
{
	struct kdbus_cmd cmd_byebye = { .size = sizeof(cmd_byebye) };
	int ret;

	ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL);
	if (ret == 0) {
		kdbus_printf("Thread received message, invoking BYEBYE ...\n");
		kdbus_msg_recv(conn_a, NULL, NULL);
		if (data == BYEBYE_ME)
			kdbus_cmd_byebye(conn_b->fd, &cmd_byebye);
		else if (data == BYEBYE_THEM)
			kdbus_cmd_byebye(conn_a->fd, &cmd_byebye);
	}

	pthread_exit(NULL);
	return NULL;
}

int kdbus_test_sync_byebye(struct kdbus_test_env *env)
{
	pthread_t thread;
	int ret;

	/*
	 * This sends a synchronous message to a thread, which waits until it
	 * received the message and then invokes BYEBYE on the *ORIGINAL*
	 * connection. That is, on the same connection that synchronously waits
	 * for an reply.
	 * This should properly wake the connection up and cause ECONNRESET as
	 * the connection is disconnected now.
	 *
	 * The second time, we do the same but invoke BYEBYE on the *TARGET*
	 * connection. This should also wake up the synchronous sender as the
	 * reply cannot be sent by a disconnected target.
	 */

	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(conn_a && conn_b);

	pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_ME);

	ret = kdbus_msg_send_sync(conn_b, NULL, cookie,
				  KDBUS_MSG_EXPECT_REPLY,
				  5000000000ULL, 0, conn_a->id, -1);

	ASSERT_RETURN(ret == -ECONNRESET);

	pthread_join(thread, NULL);

	kdbus_conn_free(conn_a);
	kdbus_conn_free(conn_b);

	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(conn_a && conn_b);

	pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_THEM);

	ret = kdbus_msg_send_sync(conn_b, NULL, cookie,
				  KDBUS_MSG_EXPECT_REPLY,
				  5000000000ULL, 0, conn_a->id, -1);

	ASSERT_RETURN(ret == -EPIPE);

	pthread_join(thread, NULL);

	kdbus_conn_free(conn_a);
	kdbus_conn_free(conn_b);

	return TEST_OK;
}
示例#10
0
static int interrupt_sync(struct kdbus_conn *conn_src,
			  struct kdbus_conn *conn_dst)
{
	pid_t pid;
	int ret, status;
	struct kdbus_msg *msg = NULL;
	struct sigaction sa = {
		.sa_handler = nop_handler,
		.sa_flags = SA_NOCLDSTOP|SA_RESTART,
	};

	cookie++;
	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, pid);

	if (pid == 0) {
		ret = sigaction(SIGINT, &sa, NULL);
		ASSERT_EXIT(ret == 0);

		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
					  KDBUS_MSG_EXPECT_REPLY,
					  100000000ULL, 0, conn_src->id, -1);
		ASSERT_EXIT(ret == -ETIMEDOUT);

		_exit(EXIT_SUCCESS);
	}

	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);

	kdbus_msg_free(msg);

	ret = kill(pid, SIGINT);
	ASSERT_RETURN_VAL(ret == 0, ret);

	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	if (WIFSIGNALED(status))
		return TEST_ERR;

	ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL);
	ASSERT_RETURN(ret == -ETIMEDOUT);

	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
}

static int close_epipe_sync(const char *bus)
{
	pid_t pid;
	int ret, status;
	struct kdbus_conn *conn_src;
	struct kdbus_conn *conn_dst;
	struct kdbus_msg *msg = NULL;

	conn_src = kdbus_hello(bus, 0, NULL, 0);
	ASSERT_RETURN(conn_src);

	ret = kdbus_add_match_empty(conn_src);
	ASSERT_RETURN(ret == 0);

	conn_dst = kdbus_hello(bus, 0, NULL, 0);
	ASSERT_RETURN(conn_dst);

	cookie++;
	pid = fork();
	ASSERT_RETURN_VAL(pid >= 0, pid);

	if (pid == 0) {
		uint64_t dst_id;

		/* close our reference */
		dst_id = conn_dst->id;
		kdbus_conn_free(conn_dst);

		ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
		ASSERT_EXIT(ret == 0 && msg->cookie == cookie);
		ASSERT_EXIT(msg->src_id == dst_id);

		cookie++;
		ret = kdbus_msg_send_sync(conn_src, NULL, cookie,
					  KDBUS_MSG_EXPECT_REPLY,
					  100000000ULL, 0, dst_id, -1);
		ASSERT_EXIT(ret == -EPIPE);

		_exit(EXIT_SUCCESS);
	}

	ret = kdbus_msg_send(conn_dst, NULL, cookie, 0, 0, 0,
			     KDBUS_DST_ID_BROADCAST);
	ASSERT_RETURN(ret == 0);

	cookie++;
	ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL);
	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);

	kdbus_msg_free(msg);

	/* destroy connection */
	kdbus_conn_free(conn_dst);
	kdbus_conn_free(conn_src);

	ret = waitpid(pid, &status, 0);
	ASSERT_RETURN_VAL(ret >= 0, ret);

	if (!WIFEXITED(status))
		return TEST_ERR;

	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
}
示例#11
0
				  int child_status)
{
	int ret = 0;
	uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;

	ASSERT_RETURN(conn_dst);

	ret = RUN_UNPRIVILEGED_CONN(unpriv, bus, ({
		ret = kdbus_msg_send(unpriv, NULL,
				     expected_cookie, 0, 0, 0,
				     conn_dst->id);
		ASSERT_EXIT(ret == child_status);
	}));
	ASSERT_RETURN(ret >= 0);

	ret = kdbus_msg_recv_poll(conn_dst, 300, NULL, NULL);
	ASSERT_RETURN(ret == parent_status);

	return 0;
}

static int test_policy_priv_by_broadcast(const char *bus,
					 struct kdbus_conn *conn_dst,
					 int drop_second_user,
					 int parent_status,
					 int child_status)
{
	int efd;
	int ret = 0;
	eventfd_t event_status = 0;
	struct kdbus_msg *msg = NULL;
示例#12
0
static int msg_recv_prio(struct kdbus_conn *conn,
			 int64_t requested_prio,
			 int64_t expected_prio)
{
	struct kdbus_cmd_recv recv = {
		.size = sizeof(recv),
		.flags = KDBUS_RECV_USE_PRIORITY,
		.priority = requested_prio,
	};
	struct kdbus_msg *msg;
	int ret;

	ret = ioctl(conn->fd, KDBUS_CMD_RECV, &recv);
	if (ret < 0) {
		kdbus_printf("error receiving message: %d (%m)\n", -errno);
		return -errno;
	}

	msg = (struct kdbus_msg *)(conn->buf + recv.reply.offset);
	kdbus_msg_dump(conn, msg);

	if (msg->priority != expected_prio) {
		kdbus_printf("expected message prio %lld, got %lld\n",
			     (unsigned long long) expected_prio,
			     (unsigned long long) msg->priority);
		return -EINVAL;
	}

	kdbus_msg_free(msg);
	ret = kdbus_free(conn, recv.reply.offset);
	if (ret < 0)
		return ret;

	return 0;
}

int kdbus_test_message_prio(struct kdbus_test_env *env)
{
	struct kdbus_conn *a, *b;
	uint64_t cookie = 0;

	a = kdbus_hello(env->buspath, 0, NULL, 0);
	b = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(a && b);

	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   25, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   10, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -35, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   20, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -15, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   10, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -10, a->id) == 0);

	ASSERT_RETURN(msg_recv_prio(a, -200, -800) == 0);
	ASSERT_RETURN(msg_recv_prio(a, -100, -800) == 0);
	ASSERT_RETURN(msg_recv_prio(a, -400, -600) == 0);
	ASSERT_RETURN(msg_recv_prio(a, -400, -600) == -ENOMSG);
	ASSERT_RETURN(msg_recv_prio(a, 10, -150) == 0);
	ASSERT_RETURN(msg_recv_prio(a, 10, -100) == 0);

	kdbus_printf("--- get priority (all)\n");
	ASSERT_RETURN(kdbus_msg_recv(a, NULL, NULL) == 0);

	kdbus_conn_free(a);
	kdbus_conn_free(b);

	return TEST_OK;
}

static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env)
{
	int ret;
	unsigned int i;
	uint64_t offset;
	struct kdbus_conn *conn;
	struct kdbus_conn *reader;
	struct kdbus_msg *msg = NULL;

	reader = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(reader);

	conn = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(conn);

	/* Register for ID signals */
	ret = kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD,
				 KDBUS_MATCH_ID_ANY);
	ASSERT_RETURN(ret == 0);

	ret = kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE,
				 KDBUS_MATCH_ID_ANY);
	ASSERT_RETURN(ret == 0);

	/* Each iteration two notifications: add and remove ID */
	for (i = 0; i < KDBUS_CONN_MAX_MSGS / 2; i++) {
		struct kdbus_conn *notifier;

		notifier = kdbus_hello(env->buspath, 0, NULL, 0);
		ASSERT_RETURN(notifier);

		kdbus_conn_free(notifier);

	}

	/*
	 * Now the reader queue is full, message will be lost
	 * but it will not be accounted in dropped msgs
	 */
	ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id);
	ASSERT_RETURN(ret == -ENOBUFS);

	/* More ID kernel notifications that will be lost */
	kdbus_conn_free(conn);

	conn = kdbus_hello(env->buspath, 0, NULL, 0);
	ASSERT_RETURN(conn);

	kdbus_conn_free(conn);

	ret = kdbus_msg_recv(reader, &msg, &offset);
	ASSERT_RETURN(ret == -EOVERFLOW);

	/*
	 * We lost only 3 packet since only broadcast mesg
	 * are accounted. The connection ID add/remove notification
	 */
	ASSERT_RETURN(offset == 3);

	kdbus_msg_free(msg);

	/* Read our queue */
	for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
		ret = kdbus_msg_recv_poll(reader, 100, &msg, NULL);
		ASSERT_RETURN(ret == 0);

		kdbus_msg_free(msg);
	}

	ret = kdbus_msg_recv(reader, NULL, NULL);
	ASSERT_RETURN(ret == -EAGAIN);

	kdbus_conn_free(reader);

	return 0;
}
示例#13
0
	}));
	ASSERT_RETURN(ret == 0);

	expected_cookie++;
	/* Now try to send a legitimate message from B to A */
	ret = kdbus_msg_send(privileged_b, NULL, expected_cookie, 0,
			     0, 0, privileged_a->id);
	ASSERT_RETURN(ret == 0);

	expected_cookie++;
	ret = kdbus_msg_send(privileged_b, NULL, expected_cookie, 0,
			     0, 0, KDBUS_DST_ID_BROADCAST);
	ASSERT_RETURN(ret == 0);

	/* Privileged service A tries to read its messages now */
	ret = kdbus_msg_recv_poll(privileged_a, 100, &msg, &offset);
	ASSERT_RETURN(ret == -EOVERFLOW);

	/*
	 * We have lost 1 broadcast messages, the one from unprivileged
	 * the privileged broadcast was queued, our quota is per user
	 */
	ASSERT_RETURN(offset == 1);

	/* Read our queue */
	for (i = 0; i < MAX_USER_TOTAL_MSGS; i++) {
		ret = kdbus_msg_recv_poll(privileged_a, 100, &msg, NULL);
		ASSERT_RETURN(ret == 0);

		ASSERT_RETURN(msg->dst_id == KDBUS_DST_ID_BROADCAST);