summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/kdbus/test-message.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/kdbus/test-message.c')
-rw-r--r--tools/testing/selftests/kdbus/test-message.c736
1 files changed, 0 insertions, 736 deletions
diff --git a/tools/testing/selftests/kdbus/test-message.c b/tools/testing/selftests/kdbus/test-message.c
deleted file mode 100644
index 33d349bb2..000000000
--- a/tools/testing/selftests/kdbus/test-message.c
+++ /dev/null
@@ -1,736 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <assert.h>
-#include <time.h>
-#include <stdbool.h>
-#include <sys/eventfd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include "kdbus-api.h"
-#include "kdbus-util.h"
-#include "kdbus-enum.h"
-#include "kdbus-test.h"
-
-/* maximum number of queued messages from the same individual user */
-#define KDBUS_CONN_MAX_MSGS 256
-
-/* maximum number of queued requests waiting for a reply */
-#define KDBUS_CONN_MAX_REQUESTS_PENDING 128
-
-/* maximum message payload size */
-#define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE (2 * 1024UL * 1024UL)
-
-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 get our own broadcasts */
- ret = kdbus_msg_recv(sender, &msg, &offset);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(msg->cookie == cookie);
-
- kdbus_msg_free(msg);
-
- /* ... 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);
-
- /* Msgs that expect a reply must have timeout and cookie */
- ret = kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY,
- 0, 0, conn->id);
- ASSERT_RETURN(ret == -EINVAL);
-
- /* Faked replies with a valid reply cookie are rejected */
- ret = kdbus_msg_send_reply(conn, time(NULL) ^ cookie, sender->id);
- ASSERT_RETURN(ret == -EBADSLT);
-
- ret = kdbus_free(conn, offset);
- ASSERT_RETURN(ret == 0);
-
- kdbus_conn_free(sender);
- kdbus_conn_free(conn);
-
- return TEST_OK;
-}
-
-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 = kdbus_cmd_recv(conn->fd, &recv);
- if (ret < 0) {
- kdbus_printf("error receiving message: %d (%m)\n", -errno);
- return ret;
- }
-
- msg = (struct kdbus_msg *)(conn->buf + recv.msg.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.msg.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) == -EAGAIN);
- 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;
- struct kdbus_conn *conn;
- struct kdbus_conn *reader;
- struct kdbus_msg *msg = NULL;
- struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
-
- 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 with kernel notfications,
- * but as a user we still have room to push our messages.
- */
- ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id);
- ASSERT_RETURN(ret == 0);
-
- /* 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);
-
- /*
- * We lost only 3 packets since only signal msgs are
- * accounted. The connection ID add/remove notification
- */
- ret = kdbus_cmd_recv(reader->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS);
- ASSERT_RETURN(recv.dropped_msgs == 3);
-
- msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
- kdbus_msg_free(msg);
-
- /* Read our queue */
- for (i = 0; i < KDBUS_CONN_MAX_MSGS - 1; i++) {
- memset(&recv, 0, sizeof(recv));
- recv.size = sizeof(recv);
-
- ret = kdbus_cmd_recv(reader->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(!(recv.return_flags &
- KDBUS_RECV_RETURN_DROPPED_MSGS));
-
- msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
- kdbus_msg_free(msg);
- }
-
- ret = kdbus_msg_recv(reader, NULL, NULL);
- ASSERT_RETURN(ret == 0);
-
- ret = kdbus_msg_recv(reader, NULL, NULL);
- ASSERT_RETURN(ret == -EAGAIN);
-
- kdbus_conn_free(reader);
-
- return 0;
-}
-
-/* Return the number of message successfully sent */
-static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src,
- uint64_t dst_id,
- unsigned int max_msgs)
-{
- unsigned int i;
- uint64_t cookie = 0;
- size_t size;
- struct kdbus_cmd_send cmd = {};
- struct kdbus_msg *msg;
- int ret;
-
- size = sizeof(struct kdbus_msg);
- msg = malloc(size);
- ASSERT_RETURN_VAL(msg, -ENOMEM);
-
- memset(msg, 0, size);
- msg->size = size;
- msg->src_id = conn_src->id;
- msg->dst_id = dst_id;
- msg->payload_type = KDBUS_PAYLOAD_DBUS;
-
- cmd.size = sizeof(cmd);
- cmd.msg_address = (uintptr_t)msg;
-
- for (i = 0; i < max_msgs; i++) {
- msg->cookie = cookie++;
- ret = kdbus_cmd_send(conn_src->fd, &cmd);
- if (ret < 0)
- break;
- }
-
- free(msg);
-
- return i;
-}
-
-static int kdbus_test_activator_quota(struct kdbus_test_env *env)
-{
- int ret;
- unsigned int i;
- unsigned int activator_msgs_count = 0;
- uint64_t cookie = time(NULL);
- struct kdbus_conn *conn;
- struct kdbus_conn *sender;
- struct kdbus_conn *activator;
- struct kdbus_msg *msg;
- uint64_t flags;
- struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
- struct kdbus_policy_access access = {
- .type = KDBUS_POLICY_ACCESS_USER,
- .id = geteuid(),
- .access = KDBUS_POLICY_OWN,
- };
-
- activator = kdbus_hello_activator(env->buspath, "foo.test.activator",
- &access, 1);
- ASSERT_RETURN(activator);
-
- conn = kdbus_hello(env->buspath, 0, NULL, 0);
- sender = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(conn || sender);
-
- ret = kdbus_list(sender, KDBUS_LIST_NAMES |
- KDBUS_LIST_UNIQUE |
- KDBUS_LIST_ACTIVATORS |
- KDBUS_LIST_QUEUED);
- ASSERT_RETURN(ret == 0);
-
- for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
- ret = kdbus_msg_send(sender, "foo.test.activator",
- cookie++, 0, 0, 0,
- KDBUS_DST_ID_NAME);
- if (ret < 0)
- break;
- activator_msgs_count++;
- }
-
- /* we must have at least sent one message */
- ASSERT_RETURN_VAL(i > 0, -errno);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- /* Good, activator queue is full now */
-
- /* ENXIO on direct send (activators can never be addressed by ID) */
- ret = kdbus_msg_send(conn, NULL, cookie++, 0, 0, 0, activator->id);
- ASSERT_RETURN(ret == -ENXIO);
-
- /* can't queue more */
- ret = kdbus_msg_send(conn, "foo.test.activator", cookie++,
- 0, 0, 0, KDBUS_DST_ID_NAME);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- /* no match installed, so the broadcast will not inc dropped_msgs */
- ret = kdbus_msg_send(sender, NULL, cookie++, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
- ASSERT_RETURN(ret == 0);
-
- /* Check activator queue */
- ret = kdbus_cmd_recv(activator->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv.dropped_msgs == 0);
-
- activator_msgs_count--;
-
- msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
- kdbus_msg_free(msg);
-
-
- /* Stage 1) of test check the pool memory quota */
-
- /* Consume the connection pool memory */
- for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
- ret = kdbus_msg_send(sender, NULL,
- cookie++, 0, 0, 0, conn->id);
- if (ret < 0)
- break;
- }
-
- /* consume one message, so later at least one can be moved */
- memset(&recv, 0, sizeof(recv));
- recv.size = sizeof(recv);
- ret = kdbus_cmd_recv(conn->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv.dropped_msgs == 0);
- msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
- kdbus_msg_free(msg);
-
- /* Try to acquire the name now */
- flags = KDBUS_NAME_REPLACE_EXISTING;
- ret = kdbus_name_acquire(conn, "foo.test.activator", &flags);
- ASSERT_RETURN(ret == 0);
-
- /* try to read messages and see if we have lost some */
- memset(&recv, 0, sizeof(recv));
- recv.size = sizeof(recv);
- ret = kdbus_cmd_recv(conn->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv.dropped_msgs != 0);
-
- /* number of dropped msgs < received ones (at least one was moved) */
- ASSERT_RETURN(recv.dropped_msgs < activator_msgs_count);
-
- /* Deduct the number of dropped msgs from the activator msgs */
- activator_msgs_count -= recv.dropped_msgs;
-
- msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
- kdbus_msg_free(msg);
-
- /*
- * Release the name and hand it back to activator, now
- * we should have 'activator_msgs_count' msgs again in
- * the activator queue
- */
- ret = kdbus_name_release(conn, "foo.test.activator");
- ASSERT_RETURN(ret == 0);
-
- /* make sure that we got our previous activator msgs */
- ret = kdbus_msg_recv(activator, &msg, NULL);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(msg->src_id == sender->id);
-
- activator_msgs_count--;
-
- kdbus_msg_free(msg);
-
-
- /* Stage 2) of test check max message quota */
-
- /* Empty conn queue */
- for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
- ret = kdbus_msg_recv(conn, NULL, NULL);
- if (ret == -EAGAIN)
- break;
- }
-
- /* fill queue with max msgs quota */
- ret = kdbus_fill_conn_queue(sender, conn->id, KDBUS_CONN_MAX_MSGS);
- ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
-
- /* This one is lost but it is not accounted */
- ret = kdbus_msg_send(sender, NULL,
- cookie++, 0, 0, 0, conn->id);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- /* Acquire the name again */
- flags = KDBUS_NAME_REPLACE_EXISTING;
- ret = kdbus_name_acquire(conn, "foo.test.activator", &flags);
- ASSERT_RETURN(ret == 0);
-
- memset(&recv, 0, sizeof(recv));
- recv.size = sizeof(recv);
-
- /*
- * Try to read messages and make sure that we have lost all
- * the activator messages due to quota checks. Our queue is
- * already full.
- */
- ret = kdbus_cmd_recv(conn->fd, &recv);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv.dropped_msgs == activator_msgs_count);
-
- msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
- kdbus_msg_free(msg);
-
- kdbus_conn_free(sender);
- kdbus_conn_free(conn);
- kdbus_conn_free(activator);
-
- return 0;
-}
-
-static int kdbus_test_expected_reply_quota(struct kdbus_test_env *env)
-{
- int ret;
- unsigned int i, n;
- unsigned int count;
- uint64_t cookie = 0x1234abcd5678eeff;
- struct kdbus_conn *conn;
- struct kdbus_conn *connections[9];
-
- conn = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(conn);
-
- for (i = 0; i < 9; i++) {
- connections[i] = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(connections[i]);
- }
-
- count = 0;
- /* Send 16 messages to 8 different connections */
- for (i = 0; i < 8; i++) {
- for (n = 0; n < 16; n++) {
- ret = kdbus_msg_send(conn, NULL, cookie++,
- KDBUS_MSG_EXPECT_REPLY,
- 100000000ULL, 0,
- connections[i]->id);
- if (ret < 0)
- break;
-
- count++;
- }
- }
-
- /*
- * We should have queued at least
- * KDBUS_CONN_MAX_REQUESTS_PENDING method call
- */
- ASSERT_RETURN(count == KDBUS_CONN_MAX_REQUESTS_PENDING);
-
- /*
- * Now try to send a message to the last connection,
- * if we have reached KDBUS_CONN_MAX_REQUESTS_PENDING
- * no further requests are allowed
- */
- ret = kdbus_msg_send(conn, NULL, cookie++, KDBUS_MSG_EXPECT_REPLY,
- 1000000000ULL, 0, connections[8]->id);
- ASSERT_RETURN(ret == -EMLINK);
-
- for (i = 0; i < 9; i++)
- kdbus_conn_free(connections[i]);
-
- kdbus_conn_free(conn);
-
- return 0;
-}
-
-int kdbus_test_pool_quota(struct kdbus_test_env *env)
-{
- struct kdbus_conn *a, *b, *c;
- struct kdbus_cmd_send cmd = {};
- struct kdbus_item *item;
- struct kdbus_msg *recv_msg;
- struct kdbus_msg *msg;
- uint64_t cookie = time(NULL);
- uint64_t size;
- unsigned int i;
- char *payload;
- int ret;
-
- /* just a guard */
- if (POOL_SIZE <= KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE ||
- POOL_SIZE % KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE != 0)
- return 0;
-
- payload = calloc(KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE, sizeof(char));
- ASSERT_RETURN_VAL(payload, -ENOMEM);
-
- a = kdbus_hello(env->buspath, 0, NULL, 0);
- b = kdbus_hello(env->buspath, 0, NULL, 0);
- c = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(a && b && c);
-
- size = sizeof(struct kdbus_msg);
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
-
- msg = malloc(size);
- ASSERT_RETURN_VAL(msg, -ENOMEM);
-
- memset(msg, 0, size);
- msg->size = size;
- msg->src_id = a->id;
- msg->dst_id = c->id;
- msg->payload_type = KDBUS_PAYLOAD_DBUS;
-
- item = msg->items;
- item->type = KDBUS_ITEM_PAYLOAD_VEC;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
- item->vec.address = (uintptr_t)payload;
- item->vec.size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
- item = KDBUS_ITEM_NEXT(item);
-
- cmd.size = sizeof(cmd);
- cmd.msg_address = (uintptr_t)msg;
-
- /*
- * Send 2097248 bytes, a user is only allowed to get 33% of half of
- * the free space of the pool, the already used space is
- * accounted as free space
- */
- size += KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
- for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
- msg->cookie = cookie++;
-
- ret = kdbus_cmd_send(a->fd, &cmd);
- ASSERT_RETURN_VAL(ret == 0, ret);
- }
-
- /* Try to get more than 33% */
- msg->cookie = cookie++;
- ret = kdbus_cmd_send(a->fd, &cmd);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- /* We still can pass small messages */
- ret = kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id);
- ASSERT_RETURN(ret == 0);
-
- for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
- ret = kdbus_msg_recv(c, &recv_msg, NULL);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv_msg->src_id == a->id);
-
- kdbus_msg_free(recv_msg);
- }
-
- ret = kdbus_msg_recv(c, &recv_msg, NULL);
- ASSERT_RETURN(ret == 0);
- ASSERT_RETURN(recv_msg->src_id == b->id);
-
- kdbus_msg_free(recv_msg);
-
- ret = kdbus_msg_recv(c, NULL, NULL);
- ASSERT_RETURN(ret == -EAGAIN);
-
- free(msg);
- free(payload);
-
- kdbus_conn_free(c);
- kdbus_conn_free(b);
- kdbus_conn_free(a);
-
- return 0;
-}
-
-int kdbus_test_message_quota(struct kdbus_test_env *env)
-{
- struct kdbus_conn *a, *b;
- uint64_t cookie = 0;
- int ret;
- int i;
-
- ret = kdbus_test_activator_quota(env);
- ASSERT_RETURN(ret == 0);
-
- ret = kdbus_test_notify_kernel_quota(env);
- ASSERT_RETURN(ret == 0);
-
- ret = kdbus_test_pool_quota(env);
- ASSERT_RETURN(ret == 0);
-
- ret = kdbus_test_expected_reply_quota(env);
- ASSERT_RETURN(ret == 0);
-
- a = kdbus_hello(env->buspath, 0, NULL, 0);
- b = kdbus_hello(env->buspath, 0, NULL, 0);
-
- ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS);
- ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
-
- ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i) {
- ret = kdbus_msg_recv(a, NULL, NULL);
- ASSERT_RETURN(ret == 0);
- }
-
- ret = kdbus_msg_recv(a, NULL, NULL);
- ASSERT_RETURN(ret == -EAGAIN);
-
- ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1);
- ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
-
- ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
- ASSERT_RETURN(ret == -ENOBUFS);
-
- kdbus_conn_free(a);
- kdbus_conn_free(b);
-
- return TEST_OK;
-}
-
-int kdbus_test_memory_access(struct kdbus_test_env *env)
-{
- struct kdbus_conn *a, *b;
- struct kdbus_cmd_send cmd = {};
- struct kdbus_item *item;
- struct kdbus_msg *msg;
- uint64_t test_addr = 0;
- char line[256];
- uint64_t size;
- FILE *f;
- int ret;
-
- /*
- * Search in /proc/kallsyms for the address of a kernel symbol that
- * should always be there, regardless of the config. Use that address
- * in a PAYLOAD_VEC item and make sure it's inaccessible.
- */
-
- f = fopen("/proc/kallsyms", "r");
- if (!f)
- return TEST_SKIP;
-
- while (fgets(line, sizeof(line), f)) {
- char *s = line;
-
- if (!strsep(&s, " "))
- continue;
-
- if (!strsep(&s, " "))
- continue;
-
- if (!strncmp(s, "mutex_lock", 10)) {
- test_addr = strtoull(line, NULL, 16);
- break;
- }
- }
-
- fclose(f);
-
- if (!test_addr)
- return TEST_SKIP;
-
- a = kdbus_hello(env->buspath, 0, NULL, 0);
- b = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(a && b);
-
- size = sizeof(struct kdbus_msg);
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
-
- msg = alloca(size);
- ASSERT_RETURN_VAL(msg, -ENOMEM);
-
- memset(msg, 0, size);
- msg->size = size;
- msg->src_id = a->id;
- msg->dst_id = b->id;
- msg->payload_type = KDBUS_PAYLOAD_DBUS;
-
- item = msg->items;
- item->type = KDBUS_ITEM_PAYLOAD_VEC;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
- item->vec.address = test_addr;
- item->vec.size = sizeof(void*);
- item = KDBUS_ITEM_NEXT(item);
-
- cmd.size = sizeof(cmd);
- cmd.msg_address = (uintptr_t)msg;
-
- ret = kdbus_cmd_send(a->fd, &cmd);
- ASSERT_RETURN(ret == -EFAULT);
-
- kdbus_conn_free(b);
- kdbus_conn_free(a);
-
- return 0;
-}