11 #include <sys/capability.h>
14 #include <sys/types.h>
15 #include <linux/unistd.h>
17 #include "kdbus-api.h"
18 #include "kdbus-test.h"
19 #include "kdbus-util.h"
20 #include "kdbus-enum.h"
23 * Should be the sum of the currently supported and compiled-in
24 * KDBUS_ITEMS_* that reflect KDBUS_ATTACH_* flags.
26 static unsigned int KDBUS_TEST_ITEMS_SUM = KDBUS_ATTACH_ITEMS_TYPE_SUM;
28 static struct kdbus_conn *__kdbus_hello(const char *path, uint64_t flags,
29 uint64_t attach_flags_send,
30 uint64_t attach_flags_recv)
32 struct kdbus_cmd_free cmd_free = {};
34 struct kdbus_conn *conn;
36 struct kdbus_cmd_hello hello;
44 uint8_t extra_items[0];
47 memset(&h, 0, sizeof(h));
49 kdbus_printf("-- opening bus connection %s\n", path);
50 fd = open(path, O_RDWR|O_CLOEXEC);
52 kdbus_printf("--- error %d (%m)\n", fd);
56 h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD;
57 h.hello.attach_flags_send = attach_flags_send;
58 h.hello.attach_flags_recv = attach_flags_recv;
59 h.conn_name.type = KDBUS_ITEM_CONN_DESCRIPTION;
60 strcpy(h.conn_name.str, "this-is-my-name");
61 h.conn_name.size = KDBUS_ITEM_HEADER_SIZE + strlen(h.conn_name.str) + 1;
63 h.hello.size = sizeof(h);
64 h.hello.pool_size = POOL_SIZE;
66 ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) &h.hello);
68 kdbus_printf("--- error when saying hello: %d (%m)\n", ret);
72 kdbus_printf("-- New connection ID : %llu\n",
73 (unsigned long long)h.hello.id);
75 cmd_free.size = sizeof(cmd_free);
76 cmd_free.offset = h.hello.offset;
77 ret = kdbus_cmd_free(fd, &cmd_free);
81 conn = malloc(sizeof(*conn));
83 kdbus_printf("unable to malloc()!?\n");
87 conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
88 if (conn->buf == MAP_FAILED) {
92 kdbus_printf("--- error mmap: %d (%m)\n", ret);
97 conn->id = h.hello.id;
101 static int kdbus_test_peers_creation(struct kdbus_test_env *env)
108 char control_path[2048];
109 uint64_t attach_flags_mask;
110 struct kdbus_conn *conn;
112 snprintf(control_path, sizeof(control_path),
113 "%s/control", env->root);
116 * Set kdbus system-wide mask to 0, this has nothing
117 * to do with the following tests, bus and connection
118 * creation nor connection update, but we do it so we are
119 * sure that everything work as expected
122 attach_flags_mask = 0;
123 ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
125 ASSERT_RETURN(ret == 0);
129 * Create bus with a full set of ATTACH flags
132 control_fd = open(control_path, O_RDWR);
133 ASSERT_RETURN(control_fd >= 0);
135 busname = unique_name("test-peers-creation-bus");
136 ASSERT_RETURN(busname);
138 ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL,
140 ASSERT_RETURN(ret == 0);
142 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
145 * Create a connection with an empty send attach flags, or
146 * with just KDBUS_ATTACH_CREDS, this should fail
148 conn = __kdbus_hello(buspath, 0, 0, 0);
149 ASSERT_RETURN(conn == NULL);
150 ASSERT_RETURN(errno == ECONNREFUSED);
152 conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_CREDS,
154 ASSERT_RETURN(conn == NULL);
155 ASSERT_RETURN(errno == ECONNREFUSED);
157 conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
160 /* Try to cut back some send attach flags */
161 ret = kdbus_conn_update_attach_flags(conn,
165 ASSERT_RETURN(ret == -EINVAL);
167 ret = kdbus_conn_update_attach_flags(conn,
168 _KDBUS_ATTACH_ALL, 0);
169 ASSERT_RETURN(ret == 0);
171 kdbus_conn_free(conn);
177 /* Test a new bus with KDBUS_ATTACH_PIDS */
179 control_fd = open(control_path, O_RDWR);
180 ASSERT_RETURN(control_fd >= 0);
182 busname = unique_name("test-peer-flags-bus");
183 ASSERT_RETURN(busname);
185 ret = kdbus_create_bus(control_fd, busname, KDBUS_ATTACH_PIDS,
187 ASSERT_RETURN(ret == 0);
189 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
192 * Create a connection with an empty send attach flags, or
193 * all flags except KDBUS_ATTACH_PIDS
195 conn = __kdbus_hello(buspath, 0, 0, 0);
196 ASSERT_RETURN(conn == NULL);
197 ASSERT_RETURN(errno == ECONNREFUSED);
199 conn = __kdbus_hello(buspath, 0,
200 _KDBUS_ATTACH_ALL & ~KDBUS_ATTACH_PIDS,
202 ASSERT_RETURN(conn == NULL);
203 ASSERT_RETURN(errno == ECONNREFUSED);
205 /* The following should succeed */
206 conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_PIDS, 0);
208 kdbus_conn_free(conn);
210 conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
213 ret = kdbus_conn_update_attach_flags(conn,
217 ASSERT_RETURN(ret == -EINVAL);
219 ret = kdbus_conn_update_attach_flags(conn, 0,
221 ASSERT_RETURN(ret == -EINVAL);
223 /* Now we want only KDBUS_ATTACH_PIDS */
224 ret = kdbus_conn_update_attach_flags(conn,
225 KDBUS_ATTACH_PIDS, 0);
226 ASSERT_RETURN(ret == 0);
228 kdbus_conn_free(conn);
235 * Create bus with 0 as ATTACH flags, the bus does not
236 * require any attach flags
239 control_fd = open(control_path, O_RDWR);
240 ASSERT_RETURN(control_fd >= 0);
242 busname = unique_name("test-peer-flags-bus");
243 ASSERT_RETURN(busname);
245 ret = kdbus_create_bus(control_fd, busname, 0, 0, &path);
246 ASSERT_RETURN(ret == 0);
248 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
250 /* Bus is open it does not require any send attach flags */
251 conn = __kdbus_hello(buspath, 0, 0, 0);
253 kdbus_conn_free(conn);
255 conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
258 ret = kdbus_conn_update_attach_flags(conn, 0, 0);
259 ASSERT_RETURN(ret == 0);
261 ret = kdbus_conn_update_attach_flags(conn, KDBUS_ATTACH_CREDS, 0);
262 ASSERT_RETURN(ret == 0);
264 kdbus_conn_free(conn);
272 static int kdbus_test_peers_info(struct kdbus_test_env *env)
281 char control_path[2048];
282 uint64_t attach_flags_mask;
283 struct kdbus_item *item;
284 struct kdbus_info *info;
285 struct kdbus_conn *conn;
286 struct kdbus_conn *reader;
287 unsigned long long attach_count = 0;
289 snprintf(control_path, sizeof(control_path),
290 "%s/control", env->root);
292 attach_flags_mask = 0;
293 ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
295 ASSERT_RETURN(ret == 0);
297 control_fd = open(control_path, O_RDWR);
298 ASSERT_RETURN(control_fd >= 0);
300 busname = unique_name("test-peers-info-bus");
301 ASSERT_RETURN(busname);
303 ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL,
305 ASSERT_RETURN(ret == 0);
307 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
309 /* Create connections with the appropriate flags */
310 conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
313 reader = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
314 ASSERT_RETURN(reader);
316 ret = kdbus_conn_info(reader, conn->id, NULL,
317 _KDBUS_ATTACH_ALL, &offset);
318 ASSERT_RETURN(ret == 0);
320 info = (struct kdbus_info *)(reader->buf + offset);
321 ASSERT_RETURN(info->id == conn->id);
323 /* all attach flags are masked, no metadata */
324 KDBUS_ITEM_FOREACH(item, info, items)
327 ASSERT_RETURN(i == 0);
329 kdbus_free(reader, offset);
331 /* Set the mask to _KDBUS_ATTACH_ANY */
332 attach_flags_mask = _KDBUS_ATTACH_ANY;
333 ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
335 ASSERT_RETURN(ret == 0);
337 ret = kdbus_conn_info(reader, conn->id, NULL,
338 _KDBUS_ATTACH_ALL, &offset);
339 ASSERT_RETURN(ret == 0);
341 info = (struct kdbus_info *)(reader->buf + offset);
342 ASSERT_RETURN(info->id == conn->id);
345 KDBUS_ITEM_FOREACH(item, info, items)
346 attach_count += item->type;
349 * All flags have been returned except for:
350 * KDBUS_ITEM_TIMESTAMP and
351 * KDBUS_ITEM_OWNED_NAME we do not own any name.
353 ASSERT_RETURN(attach_count == (KDBUS_TEST_ITEMS_SUM -
354 KDBUS_ITEM_OWNED_NAME -
355 KDBUS_ITEM_TIMESTAMP));
357 kdbus_free(reader, offset);
359 /* Request only OWNED names */
360 ret = kdbus_conn_info(reader, conn->id, NULL,
361 KDBUS_ATTACH_NAMES, &offset);
362 ASSERT_RETURN(ret == 0);
364 info = (struct kdbus_info *)(reader->buf + offset);
365 ASSERT_RETURN(info->id == conn->id);
368 KDBUS_ITEM_FOREACH(item, info, items)
369 attach_count += item->type;
371 /* we should not get any metadata since we do not own names */
372 ASSERT_RETURN(attach_count == 0);
374 kdbus_free(reader, offset);
376 kdbus_conn_free(conn);
377 kdbus_conn_free(reader);
383 * @kdbus_mask_param: kdbus module mask parameter (system-wide)
384 * @requested_meta: The bus owner metadata that we want
385 * @expected_items: The returned KDBUS_ITEMS_* sum. Used to
386 * validate the returned metadata items
388 static int kdbus_cmp_bus_creator_metadata(struct kdbus_test_env *env,
389 struct kdbus_conn *conn,
390 uint64_t kdbus_mask_param,
391 uint64_t requested_meta,
392 unsigned long expected_items)
396 struct kdbus_info *info;
397 struct kdbus_item *item;
398 unsigned long attach_count = 0;
400 ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
402 ASSERT_RETURN(ret == 0);
404 ret = kdbus_bus_creator_info(conn, requested_meta, &offset);
405 ASSERT_RETURN(ret == 0);
407 info = (struct kdbus_info *)(conn->buf + offset);
409 KDBUS_ITEM_FOREACH(item, info, items)
410 attach_count += item->type;
412 ASSERT_RETURN(attach_count == expected_items);
414 ret = kdbus_free(conn, offset);
415 ASSERT_RETURN(ret == 0);
420 static int kdbus_test_bus_creator_info(struct kdbus_test_env *env)
427 char control_path[2048];
428 uint64_t attach_flags_mask;
429 struct kdbus_conn *conn;
430 unsigned long expected_items = 0;
432 snprintf(control_path, sizeof(control_path),
433 "%s/control", env->root);
435 control_fd = open(control_path, O_RDWR);
436 ASSERT_RETURN(control_fd >= 0);
438 busname = unique_name("test-peers-info-bus");
439 ASSERT_RETURN(busname);
442 * Now the bus allows us to see all its KDBUS_ATTACH_*
445 ret = kdbus_create_bus(control_fd, busname, 0,
446 _KDBUS_ATTACH_ALL, &path);
447 ASSERT_RETURN(ret == 0);
449 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
451 conn = __kdbus_hello(buspath, 0, 0, 0);
455 * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
457 attach_flags_mask = _KDBUS_ATTACH_ANY;
460 * All flags will be returned except for:
461 * KDBUS_ITEM_TIMESTAMP
462 * KDBUS_ITEM_OWNED_NAME
463 * KDBUS_ITEM_CONN_DESCRIPTION
465 * An extra flags is always returned KDBUS_ITEM_MAKE_NAME
466 * which contains the bus name
468 expected_items = KDBUS_TEST_ITEMS_SUM + KDBUS_ITEM_MAKE_NAME;
469 expected_items -= KDBUS_ITEM_TIMESTAMP +
470 KDBUS_ITEM_OWNED_NAME +
471 KDBUS_ITEM_CONN_DESCRIPTION;
472 ret = kdbus_cmp_bus_creator_metadata(env, conn,
476 ASSERT_RETURN(ret == 0);
480 * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME
482 expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS +
483 KDBUS_ITEM_MAKE_NAME;
484 ret = kdbus_cmp_bus_creator_metadata(env, conn,
489 ASSERT_RETURN(ret == 0);
491 /* KDBUS_ITEM_MAKE_NAME is always returned */
492 expected_items = KDBUS_ITEM_MAKE_NAME;
493 ret = kdbus_cmp_bus_creator_metadata(env, conn,
496 ASSERT_RETURN(ret == 0);
499 * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS
502 attach_flags_mask = KDBUS_ATTACH_PIDS;
506 * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME
508 expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME;
509 ret = kdbus_cmp_bus_creator_metadata(env, conn,
513 ASSERT_RETURN(ret == 0);
516 /* system-wide mask to 0 */
517 attach_flags_mask = 0;
519 /* we should only see: KDBUS_ITEM_MAKE_NAME */
520 expected_items = KDBUS_ITEM_MAKE_NAME;
521 ret = kdbus_cmp_bus_creator_metadata(env, conn,
525 ASSERT_RETURN(ret == 0);
527 kdbus_conn_free(conn);
534 * A new bus that hides all its owner metadata
537 control_fd = open(control_path, O_RDWR);
538 ASSERT_RETURN(control_fd >= 0);
540 busname = unique_name("test-peers-info-bus");
541 ASSERT_RETURN(busname);
543 ret = kdbus_create_bus(control_fd, busname, 0, 0, &path);
544 ASSERT_RETURN(ret == 0);
546 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
548 conn = __kdbus_hello(buspath, 0, 0, 0);
552 * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
554 attach_flags_mask = _KDBUS_ATTACH_ANY;
557 * We only get the KDBUS_ITEM_MAKE_NAME
559 expected_items = KDBUS_ITEM_MAKE_NAME;
560 ret = kdbus_cmp_bus_creator_metadata(env, conn,
564 ASSERT_RETURN(ret == 0);
567 * We still get only kdbus_ITEM_MAKE_NAME
569 attach_flags_mask = 0;
570 expected_items = KDBUS_ITEM_MAKE_NAME;
571 ret = kdbus_cmp_bus_creator_metadata(env, conn,
575 ASSERT_RETURN(ret == 0);
577 kdbus_conn_free(conn);
584 * A new bus that shows only the PID and CREDS metadata
587 control_fd = open(control_path, O_RDWR);
588 ASSERT_RETURN(control_fd >= 0);
590 busname = unique_name("test-peers-info-bus");
591 ASSERT_RETURN(busname);
593 ret = kdbus_create_bus(control_fd, busname, 0,
595 KDBUS_ATTACH_CREDS, &path);
596 ASSERT_RETURN(ret == 0);
598 snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
600 conn = __kdbus_hello(buspath, 0, 0, 0);
604 * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
606 attach_flags_mask = _KDBUS_ATTACH_ANY;
610 * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME
612 expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS +
613 KDBUS_ITEM_MAKE_NAME;
614 ret = kdbus_cmp_bus_creator_metadata(env, conn,
618 ASSERT_RETURN(ret == 0);
620 expected_items = KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME;
621 ret = kdbus_cmp_bus_creator_metadata(env, conn,
625 ASSERT_RETURN(ret == 0);
627 /* KDBUS_ITEM_MAKE_NAME is always returned */
628 expected_items = KDBUS_ITEM_MAKE_NAME;
629 ret = kdbus_cmp_bus_creator_metadata(env, conn,
632 ASSERT_RETURN(ret == 0);
635 * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS
638 attach_flags_mask = KDBUS_ATTACH_PIDS;
641 * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME
643 expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME;
644 ret = kdbus_cmp_bus_creator_metadata(env, conn,
648 ASSERT_RETURN(ret == 0);
650 /* No KDBUS_ATTACH_CREDS */
651 expected_items = KDBUS_ITEM_MAKE_NAME;
652 ret = kdbus_cmp_bus_creator_metadata(env, conn,
656 ASSERT_RETURN(ret == 0);
658 /* system-wide mask to 0 */
659 attach_flags_mask = 0;
661 /* we should only see: KDBUS_ITEM_MAKE_NAME */
662 expected_items = KDBUS_ITEM_MAKE_NAME;
663 ret = kdbus_cmp_bus_creator_metadata(env, conn,
667 ASSERT_RETURN(ret == 0);
670 kdbus_conn_free(conn);
678 int kdbus_test_attach_flags(struct kdbus_test_env *env)
682 uint64_t old_kdbus_flags_mask;
684 /* We need CAP_DAC_OVERRIDE to overwrite the kdbus mask */
685 ret = test_is_capable(CAP_DAC_OVERRIDE, -1);
686 ASSERT_RETURN(ret >= 0);
688 /* no enough privileges, SKIP test */
693 * We need to be able to write to
694 * "/sys/module/kdbus/parameters/attach_flags_mask"
695 * perhaps we are unprvileged/privileged in its userns
697 ret = access(env->mask_param_path, W_OK);
699 kdbus_printf("--- access() '%s' failed: %d (%m)\n",
700 env->mask_param_path, -errno);
704 ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path,
705 &old_kdbus_flags_mask);
706 ASSERT_RETURN(ret == 0);
708 /* setup the right KDBUS_TEST_ITEMS_SUM */
709 if (!config_auditsyscall_is_enabled())
710 KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_AUDIT;
712 if (!config_cgroups_is_enabled())
713 KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_CGROUP;
715 if (!config_security_is_enabled())
716 KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_SECLABEL;
719 * Test the connection creation attach flags
721 ret = kdbus_test_peers_creation(env);
722 /* Restore previous kdbus mask */
723 kdbus_sysfs_set_parameter_mask(env->mask_param_path,
724 old_kdbus_flags_mask);
725 ASSERT_RETURN(ret == 0);
728 * Test the CONN_INFO attach flags
730 ret = kdbus_test_peers_info(env);
731 /* Restore previous kdbus mask */
732 kdbus_sysfs_set_parameter_mask(env->mask_param_path,
733 old_kdbus_flags_mask);
734 ASSERT_RETURN(ret == 0);
737 * Test the Bus creator info and its attach flags
739 ret = kdbus_test_bus_creator_info(env);
740 /* Restore previous kdbus mask */
741 kdbus_sysfs_set_parameter_mask(env->mask_param_path,
742 old_kdbus_flags_mask);
743 ASSERT_RETURN(ret == 0);
745 ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path,
747 ASSERT_RETURN(ret == 0 && old_kdbus_flags_mask == flags_mask);