10 #include <sys/capability.h>
11 #include <sys/eventfd.h>
14 #include "kdbus-test.h"
15 #include "kdbus-util.h"
16 #include "kdbus-enum.h"
18 static int test_policy_priv_by_id(const char *bus,
19 struct kdbus_conn *conn_dst,
20 bool drop_second_user,
25 uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
27 ASSERT_RETURN(conn_dst);
29 ret = RUN_UNPRIVILEGED_CONN(unpriv, bus, ({
30 ret = kdbus_msg_send(unpriv, NULL,
31 expected_cookie, 0, 0, 0,
32 conn_dst->id, 0, NULL);
33 ASSERT_EXIT(ret == child_status);
35 ASSERT_RETURN(ret >= 0);
37 ret = kdbus_msg_recv_poll(conn_dst, 300, NULL, NULL);
38 ASSERT_RETURN(ret == parent_status);
43 static int test_policy_priv_by_broadcast(const char *bus,
44 struct kdbus_conn *conn_dst,
51 eventfd_t event_status = 0;
52 struct kdbus_msg *msg = NULL;
53 uid_t second_uid = UNPRIV_UID;
54 gid_t second_gid = UNPRIV_GID;
55 struct kdbus_conn *child_2 = conn_dst;
56 uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
58 /* Drop to another unprivileged user other than UNPRIV_UID */
59 if (drop_second_user == DROP_OTHER_UNPRIV) {
60 second_uid = UNPRIV_UID - 1;
61 second_gid = UNPRIV_GID - 1;
64 /* child will signal parent to send broadcast */
65 efd = eventfd(0, EFD_CLOEXEC);
66 ASSERT_RETURN_VAL(efd >= 0, efd);
68 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
69 struct kdbus_conn *child;
71 child = kdbus_hello(bus, 0, NULL, 0);
74 ret = kdbus_add_match_empty(child);
75 ASSERT_EXIT(ret == 0);
78 ret = eventfd_write(efd, 1);
79 ASSERT_EXIT(ret == 0);
81 /* Use a little bit high time */
82 ret = kdbus_msg_recv_poll(child, 500, &msg, NULL);
83 ASSERT_EXIT(ret == child_status);
86 * If we expect the child to get the broadcast
87 * message, then check the received cookie.
90 ASSERT_EXIT(expected_cookie == msg->cookie);
93 /* Use expected_cookie since 'msg' might be NULL */
94 ret = kdbus_msg_send(child, NULL, expected_cookie + 1,
95 0, 0, 0, KDBUS_DST_ID_BROADCAST,
97 ASSERT_EXIT(ret == 0);
100 kdbus_conn_free(child);
103 if (drop_second_user == DO_NOT_DROP) {
104 ASSERT_RETURN(child_2);
106 ret = eventfd_read(efd, &event_status);
107 ASSERT_RETURN(ret >= 0 && event_status == 1);
109 ret = kdbus_msg_send(child_2, NULL,
110 expected_cookie, 0, 0, 0,
111 KDBUS_DST_ID_BROADCAST,
113 ASSERT_RETURN(ret == 0);
115 /* Use a little bit high time */
116 ret = kdbus_msg_recv_poll(child_2, 1000,
118 ASSERT_RETURN(ret == parent_status);
121 * Check returned cookie in case we expect
125 ASSERT_RETURN(msg->cookie ==
126 expected_cookie + 1);
132 * Two unprivileged users will try to
133 * communicate using broadcast.
135 ret = RUN_UNPRIVILEGED(second_uid, second_gid, ({
136 child_2 = kdbus_hello(bus, 0, NULL, 0);
137 ASSERT_EXIT(child_2);
139 ret = kdbus_add_match_empty(child_2);
140 ASSERT_EXIT(ret == 0);
142 ret = eventfd_read(efd, &event_status);
143 ASSERT_EXIT(ret >= 0 && event_status == 1);
145 ret = kdbus_msg_send(child_2, NULL,
146 expected_cookie, 0, 0, 0,
147 KDBUS_DST_ID_BROADCAST,
149 ASSERT_EXIT(ret == 0);
151 /* Use a little bit high time */
152 ret = kdbus_msg_recv_poll(child_2, 1000,
154 ASSERT_EXIT(ret == parent_status);
157 * Check returned cookie in case we expect
161 ASSERT_EXIT(msg->cookie ==
162 expected_cookie + 1);
166 kdbus_conn_free(child_2);
169 ASSERT_RETURN(ret == 0);
172 ASSERT_RETURN(ret == 0);
179 static void nosig(int sig)
183 static int test_priv_before_policy_upload(struct kdbus_test_env *env)
186 struct kdbus_conn *conn;
188 conn = kdbus_hello(env->buspath, 0, NULL, 0);
192 * Make sure unprivileged bus user cannot acquire names
193 * before registring any policy holder.
196 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
197 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
198 ASSERT_EXIT(ret < 0);
200 ASSERT_RETURN(ret == 0);
203 * Make sure unprivileged bus users cannot talk by default
204 * to privileged ones, unless a policy holder that allows
208 ret = test_policy_priv_by_id(env->buspath, conn, false,
210 ASSERT_RETURN(ret == 0);
212 /* Activate matching for a privileged connection */
213 ret = kdbus_add_match_empty(conn);
214 ASSERT_RETURN(ret == 0);
217 * First make sure that BROADCAST with msg flag
218 * KDBUS_MSG_EXPECT_REPLY will fail with -ENOTUNIQ
220 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
221 ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef,
222 KDBUS_MSG_EXPECT_REPLY,
224 KDBUS_DST_ID_BROADCAST,
226 ASSERT_EXIT(ret == -ENOTUNIQ);
228 ASSERT_RETURN(ret == 0);
231 * Test broadcast with a privileged connection.
233 * The first unprivileged receiver should not get the
234 * broadcast message sent by the privileged connection,
235 * since there is no a TALK policy that allows the
236 * unprivileged to TALK to the privileged connection. It
237 * will fail with -ETIMEDOUT
240 * The privileged connection should get the broadcast
241 * message from the unprivileged one. Since the receiver is
242 * a privileged bus user and it has default TALK access to
243 * all connections it will receive those.
246 ret = test_policy_priv_by_broadcast(env->buspath, conn,
249 ASSERT_RETURN(ret == 0);
253 * Test broadcast with two unprivileged connections running
254 * under the same user.
256 * Both connections should succeed.
259 ret = test_policy_priv_by_broadcast(env->buspath, NULL,
260 DROP_SAME_UNPRIV, 0, 0);
261 ASSERT_RETURN(ret == 0);
264 * Test broadcast with two unprivileged connections running
265 * under different users.
267 * Both connections will fail with -ETIMEDOUT.
270 ret = test_policy_priv_by_broadcast(env->buspath, NULL,
272 -ETIMEDOUT, -ETIMEDOUT);
273 ASSERT_RETURN(ret == 0);
275 kdbus_conn_free(conn);
280 static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
284 eventfd_t event_status = 0;
285 struct kdbus_msg *msg = NULL;
286 struct kdbus_conn *owner_a, *owner_b;
287 struct kdbus_conn *holder_a, *holder_b;
288 struct kdbus_policy_access access = {};
289 uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
291 owner_a = kdbus_hello(env->buspath, 0, NULL, 0);
292 ASSERT_RETURN(owner_a);
294 ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL);
295 ASSERT_EXIT(ret >= 0);
298 * Make sure unprivileged bus users cannot talk by default
299 * to privileged ones, unless a policy holder that allows
304 ret = test_policy_priv_by_id(env->buspath, owner_a, false,
306 ASSERT_RETURN(ret == 0);
309 * Make sure that privileged won't receive broadcasts unless
310 * it installs a match. It will fail with -ETIMEDOUT
312 * At same time check that the unprivileged connection will
313 * not receive the broadcast message from the privileged one
314 * since the privileged one owns a name with a restricted
315 * policy TALK (actually the TALK policy is still not
316 * registered so we fail by default), thus the unprivileged
317 * receiver is not able to TALK to that name.
320 ret = test_policy_priv_by_broadcast(env->buspath, owner_a,
322 -ETIMEDOUT, -ETIMEDOUT);
323 ASSERT_RETURN(ret == 0);
325 /* Activate matching for a privileged connection */
326 ret = kdbus_add_match_empty(owner_a);
327 ASSERT_RETURN(ret == 0);
330 * Redo the previous test. The privileged conn owner_a is
331 * able to TALK to any connection so it will receive the
332 * broadcast message now.
335 ret = test_policy_priv_by_broadcast(env->buspath, owner_a,
338 ASSERT_RETURN(ret == 0);
341 * Test that broadcast between two unprivileged users running
342 * under the same user still succeed.
345 ret = test_policy_priv_by_broadcast(env->buspath, NULL,
346 DROP_SAME_UNPRIV, 0, 0);
347 ASSERT_RETURN(ret == 0);
350 * Test broadcast with two unprivileged connections running
351 * under different users.
353 * Both connections will fail with -ETIMEDOUT.
356 ret = test_policy_priv_by_broadcast(env->buspath, NULL,
358 -ETIMEDOUT, -ETIMEDOUT);
359 ASSERT_RETURN(ret == 0);
361 access = (struct kdbus_policy_access){
362 .type = KDBUS_POLICY_ACCESS_USER,
364 .access = KDBUS_POLICY_OWN,
367 holder_a = kdbus_hello_registrar(env->buspath,
368 "com.example.broadcastA",
370 KDBUS_HELLO_POLICY_HOLDER);
371 ASSERT_RETURN(holder_a);
373 holder_b = kdbus_hello_registrar(env->buspath,
374 "com.example.broadcastB",
376 KDBUS_HELLO_POLICY_HOLDER);
377 ASSERT_RETURN(holder_b);
379 /* Free connections and their received messages and restart */
380 kdbus_conn_free(owner_a);
382 owner_a = kdbus_hello(env->buspath, 0, NULL, 0);
383 ASSERT_RETURN(owner_a);
385 /* Activate matching for a privileged connection */
386 ret = kdbus_add_match_empty(owner_a);
387 ASSERT_RETURN(ret == 0);
389 ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL);
390 ASSERT_EXIT(ret >= 0);
392 owner_b = kdbus_hello(env->buspath, 0, NULL, 0);
393 ASSERT_RETURN(owner_b);
395 ret = kdbus_name_acquire(owner_b, "com.example.broadcastB", NULL);
396 ASSERT_EXIT(ret >= 0);
398 /* Activate matching for a privileged connection */
399 ret = kdbus_add_match_empty(owner_b);
400 ASSERT_RETURN(ret == 0);
403 * Test that even if "com.example.broadcastA" and
404 * "com.example.broadcastB" do have a TALK access by default
405 * they are able to signal each other using broadcast due to
406 * the fact they are privileged connections, they receive
407 * all broadcasts if the match allows it.
411 ret = kdbus_msg_send(owner_a, NULL, expected_cookie, 0,
412 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
413 ASSERT_RETURN(ret == 0);
415 ret = kdbus_msg_recv_poll(owner_b, 100, &msg, NULL);
416 ASSERT_RETURN(ret == 0);
417 ASSERT_RETURN(msg->cookie == expected_cookie);
420 ASSERT_RETURN(msg->src_id == owner_a->id);
424 /* Release name "com.example.broadcastB" */
426 ret = kdbus_name_release(owner_b, "com.example.broadcastB");
427 ASSERT_EXIT(ret >= 0);
429 /* KDBUS_POLICY_OWN for unprivileged connections */
430 access = (struct kdbus_policy_access){
431 .type = KDBUS_POLICY_ACCESS_WORLD,
433 .access = KDBUS_POLICY_OWN,
436 /* Update the policy so unprivileged will own the name */
438 ret = kdbus_conn_update_policy(holder_b,
439 "com.example.broadcastB",
441 ASSERT_RETURN(ret == 0);
444 * Send broadcasts from an unprivileged connection that
445 * owns a name "com.example.broadcastB".
447 * We'll have four destinations here:
449 * 1) destination owner_a: privileged connection that owns
450 * "com.example.broadcastA". It will receive the broadcast
451 * since it is a privileged has default TALK access to all
452 * connections, and it is subscribed to the match.
455 * owner_b: privileged connection (running under a different
456 * uid) that do not own names, but with an empty broadcast
457 * match, so it will receive broadcasts since it has default
458 * TALK access to all connection.
460 * unpriv_a: unpriv connection that do not own any name.
461 * It will receive the broadcast since it is running under
462 * the same user of the one broadcasting and did install
463 * matches. It should get the message.
465 * unpriv_b: unpriv connection is not interested in broadcast
466 * messages, so it did not install broadcast matches. Should
467 * fail with -ETIMEDOUT
471 efd = eventfd(0, EFD_CLOEXEC);
472 ASSERT_RETURN_VAL(efd >= 0, efd);
474 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
475 struct kdbus_conn *unpriv_owner;
476 struct kdbus_conn *unpriv_a, *unpriv_b;
478 unpriv_owner = kdbus_hello(env->buspath, 0, NULL, 0);
479 ASSERT_EXIT(unpriv_owner);
481 unpriv_a = kdbus_hello(env->buspath, 0, NULL, 0);
482 ASSERT_EXIT(unpriv_a);
484 unpriv_b = kdbus_hello(env->buspath, 0, NULL, 0);
485 ASSERT_EXIT(unpriv_b);
487 ret = kdbus_name_acquire(unpriv_owner,
488 "com.example.broadcastB",
490 ASSERT_EXIT(ret >= 0);
492 ret = kdbus_add_match_empty(unpriv_a);
493 ASSERT_EXIT(ret == 0);
495 /* Signal that we are doing broadcasts */
496 ret = eventfd_write(efd, 1);
497 ASSERT_EXIT(ret == 0);
500 * Do broadcast from a connection that owns the
501 * names "com.example.broadcastB".
503 ret = kdbus_msg_send(unpriv_owner, NULL,
506 KDBUS_DST_ID_BROADCAST,
508 ASSERT_EXIT(ret == 0);
511 * Unprivileged connection running under the same
512 * user. It should succeed.
514 ret = kdbus_msg_recv_poll(unpriv_a, 300, &msg, NULL);
515 ASSERT_EXIT(ret == 0 && msg->cookie == expected_cookie);
518 * Did not install matches, not interested in
521 ret = kdbus_msg_recv_poll(unpriv_b, 300, NULL, NULL);
522 ASSERT_EXIT(ret == -ETIMEDOUT);
525 ret = eventfd_read(efd, &event_status);
526 ASSERT_RETURN(ret >= 0 && event_status == 1);
529 * owner_a must fail with -ETIMEDOUT, since it owns
530 * name "com.example.broadcastA" and its TALK
531 * access is restriced.
533 ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
534 ASSERT_RETURN(ret == 0);
536 /* confirm the received cookie */
537 ASSERT_RETURN(msg->cookie == expected_cookie);
542 * owner_b got the broadcast from an unprivileged
545 ret = kdbus_msg_recv_poll(owner_b, 300, &msg, NULL);
546 ASSERT_RETURN(ret == 0);
548 /* confirm the received cookie */
549 ASSERT_RETURN(msg->cookie == expected_cookie);
554 ASSERT_RETURN(ret == 0);
559 * Test broadcast with two unprivileged connections running
560 * under different users.
562 * Both connections will fail with -ETIMEDOUT.
565 ret = test_policy_priv_by_broadcast(env->buspath, NULL,
567 -ETIMEDOUT, -ETIMEDOUT);
568 ASSERT_RETURN(ret == 0);
570 /* Drop received broadcasts by privileged */
571 ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL);
572 ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL);
573 ASSERT_RETURN(ret == 0);
575 ret = kdbus_msg_recv(owner_a, NULL, NULL);
576 ASSERT_RETURN(ret == -EAGAIN);
578 ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL);
579 ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL);
580 ASSERT_RETURN(ret == 0);
582 ret = kdbus_msg_recv(owner_b, NULL, NULL);
583 ASSERT_RETURN(ret == -EAGAIN);
586 * Perform last tests, allow others to talk to name
587 * "com.example.broadcastA". So now receiving broadcasts
588 * from it should succeed since the TALK policy allow it.
591 /* KDBUS_POLICY_OWN for unprivileged connections */
592 access = (struct kdbus_policy_access){
593 .type = KDBUS_POLICY_ACCESS_WORLD,
595 .access = KDBUS_POLICY_TALK,
598 ret = kdbus_conn_update_policy(holder_a,
599 "com.example.broadcastA",
601 ASSERT_RETURN(ret == 0);
604 * Unprivileged is able to TALK to "com.example.broadcastA"
605 * now so it will receive its broadcasts
607 ret = test_policy_priv_by_broadcast(env->buspath, owner_a,
609 ASSERT_RETURN(ret == 0);
612 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
613 ret = kdbus_name_acquire(unpriv, "com.example.broadcastB",
615 ASSERT_EXIT(ret >= 0);
616 ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
617 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
618 ASSERT_EXIT(ret == 0);
620 ASSERT_RETURN(ret == 0);
622 /* owner_a is privileged it will get the broadcast now. */
623 ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
624 ASSERT_RETURN(ret == 0);
626 /* confirm the received cookie */
627 ASSERT_RETURN(msg->cookie == expected_cookie);
632 * owner_a released name "com.example.broadcastA". It should
633 * receive broadcasts since it is still privileged and has
636 * Unprivileged connection will own a name and will try to
637 * signal to the privileged connection.
640 ret = kdbus_name_release(owner_a, "com.example.broadcastA");
641 ASSERT_EXIT(ret >= 0);
644 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
645 ret = kdbus_name_acquire(unpriv, "com.example.broadcastB",
647 ASSERT_EXIT(ret >= 0);
648 ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
649 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
650 ASSERT_EXIT(ret == 0);
652 ASSERT_RETURN(ret == 0);
654 /* owner_a will get the broadcast now. */
655 ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
656 ASSERT_RETURN(ret == 0);
658 /* confirm the received cookie */
659 ASSERT_RETURN(msg->cookie == expected_cookie);
663 kdbus_conn_free(owner_a);
664 kdbus_conn_free(owner_b);
665 kdbus_conn_free(holder_a);
666 kdbus_conn_free(holder_b);
671 static int test_policy_priv(struct kdbus_test_env *env)
673 struct kdbus_conn *conn_a, *conn_b, *conn, *owner;
674 struct kdbus_policy_access access, *acc;
680 * Make sure we have CAP_SETUID/SETGID so we can drop privileges
683 ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
684 ASSERT_RETURN(ret >= 0);
689 /* make sure that uids and gids are mapped */
690 if (!all_uids_gids_are_mapped())
695 * conn_a: policy holder for com.example.a
696 * conn_b: name holder of com.example.b
699 signal(SIGUSR1, nosig);
701 sigaddset(&sset, SIGUSR1);
702 sigprocmask(SIG_BLOCK, &sset, NULL);
704 conn = kdbus_hello(env->buspath, 0, NULL, 0);
708 * Before registering any policy holder, make sure that the
709 * bus is secure by default. This test is necessary, it catches
710 * several cases where old D-Bus was vulnerable.
713 ret = test_priv_before_policy_upload(env);
714 ASSERT_RETURN(ret == 0);
717 * Make sure unprivileged are not able to register policy
721 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
722 struct kdbus_conn *holder;
724 holder = kdbus_hello_registrar(env->buspath,
725 "com.example.a", NULL, 0,
726 KDBUS_HELLO_POLICY_HOLDER);
727 ASSERT_EXIT(holder == NULL && errno == EPERM);
730 ASSERT_RETURN(ret == 0);
733 /* Register policy holder */
735 conn_a = kdbus_hello_registrar(env->buspath, "com.example.a",
736 NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
737 ASSERT_RETURN(conn_a);
739 conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
740 ASSERT_RETURN(conn_b);
742 ret = kdbus_name_acquire(conn_b, "com.example.b", NULL);
743 ASSERT_EXIT(ret >= 0);
746 * Make sure bus-owners can always acquire names.
748 ret = kdbus_name_acquire(conn, "com.example.a", NULL);
749 ASSERT_EXIT(ret >= 0);
751 kdbus_conn_free(conn);
754 * Make sure unprivileged users cannot acquire names with default
758 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
759 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
760 ASSERT_EXIT(ret < 0);
762 ASSERT_RETURN(ret >= 0);
765 * Make sure unprivileged users can acquire names if we make them
769 access = (struct kdbus_policy_access){
770 .type = KDBUS_POLICY_ACCESS_WORLD,
772 .access = KDBUS_POLICY_OWN,
776 * Make sure unprivileged/normal connections are not able
780 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
781 ret = kdbus_conn_update_policy(unpriv, "com.example.a",
783 ASSERT_EXIT(ret == -EOPNOTSUPP);
785 ASSERT_RETURN(ret == 0);
787 ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
788 ASSERT_RETURN(ret == 0);
790 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
791 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
792 ASSERT_EXIT(ret >= 0);
794 ASSERT_RETURN(ret >= 0);
797 * Make sure unprivileged users can acquire names if we make them
798 * gid-accessible. But only if the gid matches.
801 access = (struct kdbus_policy_access){
802 .type = KDBUS_POLICY_ACCESS_GROUP,
804 .access = KDBUS_POLICY_OWN,
807 ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
808 ASSERT_RETURN(ret == 0);
810 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
811 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
812 ASSERT_EXIT(ret >= 0);
814 ASSERT_RETURN(ret >= 0);
816 access = (struct kdbus_policy_access){
817 .type = KDBUS_POLICY_ACCESS_GROUP,
819 .access = KDBUS_POLICY_OWN,
822 ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
823 ASSERT_RETURN(ret == 0);
825 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
826 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
827 ASSERT_EXIT(ret < 0);
829 ASSERT_RETURN(ret >= 0);
832 * Make sure unprivileged users can acquire names if we make them
833 * uid-accessible. But only if the uid matches.
836 access = (struct kdbus_policy_access){
837 .type = KDBUS_POLICY_ACCESS_USER,
839 .access = KDBUS_POLICY_OWN,
842 ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
843 ASSERT_RETURN(ret == 0);
845 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
846 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
847 ASSERT_EXIT(ret >= 0);
849 ASSERT_RETURN(ret >= 0);
851 access = (struct kdbus_policy_access){
852 .type = KDBUS_POLICY_ACCESS_USER,
854 .access = KDBUS_POLICY_OWN,
857 ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
858 ASSERT_RETURN(ret == 0);
860 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
861 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
862 ASSERT_EXIT(ret < 0);
864 ASSERT_RETURN(ret >= 0);
867 * Make sure unprivileged users cannot acquire names if no owner-policy
868 * matches, even if SEE/TALK policies match.
872 acc = (struct kdbus_policy_access[]){
874 .type = KDBUS_POLICY_ACCESS_GROUP,
876 .access = KDBUS_POLICY_SEE,
879 .type = KDBUS_POLICY_ACCESS_USER,
881 .access = KDBUS_POLICY_TALK,
884 .type = KDBUS_POLICY_ACCESS_WORLD,
886 .access = KDBUS_POLICY_TALK,
889 .type = KDBUS_POLICY_ACCESS_WORLD,
891 .access = KDBUS_POLICY_SEE,
895 ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num);
896 ASSERT_RETURN(ret == 0);
898 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
899 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
900 ASSERT_EXIT(ret < 0);
902 ASSERT_RETURN(ret >= 0);
905 * Make sure unprivileged users can acquire names if the only matching
906 * policy is somewhere in the middle.
910 acc = (struct kdbus_policy_access[]){
912 .type = KDBUS_POLICY_ACCESS_USER,
914 .access = KDBUS_POLICY_OWN,
917 .type = KDBUS_POLICY_ACCESS_USER,
919 .access = KDBUS_POLICY_OWN,
922 .type = KDBUS_POLICY_ACCESS_USER,
924 .access = KDBUS_POLICY_OWN,
927 .type = KDBUS_POLICY_ACCESS_USER,
929 .access = KDBUS_POLICY_OWN,
932 .type = KDBUS_POLICY_ACCESS_USER,
934 .access = KDBUS_POLICY_OWN,
938 ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num);
939 ASSERT_RETURN(ret == 0);
941 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
942 ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
943 ASSERT_EXIT(ret >= 0);
945 ASSERT_RETURN(ret >= 0);
951 ret = kdbus_conn_update_policy(conn_a, "com.example.a", NULL, 0);
952 ASSERT_RETURN(ret == 0);
955 * Make sure privileged bus users can _always_ talk to others.
958 conn = kdbus_hello(env->buspath, 0, NULL, 0);
961 ret = kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0,
963 ASSERT_EXIT(ret >= 0);
965 ret = kdbus_msg_recv_poll(conn_b, 300, NULL, NULL);
966 ASSERT_EXIT(ret >= 0);
968 kdbus_conn_free(conn);
971 * Make sure unprivileged bus users cannot talk by default.
974 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
975 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
977 ASSERT_EXIT(ret == -EPERM);
979 ASSERT_RETURN(ret >= 0);
982 * Make sure unprivileged bus users can talk to equals, even without
986 access = (struct kdbus_policy_access){
987 .type = KDBUS_POLICY_ACCESS_USER,
989 .access = KDBUS_POLICY_OWN,
992 ret = kdbus_conn_update_policy(conn_a, "com.example.c", &access, 1);
993 ASSERT_RETURN(ret == 0);
995 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
996 struct kdbus_conn *owner;
998 owner = kdbus_hello(env->buspath, 0, NULL, 0);
999 ASSERT_RETURN(owner);
1001 ret = kdbus_name_acquire(owner, "com.example.c", NULL);
1002 ASSERT_EXIT(ret >= 0);
1004 ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
1006 ASSERT_EXIT(ret >= 0);
1007 ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
1008 ASSERT_EXIT(ret >= 0);
1010 kdbus_conn_free(owner);
1012 ASSERT_RETURN(ret >= 0);
1015 * Make sure unprivileged bus users can talk to privileged users if a
1016 * suitable UID policy is set.
1019 access = (struct kdbus_policy_access){
1020 .type = KDBUS_POLICY_ACCESS_USER,
1022 .access = KDBUS_POLICY_TALK,
1025 ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
1026 ASSERT_RETURN(ret == 0);
1028 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1029 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1031 ASSERT_EXIT(ret >= 0);
1033 ASSERT_RETURN(ret >= 0);
1035 ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
1036 ASSERT_EXIT(ret >= 0);
1039 * Make sure unprivileged bus users can talk to privileged users if a
1040 * suitable GID policy is set.
1043 access = (struct kdbus_policy_access){
1044 .type = KDBUS_POLICY_ACCESS_GROUP,
1046 .access = KDBUS_POLICY_TALK,
1049 ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
1050 ASSERT_RETURN(ret == 0);
1052 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1053 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1055 ASSERT_EXIT(ret >= 0);
1057 ASSERT_RETURN(ret >= 0);
1059 ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
1060 ASSERT_EXIT(ret >= 0);
1063 * Make sure unprivileged bus users can talk to privileged users if a
1064 * suitable WORLD policy is set.
1067 access = (struct kdbus_policy_access){
1068 .type = KDBUS_POLICY_ACCESS_WORLD,
1070 .access = KDBUS_POLICY_TALK,
1073 ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
1074 ASSERT_RETURN(ret == 0);
1076 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1077 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1079 ASSERT_EXIT(ret >= 0);
1081 ASSERT_RETURN(ret >= 0);
1083 ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
1084 ASSERT_EXIT(ret >= 0);
1087 * Make sure unprivileged bus users cannot talk to privileged users if
1088 * no suitable policy is set.
1092 acc = (struct kdbus_policy_access[]){
1094 .type = KDBUS_POLICY_ACCESS_USER,
1096 .access = KDBUS_POLICY_OWN,
1099 .type = KDBUS_POLICY_ACCESS_USER,
1101 .access = KDBUS_POLICY_TALK,
1104 .type = KDBUS_POLICY_ACCESS_USER,
1106 .access = KDBUS_POLICY_SEE,
1109 .type = KDBUS_POLICY_ACCESS_USER,
1111 .access = KDBUS_POLICY_TALK,
1114 .type = KDBUS_POLICY_ACCESS_USER,
1116 .access = KDBUS_POLICY_TALK,
1120 ret = kdbus_conn_update_policy(conn_a, "com.example.b", acc, num);
1121 ASSERT_RETURN(ret == 0);
1123 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1124 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1126 ASSERT_EXIT(ret == -EPERM);
1128 ASSERT_RETURN(ret >= 0);
1131 * Make sure unprivileged bus users can talk to privileged users if a
1132 * suitable OWN privilege overwrites TALK.
1135 access = (struct kdbus_policy_access){
1136 .type = KDBUS_POLICY_ACCESS_WORLD,
1138 .access = KDBUS_POLICY_OWN,
1141 ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
1142 ASSERT_RETURN(ret == 0);
1144 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1145 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1147 ASSERT_EXIT(ret >= 0);
1149 ASSERT_RETURN(ret >= 0);
1151 ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
1152 ASSERT_EXIT(ret >= 0);
1155 * Make sure the TALK cache is reset correctly when policies are
1159 access = (struct kdbus_policy_access){
1160 .type = KDBUS_POLICY_ACCESS_WORLD,
1162 .access = KDBUS_POLICY_TALK,
1165 ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
1166 ASSERT_RETURN(ret == 0);
1168 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
1169 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1171 ASSERT_EXIT(ret >= 0);
1173 ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
1174 ASSERT_EXIT(ret >= 0);
1176 ret = kdbus_conn_update_policy(conn_a, "com.example.b",
1178 ASSERT_RETURN(ret == 0);
1180 ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
1182 ASSERT_EXIT(ret == -EPERM);
1184 ASSERT_RETURN(ret >= 0);
1187 * Make sure the TALK cache is reset correctly when policy holders
1191 access = (struct kdbus_policy_access){
1192 .type = KDBUS_POLICY_ACCESS_WORLD,
1194 .access = KDBUS_POLICY_OWN,
1197 conn = kdbus_hello_registrar(env->buspath, "com.example.c",
1198 NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
1199 ASSERT_RETURN(conn);
1201 ret = kdbus_conn_update_policy(conn, "com.example.c", &access, 1);
1202 ASSERT_RETURN(ret == 0);
1204 owner = kdbus_hello(env->buspath, 0, NULL, 0);
1205 ASSERT_RETURN(owner);
1207 ret = kdbus_name_acquire(owner, "com.example.c", NULL);
1208 ASSERT_RETURN(ret >= 0);
1210 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
1211 struct kdbus_conn *unpriv;
1213 /* wait for parent to be finished */
1215 ret = sigsuspend(&sset);
1216 ASSERT_RETURN(ret == -1 && errno == EINTR);
1218 unpriv = kdbus_hello(env->buspath, 0, NULL, 0);
1219 ASSERT_RETURN(unpriv);
1221 ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
1223 ASSERT_EXIT(ret >= 0);
1225 ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
1226 ASSERT_EXIT(ret >= 0);
1228 /* free policy holder */
1229 kdbus_conn_free(conn);
1231 ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
1233 ASSERT_EXIT(ret == -EPERM);
1235 kdbus_conn_free(unpriv);
1237 /* make sure policy holder is only valid in child */
1238 kdbus_conn_free(conn);
1241 ASSERT_RETURN(ret >= 0);
1245 * The following tests are necessary.
1248 ret = test_broadcast_after_policy_upload(env);
1249 ASSERT_RETURN(ret == 0);
1251 kdbus_conn_free(owner);
1257 kdbus_conn_free(conn_b);
1258 kdbus_conn_free(conn_a);
1263 int kdbus_test_policy_priv(struct kdbus_test_env *env)
1268 /* make sure to exit() if a child returns from fork() */
1270 ret = test_policy_priv(env);
1271 if (pid != getpid())