12 #include <sys/eventfd.h>
13 #include <sys/types.h>
16 #include "kdbus-api.h"
17 #include "kdbus-util.h"
18 #include "kdbus-enum.h"
19 #include "kdbus-test.h"
21 /* maximum number of queued messages from the same individual user */
22 #define KDBUS_CONN_MAX_MSGS 256U
24 /* maximum number of queued requests waiting for a reply */
25 #define KDBUS_CONN_MAX_REQUESTS_PENDING 1024U
27 /* maximum message payload size */
28 #define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE (2 * 1024UL * 1024UL)
30 wur int kdbus_test_message_basic(struct kdbus_test_env *env)
32 struct kdbus_conn *conn;
33 struct kdbus_conn *sender;
34 struct kdbus_msg *msg;
35 uint64_t cookie = 0x1234abcd5678eeff;
38 ASSERT_NONZERO(sender = kdbus_hello(env->buspath, 0, NULL, 0));
40 /* create a 2nd connection */
41 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
43 ASSERT_ZERO(kdbus_add_match_empty(conn));
45 ASSERT_ZERO(kdbus_add_match_empty(sender));
47 /* send over 1st connection */
48 ASSERT_ZERO(kdbus_msg_send(sender, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST));
50 /* Make sure that we do get our own broadcasts */
51 ASSERT_ZERO(kdbus_msg_recv(sender, &msg, &offset));
52 ASSERT_RETURN(msg->cookie,==,cookie);
55 /* ... and receive on the 2nd */
56 ASSERT_ZERO(kdbus_msg_recv_poll(conn, 100, &msg, &offset));
57 ASSERT_RETURN(msg->cookie,==,cookie);
61 /* Msgs that expect a reply must have timeout and cookie */
62 ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY, 1000000000, 0, conn->id)); /* no cookie */
63 ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 1, KDBUS_MSG_EXPECT_REPLY, 0, 0, conn->id)); /* no timeout */
64 ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY, 0, 0, conn->id)); /* neither cookie nor timeout */
66 /* Faked replies with a valid reply cookie are rejected iff not TIZEN */
67 ASSERT_RETURN(ONTIZEN(0,-EBADSLT),==,kdbus_msg_send_reply(conn, time(NULL) ^ cookie, sender->id));
69 ASSERT_ZERO(kdbus_free(conn, offset));
71 kdbus_conn_free(sender);
72 kdbus_conn_free(conn);
77 static wur int msg_recv_prio(struct kdbus_conn *conn,
78 int64_t requested_prio,
79 int64_t expected_prio)
81 struct kdbus_cmd_recv recv = {
83 .flags = KDBUS_RECV_USE_PRIORITY,
84 .priority = requested_prio,
86 struct kdbus_msg *msg;
89 ret = kdbus_cmd_recv(conn->fd, &recv);
91 kdbus_printf("error receiving message: %d (%m)\n", -errno);
95 msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
96 dumpret = kdbus_msg_dump(msg);
98 if (msg->priority != expected_prio) {
99 kdbus_printf("expected message prio %lld, got %lld\n",
100 (unsigned long long) expected_prio,
101 (unsigned long long) msg->priority);
106 ret = kdbus_free(conn, recv.msg.offset);
115 wur int kdbus_test_message_prio(struct kdbus_test_env *env)
117 struct kdbus_conn *a, *b;
120 ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0));
121 ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0));
123 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 25, a->id));
124 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id));
125 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id));
126 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -35, a->id));
127 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id));
128 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 20, a->id));
129 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -15, a->id));
130 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id));
131 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id));
132 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id));
133 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id));
134 ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -10, a->id));
136 ASSERT_ZERO(msg_recv_prio(a, -200, -800));
137 ASSERT_ZERO(msg_recv_prio(a, -100, -800));
138 ASSERT_ZERO(msg_recv_prio(a, -400, -600));
139 ASSERT_RETURN(msg_recv_prio(a, -400, -600),==,-EAGAIN);
140 ASSERT_ZERO(msg_recv_prio(a, 10, -150));
141 ASSERT_ZERO(msg_recv_prio(a, 10, -100));
143 kdbus_printf("--- get priority (all)\n");
144 ASSERT_ZERO(kdbus_msg_recv(a, NULL, NULL));
152 static wur int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env)
155 struct kdbus_conn *conn;
156 struct kdbus_conn *reader;
157 struct kdbus_msg *msg = NULL;
158 struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
160 ASSERT_NONZERO(reader = kdbus_hello(env->buspath, 0, NULL, 0));
161 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
163 /* Register for ID signals */
164 ASSERT_ZERO(kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD, KDBUS_MATCH_ID_ANY));
166 ASSERT_ZERO(kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE, KDBUS_MATCH_ID_ANY));
168 /* Each iteration two notifications: add and remove ID */
169 for (i = 0; i < KDBUS_CONN_MAX_MSGS / 2; i++) {
170 struct kdbus_conn *notifier;
171 ASSERT_NONZERO(notifier = kdbus_hello(env->buspath, 0, NULL, 0));
172 kdbus_conn_free(notifier);
176 * Now the reader queue is full with kernel notfications,
177 * but as a user we still have room to push our messages.
179 ASSERT_ZERO(kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id));
181 /* More ID kernel notifications that will be lost */
182 kdbus_conn_free(conn);
184 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
186 kdbus_conn_free(conn);
189 * We lost only 3 packets since only signal msgs are
190 * accounted. The connection ID add/remove notification
192 ASSERT_ZERO(kdbus_cmd_recv(reader->fd, &recv));
193 ASSERT_NONZERO(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS);
194 ASSERT_RETURN(recv.dropped_msgs,==,3U);
196 msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
200 for (i = 0; i < KDBUS_CONN_MAX_MSGS - 1; i++) {
201 memset(&recv, 0, sizeof(recv));
202 recv.size = sizeof(recv);
204 ASSERT_ZERO(kdbus_cmd_recv(reader->fd, &recv));
205 ASSERT_ZERO(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS);
207 msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
211 ASSERT_ZERO(kdbus_msg_recv(reader, NULL, NULL));
213 ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(reader, NULL, NULL));
215 kdbus_conn_free(reader);
220 /* Return the number of message successfully sent */
221 static wur int kdbus_fill_conn_queue(struct kdbus_conn *conn_src,
223 unsigned int max_msgs)
228 struct kdbus_cmd_send cmd = {};
229 struct kdbus_msg *msg;
232 size = sizeof(struct kdbus_msg);
234 ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM);
236 memset(msg, 0, size);
238 msg->src_id = conn_src->id;
239 msg->dst_id = dst_id;
240 msg->payload_type = KDBUS_PAYLOAD_DBUS;
242 cmd.size = sizeof(cmd);
243 cmd.msg_address = (uintptr_t)msg;
245 for (i = 0; i < max_msgs; i++) {
246 msg->cookie = ++cookie;
247 ret = kdbus_cmd_send(conn_src->fd, &cmd);
249 /*print("fill_conn_queue_senderr(%d)", ret);*/
259 wur int kdbus_test_activator_quota(struct kdbus_test_env *env)
261 unsigned i, activator_msgs_count=0;
262 uint64_t cookie = time(NULL);
263 uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
264 struct kdbus_conn *conn;
265 struct kdbus_conn *sender;
266 struct kdbus_conn *activator;
267 struct kdbus_msg *msg;
268 struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
269 struct kdbus_policy_access access = {
270 .type = KDBUS_POLICY_ACCESS_USER,
272 .access = KDBUS_POLICY_OWN,
275 ASSERT_NONZERO(activator = kdbus_hello_activator(env->buspath, "foo.test.activator", &access, 1));
277 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
278 ASSERT_NONZERO(sender = kdbus_hello(env->buspath, 0, NULL, 0));
280 ASSERT_ZERO(kdbus_list(sender, KDBUS_LIST_NAMES | KDBUS_LIST_UNIQUE | KDBUS_LIST_ACTIVATORS | KDBUS_LIST_QUEUED));
282 #define EXHAUST(EXPECTERR,SENDOP) do {\
285 ASSERT_RETURN(i,<=,KDBUS_CONN_MAX_MSGS);\
287 ASSERT_RETURN((EXPECTERR),==,ret);\
288 ASSERT_RETURN(i,<,KDBUS_CONN_MAX_MSGS);\
293 EXHAUST(-ENOBUFS,kdbus_msg_send(sender, "foo.test.activator", ++cookie, 0, 0, 0, KDBUS_DST_ID_NAME));
294 activator_msgs_count = i;
296 /* we must have at least sent one message */
297 ASSERT_RETURN_VAL(i,>,0U, -errno);
299 /* Good, activator queue is full now */
301 /* ENXIO on direct send (activators can never be addressed by ID) */
302 ASSERT_RETURN(-ENXIO,==,kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, activator->id));
304 /* can't queue more */
305 ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(conn, "foo.test.activator", ++cookie, 0, 0, 0, KDBUS_DST_ID_NAME));
307 /* no match installed, so the broadcast will not inc dropped_msgs */
308 ASSERT_ZERO(kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST));
310 /* Check activator queue */
311 ASSERT_ZERO(kdbus_cmd_recv(activator->fd, &recv));
312 ASSERT_ZERO(recv.dropped_msgs);
314 msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
315 ASSERT_RETURN(msg->src_id,==,sender->id);
316 ASSERT_RETURN(msg->dst_id,==,(typeof(msg->dst_id))KDBUS_DST_ID_NAME);
317 --activator_msgs_count;
321 /* Stage 1) of test check the pool memory quota */
323 /* Consume the connection pool memory */
324 EXHAUST(-ENOBUFS,kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, conn->id));
326 /* consume one message, so later at least one can be moved */
327 memset(&recv, 0, sizeof(recv));
328 recv.size = sizeof(recv);
329 ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv));
330 ASSERT_ZERO(recv.dropped_msgs);
331 msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
334 /* Try to acquire the name now */
335 ASSERT_ZERO(kdbus_name_acquire(conn, "foo.test.activator", &flags));
337 /* try to read messages and see if we have lost some */
338 memset(&recv, 0, sizeof(recv));
339 recv.size = sizeof(recv);
340 ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv));
341 ASSERT_NONZERO(recv.dropped_msgs);
343 /* number of dropped msgs < received ones (at least one was moved) */
344 ASSERT_RETURN(recv.dropped_msgs,<,activator_msgs_count);
346 /* Deduct the number of dropped msgs from the activator msgs */
347 activator_msgs_count -= recv.dropped_msgs;
349 msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
352 * Release the name and hand it back to activator, now
353 * we should have 'activator_msgs_count' msgs again in
354 * the activator queue
356 ASSERT_ZERO(kdbus_name_release(conn, "foo.test.activator"));
358 /* make sure that we got our previous activator msgs */
359 ASSERT_ZERO(kdbus_msg_recv(activator, &msg, NULL));
360 ASSERT_RETURN(msg->src_id,==,sender->id);
361 ASSERT_RETURN(msg->dst_id,==,(typeof(msg->dst_id))KDBUS_DST_ID_NAME);
362 --activator_msgs_count;
366 /* Stage 2) of test check max message quota */
368 /* Empty conn queue and refill it to the brink anew */
369 EXHAUST(-EAGAIN,kdbus_msg_recv(conn, NULL, NULL));
370 EXHAUST(-ENOBUFS,kdbus_msg_send(sender, NULL, ++cookie, 0, 0, 0, conn->id));
373 if (!activator_msgs_count)
374 ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(activator, NULL, NULL));
376 /* Acquire the name again */
377 flags = KDBUS_NAME_REPLACE_EXISTING;
378 ASSERT_ZERO(kdbus_name_acquire(conn, "foo.test.activator", &flags));
380 memset(&recv, 0, sizeof(recv));
381 recv.size = sizeof(recv);
384 * Try to read messages and make sure that we have lost all
385 * the activator messages due to quota checks. Our queue is
388 ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv));
389 ASSERT_RETURN(recv.dropped_msgs,==,activator_msgs_count);
391 msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
394 kdbus_conn_free(sender);
395 kdbus_conn_free(conn);
396 kdbus_conn_free(activator);
401 #define TIMEOUT_CONNECTION_COUNT 8
402 #define TIMEOUTS_PER_CONNECTION (MIN(KDBUS_CONN_MAX_REQUESTS_PENDING,KDBUS_CONN_MAX_MSGS)/TIMEOUT_CONNECTION_COUNT)
404 static wur int kdbus_test_expected_reply_validate_timeouts(struct kdbus_conn *conn, uint64_t first_cookie, uint64_t type)
406 uint64_t cookie_reply, seqnum, monotonic_ns, realtime_ns, prev_seqnum=0, prev_monotonic_ns=0, prev_realtime_ns=0;
407 unsigned i, next_cookie[TIMEOUT_CONNECTION_COUNT];
408 memset(next_cookie, 0, sizeof(next_cookie));
409 for (i=0; i < MIN(KDBUS_CONN_MAX_REQUESTS_PENDING,KDBUS_CONN_MAX_MSGS); i++) {
411 ASSERT_ZERO(timeout_msg_recv(conn, type, &cookie_reply, &seqnum, &monotonic_ns, &realtime_ns));
412 #define A(W,R) do { ASSERT_RETURN(prev_##W,R,W); prev_##W = W; } while (0);
417 ASSERT_RETURN(first_cookie,<=,cookie_reply);
418 cookie_reply -= first_cookie;
419 n = cookie_reply % TIMEOUT_CONNECTION_COUNT;
420 r = cookie_reply / TIMEOUT_CONNECTION_COUNT;
421 ASSERT_RETURN(r,==,next_cookie[n]);
424 ASSERT_NO_PENDING(conn);
428 static wur int kdbus_test_expected_reply_timeouts_or_quota(struct kdbus_test_env *env)
431 uint64_t first_cookie = 0x1234abcd5678eeff;
432 struct kdbus_conn *conn;
433 struct kdbus_conn *connections[1+TIMEOUT_CONNECTION_COUNT];
435 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
437 for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++)
438 ASSERT_NONZERO(connections[i] = kdbus_hello(env->buspath, 0, NULL, 0));
440 _Static_assert(!(KDBUS_CONN_MAX_REQUESTS_PENDING%TIMEOUT_CONNECTION_COUNT), "KDBUS_CONN_MAX_REQUESTS_PENDING) not a multitude of TIMEOUT_CONNECTION_COUNT - quota test needs to be modified to reflect that");
442 /* Send messages to TIMEOUT_CONNECTION_COUNT different connections */
443 for (i = 0; i < TIMEOUT_CONNECTION_COUNT; i++)
444 for (n = 0; n < TIMEOUTS_PER_CONNECTION; n++) {
445 ASSERT_ZERO(kdbus_msg_send(conn, NULL, first_cookie + i + n*TIMEOUT_CONNECTION_COUNT,
446 KDBUS_MSG_EXPECT_REPLY,
447 200000000ULL /* 0.2s */, 0,
448 connections[i]->id));
449 /* drain queue to avoid hitting KDBUS_CONN_MAX_MSGS */
450 ASSERT_ZERO(kdbus_msg_recv(connections[i], NULL, NULL));
453 sleep(1); /* just to wait and see if timeout logic somehow destabilizes the system */
455 ASSERT_ZERO(kdbus_test_expected_reply_validate_timeouts(conn, first_cookie, KDBUS_ITEM_REPLY_TIMEOUT));
457 for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++)
458 kdbus_conn_free(connections[i]);
460 kdbus_conn_free(conn);
465 static wur int kdbus_test_expected_reply_quota(struct kdbus_test_env *env)
468 uint64_t first_cookie = 0x5678eeff1234abcd;
469 struct kdbus_conn *conn;
470 struct kdbus_conn *connections[1+TIMEOUT_CONNECTION_COUNT];
472 ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0));
474 for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++)
475 ASSERT_NONZERO(connections[i] = kdbus_hello(env->buspath, 0, NULL, 0));
477 /* Send messages to TIMEOUT_CONNECTION_COUNT different connections */
478 for (i = 0; i < TIMEOUT_CONNECTION_COUNT; i++)
479 for (n = 0; n < KDBUS_CONN_MAX_REQUESTS_PENDING/TIMEOUT_CONNECTION_COUNT; n++) {
480 ASSERT_ZERO(kdbus_msg_send(conn, NULL, first_cookie + i + n*TIMEOUT_CONNECTION_COUNT,
481 KDBUS_MSG_EXPECT_REPLY,
482 KDBUS_TIMEOUT_INFINITE, 0, /* massive timeout to make sure all pending replies do not timeout before quota check below */
483 connections[i]->id));
484 /* drain queue to avoid hitting KDBUS_CONN_MAX_MSGS */
485 ASSERT_ZERO(kdbus_msg_recv(connections[i], NULL, NULL));
489 * Now try to send a message to the last connection,
490 * if we have reached KDBUS_CONN_MAX_REQUESTS_PENDING
491 * no further requests are allowed
493 ASSERT_RETURN(-EMLINK,==,kdbus_msg_send(conn, NULL, first_cookie + TIMEOUT_CONNECTION_COUNT*TIMEOUTS_PER_CONNECTION, KDBUS_MSG_EXPECT_REPLY, 1000000000ULL, 0, connections[TIMEOUT_CONNECTION_COUNT]->id));
495 for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++)
496 kdbus_conn_free(connections[i]);
498 ASSERT_ZERO(kdbus_test_expected_reply_validate_timeouts(conn, first_cookie, KDBUS_ITEM_REPLY_DEAD));
500 kdbus_conn_free(conn);
505 wur int kdbus_test_pool_quota(struct kdbus_test_env *env)
507 struct kdbus_conn *a, *b, *c;
508 struct kdbus_cmd_send cmd = {};
509 struct kdbus_item *item;
510 struct kdbus_msg *recv_msg;
511 struct kdbus_msg *msg;
512 uint64_t cookie = time(NULL);
519 if (POOL_SIZE <= KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE ||
520 POOL_SIZE % KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE != 0)
523 payload = calloc(KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE, sizeof(char));
524 ASSERT_RETURN_VAL(payload,!=,NULL, -ENOMEM);
526 ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0));
527 ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0));
528 ASSERT_NONZERO(c = kdbus_hello(env->buspath, 0, NULL, 0));
530 size = sizeof(struct kdbus_msg);
531 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
534 ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM);
536 memset(msg, 0, size);
540 msg->payload_type = KDBUS_PAYLOAD_DBUS;
543 item->type = KDBUS_ITEM_PAYLOAD_VEC;
544 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
545 item->vec.address = (uintptr_t)payload;
546 item->vec.size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
547 item = KDBUS_ITEM_NEXT(item);
549 cmd.size = sizeof(cmd);
550 cmd.msg_address = (uintptr_t)msg;
553 * Send 2097248 bytes, a user is only allowed to get 33% of half of
554 * the free space of the pool, the already used space is
555 * accounted as free space
557 size += KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
558 for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
559 msg->cookie = cookie++;
561 ret = kdbus_cmd_send(a->fd, &cmd);
562 ASSERT_RETURN_VAL(ret,==,0, ret);
565 /* Try to get more than 33% */
566 msg->cookie = cookie++;
567 ASSERT_RETURN(-ENOBUFS,==,kdbus_cmd_send(a->fd, &cmd));
569 /* We still can pass small messages */
570 ASSERT_ZERO(kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id));
572 for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
573 ASSERT_ZERO(kdbus_msg_recv(c, &recv_msg, NULL));
574 ASSERT_RETURN(recv_msg->src_id,==,a->id);
576 kdbus_msg_free(recv_msg);
579 ASSERT_ZERO(kdbus_msg_recv(c, &recv_msg, NULL));
580 ASSERT_RETURN(recv_msg->src_id,==,b->id);
582 kdbus_msg_free(recv_msg);
584 ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(c, NULL, NULL));
596 wur int kdbus_test_message_quota(struct kdbus_test_env *env)
598 struct kdbus_conn *a, *b;
602 ASSERT_ZERO(kdbus_test_notify_kernel_quota(env));
604 ASSERT_ZERO(kdbus_test_pool_quota(env));
606 ASSERT_ZERO(kdbus_test_expected_reply_timeouts_or_quota(env));
608 ASSERT_ZERO(kdbus_test_expected_reply_quota(env));
610 a = kdbus_hello(env->buspath, 0, NULL, 0);
611 b = kdbus_hello(env->buspath, 0, NULL, 0);
613 ASSERT_RETURN((typeof(kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS)))KDBUS_CONN_MAX_MSGS,==,kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS));
615 ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id));
617 for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i)
618 ASSERT_ZERO(kdbus_msg_recv(a, NULL, NULL));
620 ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(a, NULL, NULL));
622 ASSERT_RETURN((typeof(kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1)))KDBUS_CONN_MAX_MSGS,==,kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1));
624 ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id));
632 wur int kdbus_test_memory_access(struct kdbus_test_env *env)
634 struct kdbus_conn *a, *b;
635 struct kdbus_cmd_send cmd = {};
636 struct kdbus_item *item;
637 struct kdbus_msg *msg;
638 uint64_t test_addr = 0;
644 * Search in /proc/kallsyms for the address of a kernel symbol that
645 * should always be there, regardless of the config. Use that address
646 * in a PAYLOAD_VEC item and make sure it's inaccessible.
649 f = fopen("/proc/kallsyms", "r");
653 while (fgets(line, sizeof(line), f)) {
656 if (!strsep(&s, " "))
659 if (!strsep(&s, " "))
662 if (!strncmp(s, "mutex_lock", 10)) {
663 test_addr = strtoull(line, NULL, 16);
673 ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0));
674 ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0));
676 size = sizeof(struct kdbus_msg);
677 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
680 ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM);
682 memset(msg, 0, size);
686 msg->payload_type = KDBUS_PAYLOAD_DBUS;
689 item->type = KDBUS_ITEM_PAYLOAD_VEC;
690 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
691 item->vec.address = test_addr;
692 item->vec.size = sizeof(void*);
693 item = KDBUS_ITEM_NEXT(item);
695 cmd.size = sizeof(cmd);
696 cmd.msg_address = (uintptr_t)msg;
698 ASSERT_RETURN(-EFAULT,==,kdbus_cmd_send(a->fd, &cmd));