kdbus: the driver, original and non-working
[platform/kernel/linux-exynos.git] / tools / testing / selftests / kdbus / test-fd.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <time.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <unistd.h>
9 #include <stdint.h>
10 #include <errno.h>
11 #include <assert.h>
12 #include <sys/types.h>
13 #include <sys/mman.h>
14 #include <sys/socket.h>
15 #include <sys/wait.h>
16
17 #include "kdbus-api.h"
18 #include "kdbus-test.h"
19 #include "kdbus-util.h"
20 #include "kdbus-enum.h"
21
22 #define KDBUS_MSG_MAX_ITEMS     128
23 #define KDBUS_USER_MAX_CONN     256
24
25 /* maximum number of inflight fds in a target queue per user */
26 #define KDBUS_CONN_MAX_FDS_PER_USER     16
27
28 /* maximum number of memfd items per message */
29 #define KDBUS_MSG_MAX_MEMFD_ITEMS       16
30
31 static int make_msg_payload_dbus(uint64_t src_id, uint64_t dst_id,
32                                  uint64_t msg_size,
33                                  struct kdbus_msg **msg_dbus)
34 {
35         struct kdbus_msg *msg;
36
37         msg = malloc(msg_size);
38         ASSERT_RETURN_VAL(msg, -ENOMEM);
39
40         memset(msg, 0, msg_size);
41         msg->size = msg_size;
42         msg->src_id = src_id;
43         msg->dst_id = dst_id;
44         msg->payload_type = KDBUS_PAYLOAD_DBUS;
45
46         *msg_dbus = msg;
47
48         return 0;
49 }
50
51 static void make_item_memfds(struct kdbus_item *item,
52                              int *memfds, size_t memfd_size)
53 {
54         size_t i;
55
56         for (i = 0; i < memfd_size; i++) {
57                 item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
58                 item->size = KDBUS_ITEM_HEADER_SIZE +
59                              sizeof(struct kdbus_memfd);
60                 item->memfd.fd = memfds[i];
61                 item->memfd.size = sizeof(uint64_t); /* const size */
62                 item = KDBUS_ITEM_NEXT(item);
63         }
64 }
65
66 static void make_item_fds(struct kdbus_item *item,
67                           int *fd_array, size_t fd_size)
68 {
69         size_t i;
70         item->type = KDBUS_ITEM_FDS;
71         item->size = KDBUS_ITEM_HEADER_SIZE + (sizeof(int) * fd_size);
72
73         for (i = 0; i < fd_size; i++)
74                 item->fds[i] = fd_array[i];
75 }
76
77 static int memfd_write(const char *name, void *buf, size_t bufsize)
78 {
79         ssize_t ret;
80         int memfd;
81
82         memfd = sys_memfd_create(name, 0);
83         ASSERT_RETURN_VAL(memfd >= 0, memfd);
84
85         ret = write(memfd, buf, bufsize);
86         ASSERT_RETURN_VAL(ret == (ssize_t)bufsize, -EAGAIN);
87
88         ret = sys_memfd_seal_set(memfd);
89         ASSERT_RETURN_VAL(ret == 0, -errno);
90
91         return memfd;
92 }
93
94 static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id,
95                        int *memfds_array, size_t memfd_count)
96 {
97         struct kdbus_cmd_send cmd = {};
98         struct kdbus_item *item;
99         struct kdbus_msg *msg;
100         uint64_t size;
101         int ret;
102
103         size = sizeof(struct kdbus_msg);
104         size += memfd_count * KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
105
106         if (dst_id == KDBUS_DST_ID_BROADCAST)
107                 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
108
109         ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
110         ASSERT_RETURN_VAL(ret == 0, ret);
111
112         item = msg->items;
113
114         if (dst_id == KDBUS_DST_ID_BROADCAST) {
115                 item->type = KDBUS_ITEM_BLOOM_FILTER;
116                 item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
117                 item = KDBUS_ITEM_NEXT(item);
118
119                 msg->flags |= KDBUS_MSG_SIGNAL;
120         }
121
122         make_item_memfds(item, memfds_array, memfd_count);
123
124         cmd.size = sizeof(cmd);
125         cmd.msg_address = (uintptr_t)msg;
126
127         ret = kdbus_cmd_send(conn->fd, &cmd);
128         if (ret < 0) {
129                 kdbus_printf("error sending message: %d (%m)\n", ret);
130                 return ret;
131         }
132
133         free(msg);
134         return 0;
135 }
136
137 static int send_fds(struct kdbus_conn *conn, uint64_t dst_id,
138                     int *fd_array, size_t fd_count)
139 {
140         struct kdbus_cmd_send cmd = {};
141         struct kdbus_item *item;
142         struct kdbus_msg *msg;
143         uint64_t size;
144         int ret;
145
146         size = sizeof(struct kdbus_msg);
147         size += KDBUS_ITEM_SIZE(sizeof(int) * fd_count);
148
149         if (dst_id == KDBUS_DST_ID_BROADCAST)
150                 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
151
152         ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
153         ASSERT_RETURN_VAL(ret == 0, ret);
154
155         item = msg->items;
156
157         if (dst_id == KDBUS_DST_ID_BROADCAST) {
158                 item->type = KDBUS_ITEM_BLOOM_FILTER;
159                 item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
160                 item = KDBUS_ITEM_NEXT(item);
161
162                 msg->flags |= KDBUS_MSG_SIGNAL;
163         }
164
165         make_item_fds(item, fd_array, fd_count);
166
167         cmd.size = sizeof(cmd);
168         cmd.msg_address = (uintptr_t)msg;
169
170         ret = kdbus_cmd_send(conn->fd, &cmd);
171         if (ret < 0) {
172                 kdbus_printf("error sending message: %d (%m)\n", ret);
173                 return ret;
174         }
175
176         free(msg);
177         return ret;
178 }
179
180 static int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id,
181                            int *fds_array, size_t fd_count,
182                            int *memfds_array, size_t memfd_count)
183 {
184         struct kdbus_cmd_send cmd = {};
185         struct kdbus_item *item;
186         struct kdbus_msg *msg;
187         uint64_t size;
188         int ret;
189
190         size = sizeof(struct kdbus_msg);
191         size += memfd_count * KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
192         size += KDBUS_ITEM_SIZE(sizeof(int) * fd_count);
193
194         ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
195         ASSERT_RETURN_VAL(ret == 0, ret);
196
197         item = msg->items;
198
199         make_item_fds(item, fds_array, fd_count);
200         item = KDBUS_ITEM_NEXT(item);
201         make_item_memfds(item, memfds_array, memfd_count);
202
203         cmd.size = sizeof(cmd);
204         cmd.msg_address = (uintptr_t)msg;
205
206         ret = kdbus_cmd_send(conn->fd, &cmd);
207         if (ret < 0) {
208                 kdbus_printf("error sending message: %d (%m)\n", ret);
209                 return ret;
210         }
211
212         free(msg);
213         return ret;
214 }
215
216 /* Return the number of received fds */
217 static unsigned int kdbus_item_get_nfds(struct kdbus_msg *msg)
218 {
219         unsigned int fds = 0;
220         const struct kdbus_item *item;
221
222         KDBUS_ITEM_FOREACH(item, msg, items) {
223                 switch (item->type) {
224                 case KDBUS_ITEM_FDS: {
225                         fds += (item->size - KDBUS_ITEM_HEADER_SIZE) /
226                                 sizeof(int);
227                         break;
228                 }
229
230                 case KDBUS_ITEM_PAYLOAD_MEMFD:
231                         fds++;
232                         break;
233
234                 default:
235                         break;
236                 }
237         }
238
239         return fds;
240 }
241
242 static struct kdbus_msg *
243 get_kdbus_msg_with_fd(struct kdbus_conn *conn_src,
244                       uint64_t dst_id, uint64_t cookie, int fd)
245 {
246         int ret;
247         uint64_t size;
248         struct kdbus_item *item;
249         struct kdbus_msg *msg;
250
251         size = sizeof(struct kdbus_msg);
252         if (fd >= 0)
253                 size += KDBUS_ITEM_SIZE(sizeof(int));
254
255         ret = make_msg_payload_dbus(conn_src->id, dst_id, size, &msg);
256         ASSERT_RETURN_VAL(ret == 0, NULL);
257
258         msg->cookie = cookie;
259
260         if (fd >= 0) {
261                 item = msg->items;
262
263                 make_item_fds(item, (int *)&fd, 1);
264         }
265
266         return msg;
267 }
268
269 static int kdbus_test_no_fds(struct kdbus_test_env *env,
270                              int *fds, int *memfd)
271 {
272         pid_t pid;
273         int ret, status;
274         uint64_t cookie;
275         int connfd1, connfd2;
276         struct kdbus_msg *msg, *msg_sync_reply;
277         struct kdbus_cmd_hello hello;
278         struct kdbus_conn *conn_src, *conn_dst, *conn_dummy;
279         struct kdbus_cmd_send cmd = {};
280         struct kdbus_cmd_free cmd_free = {};
281
282         conn_src = kdbus_hello(env->buspath, 0, NULL, 0);
283         ASSERT_RETURN(conn_src);
284
285         connfd1 = open(env->buspath, O_RDWR|O_CLOEXEC);
286         ASSERT_RETURN(connfd1 >= 0);
287
288         connfd2 = open(env->buspath, O_RDWR|O_CLOEXEC);
289         ASSERT_RETURN(connfd2 >= 0);
290
291         /*
292          * Create connections without KDBUS_HELLO_ACCEPT_FD
293          * to test if send fd operations are blocked
294          */
295         conn_dst = malloc(sizeof(*conn_dst));
296         ASSERT_RETURN(conn_dst);
297
298         conn_dummy = malloc(sizeof(*conn_dummy));
299         ASSERT_RETURN(conn_dummy);
300
301         memset(&hello, 0, sizeof(hello));
302         hello.size = sizeof(struct kdbus_cmd_hello);
303         hello.pool_size = POOL_SIZE;
304         hello.attach_flags_send = _KDBUS_ATTACH_ALL;
305
306         ret = kdbus_cmd_hello(connfd1, &hello);
307         ASSERT_RETURN(ret == 0);
308
309         cmd_free.size = sizeof(cmd_free);
310         cmd_free.offset = hello.offset;
311         ret = kdbus_cmd_free(connfd1, &cmd_free);
312         ASSERT_RETURN(ret >= 0);
313
314         conn_dst->fd = connfd1;
315         conn_dst->id = hello.id;
316
317         memset(&hello, 0, sizeof(hello));
318         hello.size = sizeof(struct kdbus_cmd_hello);
319         hello.pool_size = POOL_SIZE;
320         hello.attach_flags_send = _KDBUS_ATTACH_ALL;
321
322         ret = kdbus_cmd_hello(connfd2, &hello);
323         ASSERT_RETURN(ret == 0);
324
325         cmd_free.size = sizeof(cmd_free);
326         cmd_free.offset = hello.offset;
327         ret = kdbus_cmd_free(connfd2, &cmd_free);
328         ASSERT_RETURN(ret >= 0);
329
330         conn_dummy->fd = connfd2;
331         conn_dummy->id = hello.id;
332
333         conn_dst->buf = mmap(NULL, POOL_SIZE, PROT_READ,
334                              MAP_SHARED, connfd1, 0);
335         ASSERT_RETURN(conn_dst->buf != MAP_FAILED);
336
337         conn_dummy->buf = mmap(NULL, POOL_SIZE, PROT_READ,
338                                MAP_SHARED, connfd2, 0);
339         ASSERT_RETURN(conn_dummy->buf != MAP_FAILED);
340
341         /*
342          * Send fds to connection that do not accept fd passing
343          */
344         ret = send_fds(conn_src, conn_dst->id, fds, 1);
345         ASSERT_RETURN(ret == -ECOMM);
346
347         /*
348          * memfd are kdbus payload
349          */
350         ret = send_memfds(conn_src, conn_dst->id, memfd, 1);
351         ASSERT_RETURN(ret == 0);
352
353         ret = kdbus_msg_recv_poll(conn_dst, 100, NULL, NULL);
354         ASSERT_RETURN(ret == 0);
355
356         cookie = time(NULL);
357
358         pid = fork();
359         ASSERT_RETURN_VAL(pid >= 0, pid);
360
361         if (pid == 0) {
362                 struct timespec now;
363
364                 /*
365                  * A sync send/reply to a connection that do not
366                  * accept fds should fail if it contains an fd
367                  */
368                 msg_sync_reply = get_kdbus_msg_with_fd(conn_dst,
369                                                        conn_dummy->id,
370                                                        cookie, fds[0]);
371                 ASSERT_EXIT(msg_sync_reply);
372
373                 ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
374                 ASSERT_EXIT(ret == 0);
375
376                 msg_sync_reply->timeout_ns = now.tv_sec * 1000000000ULL +
377                                              now.tv_nsec + 100000000ULL;
378                 msg_sync_reply->flags = KDBUS_MSG_EXPECT_REPLY;
379
380                 memset(&cmd, 0, sizeof(cmd));
381                 cmd.size = sizeof(cmd);
382                 cmd.msg_address = (uintptr_t)msg_sync_reply;
383                 cmd.flags = KDBUS_SEND_SYNC_REPLY;
384
385                 ret = kdbus_cmd_send(conn_dst->fd, &cmd);
386                 ASSERT_EXIT(ret == -ECOMM);
387
388                 /*
389                  * Now send a normal message, but the sync reply
390                  * will fail since it contains an fd that the
391                  * original sender do not want.
392                  *
393                  * The original sender will fail with -ETIMEDOUT
394                  */
395                 cookie++;
396                 ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
397                                           KDBUS_MSG_EXPECT_REPLY,
398                                           5000000000ULL, 0, conn_src->id, -1);
399                 ASSERT_EXIT(ret == -EREMOTEIO);
400
401                 cookie++;
402                 ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL);
403                 ASSERT_EXIT(ret == 0);
404                 ASSERT_EXIT(msg->cookie == cookie);
405
406                 free(msg_sync_reply);
407                 kdbus_msg_free(msg);
408
409                 _exit(EXIT_SUCCESS);
410         }
411
412         ret = kdbus_msg_recv_poll(conn_dummy, 100, NULL, NULL);
413         ASSERT_RETURN(ret == -ETIMEDOUT);
414
415         cookie++;
416         ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
417         ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
418
419         kdbus_msg_free(msg);
420
421         /*
422          * Try to reply with a kdbus connection handle, this should
423          * fail with -EOPNOTSUPP
424          */
425         msg_sync_reply = get_kdbus_msg_with_fd(conn_src,
426                                                conn_dst->id,
427                                                cookie, conn_dst->fd);
428         ASSERT_RETURN(msg_sync_reply);
429
430         msg_sync_reply->cookie_reply = cookie;
431
432         memset(&cmd, 0, sizeof(cmd));
433         cmd.size = sizeof(cmd);
434         cmd.msg_address = (uintptr_t)msg_sync_reply;
435
436         ret = kdbus_cmd_send(conn_src->fd, &cmd);
437         ASSERT_RETURN(ret == -EOPNOTSUPP);
438
439         free(msg_sync_reply);
440
441         /*
442          * Try to reply with a normal fd, this should fail even
443          * if the response is a sync reply
444          *
445          * From the sender view we fail with -ECOMM
446          */
447         msg_sync_reply = get_kdbus_msg_with_fd(conn_src,
448                                                conn_dst->id,
449                                                cookie, fds[0]);
450         ASSERT_RETURN(msg_sync_reply);
451
452         msg_sync_reply->cookie_reply = cookie;
453
454         memset(&cmd, 0, sizeof(cmd));
455         cmd.size = sizeof(cmd);
456         cmd.msg_address = (uintptr_t)msg_sync_reply;
457
458         ret = kdbus_cmd_send(conn_src->fd, &cmd);
459         ASSERT_RETURN(ret == -ECOMM);
460
461         free(msg_sync_reply);
462
463         /*
464          * Resend another normal message and check if the queue
465          * is clear
466          */
467         cookie++;
468         ret = kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0,
469                              conn_dst->id, 0, NULL);
470         ASSERT_RETURN(ret == 0);
471
472         ret = waitpid(pid, &status, 0);
473         ASSERT_RETURN_VAL(ret >= 0, ret);
474
475         kdbus_conn_free(conn_dummy);
476         kdbus_conn_free(conn_dst);
477         kdbus_conn_free(conn_src);
478
479         return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
480 }
481
482 static int kdbus_send_multiple_fds(struct kdbus_conn *conn_src,
483                                    struct kdbus_conn *conn_dst)
484 {
485         int ret, i;
486         unsigned int nfds;
487         int fds[KDBUS_CONN_MAX_FDS_PER_USER + 1];
488         int memfds[KDBUS_MSG_MAX_ITEMS + 1];
489         struct kdbus_msg *msg;
490         uint64_t dummy_value;
491
492         dummy_value = time(NULL);
493
494         for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) {
495                 fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC);
496                 ASSERT_RETURN_VAL(fds[i] >= 0, -errno);
497         }
498
499         /* Send KDBUS_CONN_MAX_FDS_PER_USER with one more fd */
500         ret = send_fds(conn_src, conn_dst->id, fds,
501                        KDBUS_CONN_MAX_FDS_PER_USER + 1);
502         ASSERT_RETURN(ret == -EMFILE);
503
504         /* Retry with the correct KDBUS_CONN_MAX_FDS_PER_USER */
505         ret = send_fds(conn_src, conn_dst->id, fds,
506                        KDBUS_CONN_MAX_FDS_PER_USER);
507         ASSERT_RETURN(ret == 0);
508
509         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
510         ASSERT_RETURN(ret == 0);
511
512         /* Check we got the right number of fds */
513         nfds = kdbus_item_get_nfds(msg);
514         ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER);
515
516         kdbus_msg_free(msg);
517
518         for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++, dummy_value++) {
519                 memfds[i] = memfd_write("memfd-name",
520                                         &dummy_value,
521                                         sizeof(dummy_value));
522                 ASSERT_RETURN_VAL(memfds[i] >= 0, memfds[i]);
523         }
524
525         /* Send KDBUS_MSG_MAX_ITEMS with one more memfd */
526         ret = send_memfds(conn_src, conn_dst->id,
527                           memfds, KDBUS_MSG_MAX_ITEMS + 1);
528         ASSERT_RETURN(ret == -E2BIG);
529
530         ret = send_memfds(conn_src, conn_dst->id,
531                           memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1);
532         ASSERT_RETURN(ret == -E2BIG);
533
534         /* Retry with the correct KDBUS_MSG_MAX_ITEMS */
535         ret = send_memfds(conn_src, conn_dst->id,
536                           memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
537         ASSERT_RETURN(ret == 0);
538
539         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
540         ASSERT_RETURN(ret == 0);
541
542         /* Check we got the right number of fds */
543         nfds = kdbus_item_get_nfds(msg);
544         ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS);
545
546         kdbus_msg_free(msg);
547
548
549         /*
550          * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER+1 fds and
551          * 10 memfds
552          */
553         ret = send_fds_memfds(conn_src, conn_dst->id,
554                               fds, KDBUS_CONN_MAX_FDS_PER_USER + 1,
555                               memfds, 10);
556         ASSERT_RETURN(ret == -EMFILE);
557
558         ret = kdbus_msg_recv(conn_dst, NULL, NULL);
559         ASSERT_RETURN(ret == -EAGAIN);
560
561         /*
562          * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER fds and
563          * (128 - 1) + 1 memfds, all fds take one item, while each
564          * memfd takes one item
565          */
566         ret = send_fds_memfds(conn_src, conn_dst->id,
567                               fds, KDBUS_CONN_MAX_FDS_PER_USER,
568                               memfds, (KDBUS_MSG_MAX_ITEMS - 1) + 1);
569         ASSERT_RETURN(ret == -E2BIG);
570
571         ret = send_fds_memfds(conn_src, conn_dst->id,
572                               fds, KDBUS_CONN_MAX_FDS_PER_USER,
573                               memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1);
574         ASSERT_RETURN(ret == -E2BIG);
575
576         ret = kdbus_msg_recv(conn_dst, NULL, NULL);
577         ASSERT_RETURN(ret == -EAGAIN);
578
579         /*
580          * Send KDBUS_CONN_MAX_FDS_PER_USER fds +
581          * KDBUS_MSG_MAX_MEMFD_ITEMS memfds
582          */
583         ret = send_fds_memfds(conn_src, conn_dst->id,
584                               fds, KDBUS_CONN_MAX_FDS_PER_USER,
585                               memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
586         ASSERT_RETURN(ret == 0);
587
588         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
589         ASSERT_RETURN(ret == 0);
590
591         /* Check we got the right number of fds */
592         nfds = kdbus_item_get_nfds(msg);
593         ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER +
594                               KDBUS_MSG_MAX_MEMFD_ITEMS);
595
596         kdbus_msg_free(msg);
597
598
599         /*
600          * Re-send fds + memfds, close them, but do not receive them
601          * and try to queue more
602          */
603         ret = send_fds_memfds(conn_src, conn_dst->id,
604                               fds, KDBUS_CONN_MAX_FDS_PER_USER,
605                               memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
606         ASSERT_RETURN(ret == 0);
607
608         /* close old references and get a new ones */
609         for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) {
610                 close(fds[i]);
611                 fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC);
612                 ASSERT_RETURN_VAL(fds[i] >= 0, -errno);
613         }
614
615         /* should fail since we have already fds in the queue */
616         ret = send_fds(conn_src, conn_dst->id, fds,
617                        KDBUS_CONN_MAX_FDS_PER_USER);
618         ASSERT_RETURN(ret == -EMFILE);
619
620         /* This should succeed */
621         ret = send_memfds(conn_src, conn_dst->id,
622                           memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
623         ASSERT_RETURN(ret == 0);
624
625         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
626         ASSERT_RETURN(ret == 0);
627
628         nfds = kdbus_item_get_nfds(msg);
629         ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER +
630                               KDBUS_MSG_MAX_MEMFD_ITEMS);
631
632         kdbus_msg_free(msg);
633
634         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
635         ASSERT_RETURN(ret == 0);
636
637         nfds = kdbus_item_get_nfds(msg);
638         ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS);
639
640         kdbus_msg_free(msg);
641
642         ret = kdbus_msg_recv(conn_dst, NULL, NULL);
643         ASSERT_RETURN(ret == -EAGAIN);
644
645         for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++)
646                 close(fds[i]);
647
648         for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++)
649                 close(memfds[i]);
650
651         return 0;
652 }
653
654 int kdbus_test_fd_passing(struct kdbus_test_env *env)
655 {
656         struct kdbus_conn *conn_src, *conn_dst;
657         const char *str = "stackenblocken";
658         const struct kdbus_item *item;
659         struct kdbus_msg *msg;
660         unsigned int i;
661         uint64_t now;
662         int fds_conn[2];
663         int sock_pair[2];
664         int fds[2];
665         int memfd;
666         int ret;
667
668         now = (uint64_t) time(NULL);
669
670         /* create two connections */
671         conn_src = kdbus_hello(env->buspath, 0, NULL, 0);
672         conn_dst = kdbus_hello(env->buspath, 0, NULL, 0);
673         ASSERT_RETURN(conn_src && conn_dst);
674
675         fds_conn[0] = conn_src->fd;
676         fds_conn[1] = conn_dst->fd;
677
678         ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock_pair);
679         ASSERT_RETURN(ret == 0);
680
681         /* Setup memfd */
682         memfd = memfd_write("memfd-name", &now, sizeof(now));
683         ASSERT_RETURN(memfd >= 0);
684
685         /* Setup pipes */
686         ret = pipe(fds);
687         ASSERT_RETURN(ret == 0);
688
689         i = write(fds[1], str, strlen(str));
690         ASSERT_RETURN(i == strlen(str));
691
692         /*
693          * Try to ass the handle of a connection as message payload.
694          * This must fail.
695          */
696         ret = send_fds(conn_src, conn_dst->id, fds_conn, 2);
697         ASSERT_RETURN(ret == -ENOTSUP);
698
699         ret = send_fds(conn_dst, conn_src->id, fds_conn, 2);
700         ASSERT_RETURN(ret == -ENOTSUP);
701
702         ret = send_fds(conn_src, conn_dst->id, sock_pair, 2);
703         ASSERT_RETURN(ret == -ENOTSUP);
704
705         /*
706          * Send fds and memfds to connection that do not accept fds
707          */
708         ret = kdbus_test_no_fds(env, fds, (int *)&memfd);
709         ASSERT_RETURN(ret == 0);
710
711         /* Try to broadcast file descriptors. This must fail. */
712         ret = send_fds(conn_src, KDBUS_DST_ID_BROADCAST, fds, 1);
713         ASSERT_RETURN(ret == -ENOTUNIQ);
714
715         /* Try to broadcast memfd. This must succeed. */
716         ret = send_memfds(conn_src, KDBUS_DST_ID_BROADCAST, (int *)&memfd, 1);
717         ASSERT_RETURN(ret == 0);
718
719         /* Open code this loop */
720 loop_send_fds:
721
722         /*
723          * Send the read end of the pipe and close it.
724          */
725         ret = send_fds(conn_src, conn_dst->id, fds, 1);
726         ASSERT_RETURN(ret == 0);
727         close(fds[0]);
728
729         ret = kdbus_msg_recv(conn_dst, &msg, NULL);
730         ASSERT_RETURN(ret == 0);
731
732         KDBUS_ITEM_FOREACH(item, msg, items) {
733                 if (item->type == KDBUS_ITEM_FDS) {
734                         char tmp[14];
735                         int nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) /
736                                         sizeof(int);
737                         ASSERT_RETURN(nfds == 1);
738
739                         i = read(item->fds[0], tmp, sizeof(tmp));
740                         if (i != 0) {
741                                 ASSERT_RETURN(i == sizeof(tmp));
742                                 ASSERT_RETURN(memcmp(tmp, str, sizeof(tmp)) == 0);
743
744                                 /* Write EOF */
745                                 close(fds[1]);
746
747                                 /*
748                                  * Resend the read end of the pipe,
749                                  * the receiver still holds a reference
750                                  * to it...
751                                  */
752                                 goto loop_send_fds;
753                         }
754
755                         /* Got EOF */
756
757                         /*
758                          * Close the last reference to the read end
759                          * of the pipe, other references are
760                          * automatically closed just after send.
761                          */
762                         close(item->fds[0]);
763                 }
764         }
765
766         /*
767          * Try to resend the read end of the pipe. Must fail with
768          * -EBADF since both the sender and receiver closed their
769          * references to it. We assume the above since sender and
770          * receiver are on the same process.
771          */
772         ret = send_fds(conn_src, conn_dst->id, fds, 1);
773         ASSERT_RETURN(ret == -EBADF);
774
775         /* Then we clear out received any data... */
776         kdbus_msg_free(msg);
777
778         ret = kdbus_send_multiple_fds(conn_src, conn_dst);
779         ASSERT_RETURN(ret == 0);
780
781         close(sock_pair[0]);
782         close(sock_pair[1]);
783         close(memfd);
784
785         kdbus_conn_free(conn_src);
786         kdbus_conn_free(conn_dst);
787
788         return TEST_OK;
789 }