usb: gadget: f_fs: Prevent panic due to failure of huge size buffer allocation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / kdbus / kdbus-test.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <time.h>
8 #include <unistd.h>
9 #include <stdint.h>
10 #include <assert.h>
11 #include <getopt.h>
12 #include <stdbool.h>
13 #include <signal.h>
14 #include <sys/mount.h>
15 #include <sys/prctl.h>
16 #include <sys/wait.h>
17 #include <sys/syscall.h>
18 #include <sys/eventfd.h>
19 #include <linux/sched.h>
20
21 #include "kdbus-util.h"
22 #include "kdbus-enum.h"
23 #include "kdbus-test.h"
24
25 enum {
26         TEST_CREATE_BUS         = 1 << 0,
27         TEST_CREATE_CONN        = 1 << 1,
28 };
29
30 struct kdbus_test {
31         const char *name;
32         const char *desc;
33         int (*func)(struct kdbus_test_env *env);
34         unsigned int flags;
35         unsigned timeout;
36 };
37
38 struct kdbus_test_args {
39         bool mntns;
40         bool pidns;
41         bool userns;
42         bool no_timeout;
43         char *uid_map;
44         char *gid_map;
45         int loop;
46         int wait;
47         int fork;
48         int tap_output;
49         unsigned nTests;
50         char const * const *tests;
51         char *module;
52         char *root;
53         char *busname;
54 };
55
56 pthread_mutex_t global_print_lock = PTHREAD_MUTEX_INITIALIZER;
57
58 static const struct kdbus_test tests[] = {
59         {
60                 .name   = "bus-make",
61                 .desc   = "bus make functions",
62                 .func   = kdbus_test_bus_make,
63                 .flags  = 0,
64                 .timeout = 10,
65         },
66         {
67                 .name   = "hello",
68                 .desc   = "the HELLO command",
69                 .func   = kdbus_test_hello,
70                 .flags  = TEST_CREATE_BUS,
71                 .timeout = 10,
72         },
73         {
74                 .name   = "byebye",
75                 .desc   = "the BYEBYE command",
76                 .func   = kdbus_test_byebye,
77                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
78                 .timeout = 10,
79         },
80         {
81                 .name   = "chat",
82                 .desc   = "a chat pattern",
83                 .func   = kdbus_test_chat,
84                 .flags  = TEST_CREATE_BUS,
85                 .timeout = 10,
86         },
87         {
88                 .name   = "daemon",
89                 .desc   = "a simple daemon",
90                 .func   = kdbus_test_daemon,
91                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
92                 .timeout = 10,
93         },
94         {
95                 .name   = "fd-passing",
96                 .desc   = "file descriptor passing",
97                 .func   = kdbus_test_fd_passing,
98                 .flags  = TEST_CREATE_BUS,
99                 .timeout = 10,
100         },
101         {
102                 .name   = "endpoint",
103                 .desc   = "custom endpoint",
104                 .func   = kdbus_test_custom_endpoint,
105                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
106                 .timeout = 10,
107         },
108         {
109                 .name   = "monitor",
110                 .desc   = "monitor functionality",
111                 .func   = kdbus_test_monitor,
112                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
113                 .timeout = 10,
114         },
115         {
116                 .name   = "name-basics",
117                 .desc   = "basic name registry functions",
118                 .func   = kdbus_test_name_basic,
119                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
120                 .timeout = 10,
121         },
122         {
123                 .name   = "name-conflict",
124                 .desc   = "name registry conflict details",
125                 .func   = kdbus_test_name_conflict,
126                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
127                 .timeout = 10,
128         },
129         {
130                 .name   = "name-queue",
131                 .desc   = "queuing of names",
132                 .func   = kdbus_test_name_queue,
133                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
134                 .timeout = 10,
135         },
136         {
137                 .name   = "name-takeover",
138                 .desc   = "takeover of names",
139                 .func   = kdbus_test_name_takeover,
140                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
141                 .timeout = 10,
142         },
143         {
144                 .name   = "message-basic",
145                 .desc   = "basic message handling",
146                 .func   = kdbus_test_message_basic,
147                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
148                 .timeout = 10,
149         },
150         {
151                 .name   = "message-prio",
152                 .desc   = "handling of messages with priority",
153                 .func   = kdbus_test_message_prio,
154                 .flags  = TEST_CREATE_BUS,
155                 .timeout = 10,
156         },
157         {
158                 .name   = "activator-quota",
159                 .desc   = "activator message quotas are enforced",
160                 .func   = kdbus_test_activator_quota,
161                 .flags  = TEST_CREATE_BUS,
162                 .timeout = 20,
163         },
164         {
165                 .name   = "message-quota",
166                 .desc   = "message quotas are enforced",
167                 .func   = kdbus_test_message_quota,
168                 .flags  = TEST_CREATE_BUS,
169                 .timeout = 20,
170         },
171         {
172                 .name   = "memory-access",
173                 .desc   = "memory access",
174                 .func   = kdbus_test_memory_access,
175                 .flags  = TEST_CREATE_BUS,
176                 .timeout = 10,
177         },
178         {
179                 .name   = "timeout",
180                 .desc   = "timeout",
181                 .func   = kdbus_test_timeout,
182                 .flags  = TEST_CREATE_BUS,
183                 .timeout = 10,
184         },
185         {
186                 .name   = "sync-byebye",
187                 .desc   = "synchronous replies vs. BYEBYE",
188                 .func   = kdbus_test_sync_byebye,
189                 .flags  = TEST_CREATE_BUS,
190                 .timeout = 10,
191         },
192         {
193                 .name   = "sync-reply",
194                 .desc   = "synchronous replies",
195                 .func   = kdbus_test_sync_reply,
196                 .flags  = TEST_CREATE_BUS,
197                 .timeout = 10,
198         },
199         {
200                 .name   = "big-meta",
201                 .desc   = "big metadata",
202                 .func   = kdbus_test_big_metadata,
203                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
204                 .timeout = 10,
205         },
206         {
207                 .name   = "message-free",
208                 .desc   = "freeing of memory",
209                 .func   = kdbus_test_free,
210                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
211                 .timeout = 10,
212         },
213         {
214                 .name   = "connection-info",
215                 .desc   = "retrieving connection information",
216                 .func   = kdbus_test_conn_info,
217                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
218                 .timeout = 10,
219         },
220         {
221                 .name   = "connection-update",
222                 .desc   = "updating connection information",
223                 .func   = kdbus_test_conn_update,
224                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
225                 .timeout = 10,
226         },
227         {
228                 .name   = "writable-pool",
229                 .desc   = "verifying pools are never writable",
230                 .func   = kdbus_test_writable_pool,
231                 .flags  = TEST_CREATE_BUS,
232                 .timeout = 10,
233         },
234         {
235                 .name   = "policy",
236                 .desc   = "policy",
237                 .func   = kdbus_test_policy,
238                 .flags  = TEST_CREATE_BUS,
239                 .timeout = 10,
240         },
241         {
242                 .name   = "policy-priv",
243                 .desc   = "unprivileged bus access",
244                 .func   = kdbus_test_policy_priv,
245                 .flags  = TEST_CREATE_BUS,
246                 .timeout = 10,
247         },
248         {
249                 .name   = "policy-ns",
250                 .desc   = "policy in user namespaces",
251                 .func   = kdbus_test_policy_ns,
252                 .flags  = TEST_CREATE_BUS,
253                 .timeout = 10,
254         },
255         {
256                 .name   = "metadata",
257                 .desc   = "metadata",
258                 .func   = kdbus_test_metadata,
259                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
260                 .timeout = 10,
261         },
262         {
263                 .name   = "metadata-conn-info",
264                 .desc   = "metadata in connection-info",
265                 .func   = kdbus_test_metadata_conn_info,
266                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
267                 .timeout = 10,
268         },
269         {
270                 .name   = "metadata-ns",
271                 .desc   = "metadata in different namespaces",
272                 .func   = kdbus_test_metadata_ns,
273                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
274                 .timeout = 10,
275         },
276         {
277                 .name   = "match-id-add",
278                 .desc   = "adding of matches by id",
279                 .func   = kdbus_test_match_id_add,
280                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
281                 .timeout = 10,
282         },
283         {
284                 .name   = "match-id-remove",
285                 .desc   = "removing of matches by id",
286                 .func   = kdbus_test_match_id_remove,
287                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
288                 .timeout = 10,
289         },
290         {
291                 .name   = "match-replace",
292                 .desc   = "replace of matches with the same cookie",
293                 .func   = kdbus_test_match_replace,
294                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
295                 .timeout = 10,
296         },
297         {
298                 .name   = "match-name-add",
299                 .desc   = "adding of matches by name",
300                 .func   = kdbus_test_match_name_add,
301                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
302                 .timeout = 10,
303         },
304         {
305                 .name   = "match-name-remove",
306                 .desc   = "removing of matches by name",
307                 .func   = kdbus_test_match_name_remove,
308                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
309                 .timeout = 10,
310         },
311         {
312                 .name   = "match-name-change",
313                 .desc   = "matching for name changes",
314                 .func   = kdbus_test_match_name_change,
315                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
316                 .timeout = 10,
317         },
318         {
319                 .name   = "match-bloom",
320                 .desc   = "matching with bloom filters",
321                 .func   = kdbus_test_match_bloom,
322                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
323                 .timeout = 10,
324         },
325         {
326                 .name   = "match-all",
327                 .desc   = "itemless catch-all matching",
328                 .func   = kdbus_test_match_itemless,
329                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
330                 .timeout = 10,
331         },
332         {
333                 .name   = "activator",
334                 .desc   = "activator connections",
335                 .func   = kdbus_test_activator,
336                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
337                 .timeout = 10,
338         },
339         {
340                 .name   = "benchmark",
341                 .desc   = "benchmark",
342                 .func   = kdbus_test_benchmark,
343                 .flags  = TEST_CREATE_BUS,
344                 .timeout = 10,
345         },
346         {
347                 .name   = "benchmark-nomemfds",
348                 .desc   = "benchmark without using memfds",
349                 .func   = kdbus_test_benchmark_nomemfds,
350                 .flags  = TEST_CREATE_BUS,
351                 .timeout = 10,
352         },
353         {
354                 .name   = "benchmark-uds",
355                 .desc   = "benchmark comparison to UDS",
356                 .func   = kdbus_test_benchmark_uds,
357                 .flags  = TEST_CREATE_BUS,
358                 .timeout = 10,
359         },
360 };
361
362 #define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0])))
363
364 static wur int test_prepare_env(const struct kdbus_test *t,
365                             const struct kdbus_test_args *args,
366                             struct kdbus_test_env *env)
367 {
368         if (t->flags & TEST_CREATE_BUS) {
369                 char *s;
370                 char *n = NULL;
371                 int ret;
372
373                 if (0 >= asprintf(&s, "%s/control", args->root))
374                         fail("asprintf");
375
376                 env->control_fd = open(s, O_RDWR);
377                 free(s);
378                 ASSERT_RETURN(env->control_fd,>=,0);
379
380                 if (!args->busname)
381                         ASSERT_NONZERO(n = unique_name("test-bus"));
382
383                 ret = kdbus_create_bus(env->control_fd,
384                                        args->busname ?: n,
385                                        _KDBUS_ATTACH_ALL, &s);
386                 free(n);
387                 ASSERT_ZERO(ret);
388
389                 if (0 >= asprintf(&env->buspath, "%s/%s/bus", args->root, s))
390                         fail("asprintf");
391                 free(s);
392         }
393
394         if (t->flags & TEST_CREATE_CONN)
395                 ASSERT_NONZERO(env->conn = kdbus_hello(env->buspath, 0, NULL, 0));
396
397         env->root = args->root;
398         env->module = args->module;
399
400         return 0;
401 }
402
403 static void test_unprepare_env(struct kdbus_test_env *env)
404 {
405         if (env->conn) {
406                 kdbus_conn_free(env->conn);
407                 env->conn = NULL;
408         }
409
410         if (env->control_fd >= 0) {
411                 CLOSE(env->control_fd);
412                 env->control_fd = -1;
413         }
414
415         if (env->buspath) {
416                 free(env->buspath);
417                 env->buspath = NULL;
418         }
419 }
420
421 static wur int test_run(const struct kdbus_test *t,
422                     const struct kdbus_test_args *kdbus_args,
423                     int wait)
424 {
425         int ret;
426         struct kdbus_test_env env = {};
427
428         ret = test_prepare_env(t, kdbus_args, &env);
429         if (ret != TEST_OK)
430                 return ret;
431
432         if (wait > 0) {
433                 print("Sleeping %d seconds before running test ...\n", wait);
434                 sleep(wait);
435         }
436
437         ret = t->func(&env);
438         test_unprepare_env(&env);
439         return ret;
440 }
441
442 static wur int test_run_forked(const struct kdbus_test *t,
443                            const struct kdbus_test_args *kdbus_args,
444                            int _wait)
445 {
446         int ret, result;
447         pid_t pid, timer_pid = 0;
448
449         pid = fork();
450         if (pid < 0) {
451                 return TEST_ERR;
452         } else if (pid == 0) {
453                 ret = test_run(t, kdbus_args, _wait);
454                 exit(ret);
455         }
456
457         if (!kdbus_args->no_timeout) {
458                 timer_pid = fork();
459                 if (timer_pid < 0) {
460                         return TEST_ERR;
461                 } else if (timer_pid == 0) {
462                         sleep(t->timeout);
463                         exit(1);
464                 }
465         }
466
467         result = -1;
468         for (;;) {
469                 pid_t wpid = wait(&ret);
470                 if (wpid <= 0)
471                         return TEST_ERR;
472                 if (result >= 0)
473                         break;
474                 result = !WIFEXITED(ret) || WEXITSTATUS(ret) ? TEST_ERR + (timer_pid==wpid) : TEST_OK;
475                 if (kdbus_args->no_timeout)
476                         break;
477                 kill(wpid ^ pid ^ timer_pid, SIGKILL);
478         }
479
480         return result;
481 }
482
483 static void print_test_result(int ret)
484 {
485         switch (ret) {
486         case TEST_OK:
487                 print("OK");
488                 break;
489         case TEST_SKIP:
490                 print("SKIPPED");
491                 break;
492         case TEST_ERR:
493                 print("ERROR");
494                 break;
495         }
496 }
497
498 static void print_res(struct kdbus_test const *t, int ret) {
499         printf("%s;%s\n", t->name, !ret ? "PASS" : TEST_TIME==ret ? "FAIL;TIMEOUT" : "FAIL");
500 }
501
502 static wur int start_all_tests(struct kdbus_test_args const *kdbus_args)
503 {
504         int ret;
505         unsigned int fail_cnt = 0;
506         unsigned int skip_cnt = 0;
507         unsigned int ok_cnt = 0;
508         unsigned int i;
509
510         if (kdbus_args->tap_output) {
511                 print("1..%d\n", N_TESTS);
512                 fflush(stdout);
513         }
514
515         kdbus_util_verbose = false;
516
517         for (i = 0; i < N_TESTS; i++) {
518                 const struct kdbus_test *t = tests + i;
519
520                 if (!kdbus_args->tap_output) {
521                         unsigned int n;
522
523                         print("Testing %s (%s) ", t->desc, t->name);
524                         for (n = 0; n < 60 - strlen(t->desc) - strlen(t->name); n++)
525                                 print(".");
526                         print(" ");
527                 }
528
529                 ret = test_run_forked(t, kdbus_args, 0);
530                 switch (ret) {
531                 case TEST_OK:
532                         ok_cnt++;
533                         break;
534                 case TEST_SKIP:
535                         skip_cnt++;
536                         break;
537                 case TEST_ERR:
538                 case TEST_TIME:
539                         fail_cnt++;
540                         break;
541                 }
542
543                 if (kdbus_args->tap_output) {
544                         print("%sok %d - %s%s (%s)\n",
545                                (ret >= TEST_ERR) ? "not " : "", i + 1,
546                                (ret == TEST_SKIP) ? "# SKIP " : "",
547                                t->desc, t->name);
548                         fflush(stdout);
549                 } else {
550                         print_test_result(ret);
551                         print_res(t, ret);
552                         print("\n");
553                 }
554         }
555
556         if (kdbus_args->tap_output)
557                 print("Failed %d/%d tests, %.2f%% okay\n", fail_cnt, N_TESTS,
558                        100.0 - (fail_cnt * 100.0) / ((float) N_TESTS));
559         else
560                 print("\nSUMMARY: %u tests passed, %u skipped, %u failed\n",
561                        ok_cnt, skip_cnt, fail_cnt);
562
563         return fail_cnt > 0 ? TEST_ERR : TEST_OK;
564 }
565
566 static wur int start_some_tests(struct kdbus_test_args const *kdbus_args)
567 {
568         int i, ret = TEST_ERR;
569         bool test_found = false;
570         unsigned j=0, nTests = kdbus_args->nTests;
571
572         do {
573                 char const *tName = kdbus_args->tests[j];
574                 for (i = 0; i < N_TESTS; i++) {
575                         const struct kdbus_test *t = tests + i;
576
577                         if (strcmp(t->name, tName))
578                                 continue;
579
580                         do {
581                                 test_found = true;
582                                 if (kdbus_args->fork)
583                                         ret = test_run_forked(t, kdbus_args,
584                                                                   kdbus_args->wait);
585                                 else
586                                         ret = test_run(t, kdbus_args,
587                                                            kdbus_args->wait);
588
589                                 print("Testing %s: ", t->desc);
590                                 print_test_result(ret);
591                                 print_res(t, ret);
592                                 print("\n");
593
594                                 if (ret != TEST_OK)
595                                         break;
596                         } while (kdbus_args->loop);
597                 }
598
599                 if (!test_found) {
600                         print("%s;UNKNOWN\n", tName);
601                 }
602         } while (++j < nTests);
603
604         return ret;
605 }
606
607 static void usage(const char *argv0)
608 {
609         unsigned int i, j;
610
611         print("Usage: %s [options]\n"
612                "Options:\n"
613                "\t-a, --tap             Output test results in TAP format\n"
614                "\t-m, --module <module> Kdbus module name\n"
615                "\t-x, --loop            Run in a loop\n"
616                "\t-f, --fork            Fork before running a test\n"
617                "\t-h, --help            Print this help\n"
618                "\t-R, --root <root>     Toplevel of the kdbus hierarchy\n"
619                "\t-t, --test <test-id>  Run one specific test only, in verbose mode\n"
620                "\t-b, --bus <busname>   Instead of generating a random bus name, take <busname>.\n"
621                "\t-w, --wait <secs>     Wait <secs> before actually starting test\n"
622                "\t    --mntns           New mount namespace\n"
623                "\t    --pidns           New PID namespace\n"
624                "\t    --userns          New user namespace\n"
625                "\t    --uidmap uid_map  UID map for user namespace\n"
626                "\t    --gidmap gid_map  GID map for user namespace\n"
627                "\n", argv0);
628
629         print("By default, all test are run once, and a summary is printed.\n"
630                "Available tests for --test:\n\n");
631
632         for (i = 0; i < N_TESTS; i++) {
633                 const struct kdbus_test *t = tests + i;
634
635                 print("\t%s", t->name);
636
637                 for (j = 0; j < 24 - strlen(t->name); j++)
638                         print(" ");
639
640                 print("Test %s\n", t->desc);
641         }
642
643         print("\n");
644         print("Note that some tests may, if run specifically by --test, "
645                "behave differently, and not terminate by themselves.\n");
646
647         exit(EXIT_FAILURE);
648 }
649
650 void print_kdbus_test_args(struct kdbus_test_args const *args)
651 {
652         if (args->userns || args->pidns || args->mntns)
653                 print("# Starting tests in new %s%s%s namespaces%s\n",
654                         args->mntns ? "MOUNT " : "",
655                         args->pidns ? "PID " : "",
656                         args->userns ? "USER " : "",
657                         args->mntns ? ", kdbusfs will be remounted" : "");
658         else
659                 print("# Starting tests in the same namespaces\n");
660 }
661
662 void print_metadata_support(void)
663 {
664         bool no_meta_audit, no_meta_cgroups, no_meta_seclabel;
665
666         /*
667          * KDBUS_ATTACH_CGROUP, KDBUS_ATTACH_AUDIT and
668          * KDBUS_ATTACH_SECLABEL
669          */
670         no_meta_audit = !config_auditsyscall_is_enabled();
671         no_meta_cgroups = !config_cgroups_is_enabled();
672         no_meta_seclabel = !config_security_is_enabled();
673
674         if (no_meta_audit | no_meta_cgroups | no_meta_seclabel)
675                 print("# Starting tests without %s%s%s metadata support\n",
676                        no_meta_audit ? "AUDIT " : "",
677                        no_meta_cgroups ? "CGROUP " : "",
678                        no_meta_seclabel ? "SECLABEL " : "");
679         else
680                 print("# Starting tests with full metadata support\n");
681 }
682
683 wur int run_tests(struct kdbus_test_args const *kdbus_args)
684 {
685         int ret;
686         static char control[4096];
687
688         snprintf(control, sizeof(control), "%s/control", kdbus_args->root);
689
690         if (access(control, W_OK) < 0) {
691                 print("Unable to locate control node at '%s'.\n",
692                         control);
693                 return TEST_ERR;
694         }
695
696         if (kdbus_args->nTests) {
697                 ret = start_some_tests(kdbus_args);
698         } else {
699                 do {
700                         ret = start_all_tests(kdbus_args);
701                         if (ret != TEST_OK)
702                                 break;
703                 } while (kdbus_args->loop);
704         }
705
706         return ret;
707 }
708
709 static void nop_handler(int sig) { UNUSED(sig); }
710
711 static wur int test_prepare_mounts(struct kdbus_test_args const *kdbus_args)
712 {
713         int ret;
714         char kdbusfs[64] = {'\0'};
715
716         snprintf(kdbusfs, sizeof(kdbusfs), "%sfs", kdbus_args->module);
717
718         /* make current mount slave */
719         ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
720         if (ret < 0) {
721                 ret = -errno;
722                 print("error mount() root: %d (%m)\n", ret);
723                 return ret;
724         }
725
726         /* Remount procfs since we need it in our tests */
727         if (kdbus_args->pidns) {
728                 ret = mount("proc", "/proc", "proc",
729                             MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
730                 if (ret < 0) {
731                         ret = -errno;
732                         print("error mount() /proc : %d (%m)\n", ret);
733                         return ret;
734                 }
735         }
736
737         /* Remount kdbusfs */
738         ret = mount(kdbusfs, kdbus_args->root, kdbusfs,
739                     MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
740         if (ret < 0) {
741                 ret = -errno;
742                 print("error mount() %s :%d (%m)\n", kdbusfs, ret);
743                 return ret;
744         }
745
746         return 0;
747 }
748
749 wur int run_tests_in_namespaces(struct kdbus_test_args const *kdbus_args)
750 {
751         int ret;
752         int efd = -1;
753         int status;
754         pid_t pid, rpid;
755         struct sigaction oldsa;
756         struct sigaction sa = {
757                 .sa_handler = nop_handler,
758                 .sa_flags = SA_NOCLDSTOP,
759         };
760
761         efd = eventfd(0, EFD_CLOEXEC);
762         if (efd < 0) {
763                 ret = -errno;
764                 print("eventfd() failed: %d (%m)\n", ret);
765                 return TEST_ERR;
766         }
767
768         ret = sigaction(SIGCHLD, &sa, &oldsa);
769         if (ret < 0) {
770                 ret = -errno;
771                 print("sigaction() failed: %d (%m)\n", ret);
772                 return TEST_ERR;
773         }
774
775         /* setup namespaces */
776         pid = syscall(__NR_clone, SIGCHLD|
777                       (kdbus_args->userns ? CLONE_NEWUSER : 0) |
778                       (kdbus_args->mntns ? CLONE_NEWNS : 0) |
779                       (kdbus_args->pidns ? CLONE_NEWPID : 0), NULL);
780         if (pid < 0) {
781                 print("clone() failed: %d (%m)\n", -errno);
782                 return TEST_ERR;
783         }
784
785         if (pid == 0) {
786                 eventfd_t event_status = 0;
787
788                 ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
789                 if (ret < 0) {
790                         ret = -errno;
791                         print("error prctl(): %d (%m)\n", ret);
792                         exit(TEST_ERR);
793                 }
794
795                 /* reset sighandlers of childs */
796                 ret = sigaction(SIGCHLD, &oldsa, NULL);
797                 if (ret < 0) {
798                         ret = -errno;
799                         print("sigaction() failed: %d (%m)\n", ret);
800                         exit(TEST_ERR);
801                 }
802
803                 ret = eventfd_read(efd, &event_status);
804                 if (ret < 0 || event_status != 1) {
805                         print("error eventfd_read()\n");
806                         exit(TEST_ERR);
807                 }
808
809                 if (kdbus_args->mntns) {
810                         ret = test_prepare_mounts(kdbus_args);
811                         if (ret < 0) {
812                                 print("error preparing mounts\n");
813                                 exit(TEST_ERR);
814                         }
815                 }
816
817                 ret = run_tests(kdbus_args);
818                 exit(ret);
819         }
820
821         /* Setup userns mapping */
822         if (kdbus_args->userns) {
823                 ret = userns_map_uid_gid(pid, kdbus_args->uid_map,
824                                          kdbus_args->gid_map);
825                 if (ret < 0) {
826                         print("error mapping uid and gid in userns\n");
827                         eventfd_write(efd, 2);
828                         return TEST_ERR;
829                 }
830         }
831
832         ret = eventfd_write(efd, 1);
833         if (ret < 0) {
834                 ret = -errno;
835                 print("error eventfd_write(): %d (%m)\n", ret);
836                 return TEST_ERR;
837         }
838
839         rpid = waitpid(pid, &status, 0);
840         ASSERT_RETURN_VAL(rpid,==,pid, TEST_ERR);
841
842         CLOSE(efd);
843
844         if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
845                 return TEST_ERR;
846
847         return TEST_OK;
848 }
849
850 wur int start_tests(struct kdbus_test_args const *kdbus_args)
851 {
852         int ret;
853         bool namespaces;
854
855         namespaces = (kdbus_args->mntns || kdbus_args->pidns ||
856                       kdbus_args->userns);
857
858         /* for pidns we need mntns set */
859         if (kdbus_args->pidns && !kdbus_args->mntns) {
860                 print("Failed: please set both pid and mnt namesapces\n");
861                 return TEST_ERR;
862         }
863
864         if (kdbus_args->userns) {
865                 if (!config_user_ns_is_enabled()) {
866                         print("User namespace not supported\n");
867                         return TEST_ERR;
868                 }
869
870                 if (!kdbus_args->uid_map || !kdbus_args->gid_map) {
871                         print("Failed: please specify uid or gid mapping\n");
872                         return TEST_ERR;
873                 }
874         }
875
876         print_kdbus_test_args(kdbus_args);
877         print_metadata_support();
878
879         /* Start tests */
880         if (namespaces)
881                 ret = run_tests_in_namespaces(kdbus_args);
882         else
883                 ret = run_tests(kdbus_args);
884
885         return ret;
886 }
887
888 wur int main(int argc, char *argv[])
889 {
890         int t, ret = 0;
891         struct kdbus_test_args kdbus_args;
892         static char fspath[4096];
893         enum {
894                 ARG_MNTNS = 0x100,
895                 ARG_PIDNS,
896                 ARG_USERNS,
897                 ARG_UIDMAP,
898                 ARG_GIDMAP,
899         };
900
901         memset(&kdbus_args, 0, sizeof(kdbus_args));
902         kdbus_args.module = "kdbus";
903
904         static const struct option options[] = {
905                 { "loop",       no_argument,            NULL, 'x' },
906                 { "help",       no_argument,            NULL, 'h' },
907                 { "root",       required_argument,      NULL, 'R' },
908                 { "test",       no_argument,            NULL, 't' },
909                 { "bus",        required_argument,      NULL, 'b' },
910                 { "wait",       required_argument,      NULL, 'w' },
911                 { "fork",       no_argument,            NULL, 'f' },
912                 { "list",       no_argument,            NULL, 'l' },
913                 { "module",     required_argument,      NULL, 'm' },
914                 { "tap",        no_argument,            NULL, 'a' },
915                 { "notimeout",  no_argument,    NULL, 'n' },
916                 { "mntns",      no_argument,            NULL, ARG_MNTNS },
917                 { "pidns",      no_argument,            NULL, ARG_PIDNS },
918                 { "userns",     no_argument,            NULL, ARG_USERNS },
919                 { "uidmap",     required_argument,      NULL, ARG_UIDMAP },
920                 { "gidmap",     required_argument,      NULL, ARG_GIDMAP },
921                 {}
922         };
923
924         srand(time(NULL));
925
926         bool gotT = 0;
927
928         while ((t = getopt_long(argc, argv, "xhtflnm:R:b:w:a:", options, NULL)) >= 0) {
929                 switch (t) {
930                 case 'x':
931                         kdbus_args.loop = 1;
932                         break;
933
934                 case 'm':
935                         kdbus_args.module = optarg;
936                         break;
937
938                 case 'R':
939                         kdbus_args.root = optarg;
940                         break;
941
942                 case 't':
943                         gotT = 1;
944                         break;
945
946                 case 'b':
947                         kdbus_args.busname = optarg;
948                         break;
949
950                 case 'w':
951                         kdbus_args.wait = strtol(optarg, NULL, 10);
952                         break;
953
954                 case 'f':
955                         kdbus_args.fork = 1;
956                         break;
957
958                 case 'a':
959                         kdbus_args.tap_output = 1;
960                         break;
961
962                 case 'n':
963                         kdbus_args.no_timeout = 1;
964                         break;
965
966                 case 'l':
967                         {
968                                 unsigned i = 0;
969                                 do {
970                                         const struct kdbus_test *t = &tests[i];
971                                         printf("%s;%s\n", t->name, t->desc);
972                                 } while (++i < TABSIZE(tests)-1);
973                         }
974                         return 0;
975
976                 case ARG_MNTNS:
977                         kdbus_args.mntns = true;
978                         break;
979
980                 case ARG_PIDNS:
981                         kdbus_args.pidns = true;
982                         break;
983
984                 case ARG_USERNS:
985                         kdbus_args.userns = true;
986                         break;
987
988                 case ARG_UIDMAP:
989                         kdbus_args.uid_map = optarg;
990                         break;
991
992                 case ARG_GIDMAP:
993                         kdbus_args.gid_map = optarg;
994                         break;
995
996                 case 'h':
997                         usage(argv[0]);
998
999                 default:;
1000                 }
1001         }
1002
1003         if ((kdbus_args.nTests = argc-optind)) {
1004                 kdbus_args.tests = (char const * const *)&argv[optind];
1005                 if (1 < kdbus_args.nTests || !gotT)
1006                         kdbus_args.fork = 1;
1007         }
1008
1009         if (!kdbus_args.root) {
1010                 snprintf(fspath, sizeof(fspath), "/sys/fs/%s",
1011                          kdbus_args.module);
1012                 kdbus_args.root = fspath;
1013         }
1014
1015         ret = start_tests(&kdbus_args);
1016         if (ret == TEST_ERR)
1017                 return EXIT_FAILURE;
1018
1019         return 0;
1020 }