kdbus: the driver, original and non-working
[platform/kernel/linux-exynos.git] / tools / testing / selftests / kdbus / test-monitor.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <time.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <unistd.h>
8 #include <stdint.h>
9 #include <stdbool.h>
10 #include <errno.h>
11 #include <assert.h>
12 #include <signal.h>
13 #include <sys/time.h>
14 #include <sys/mman.h>
15 #include <sys/capability.h>
16 #include <sys/wait.h>
17
18 #include "kdbus-util.h"
19 #include "kdbus-enum.h"
20
21 #include "kdbus-util.h"
22 #include "kdbus-enum.h"
23 #include "kdbus-test.h"
24
25 int kdbus_test_monitor(struct kdbus_test_env *env)
26 {
27         struct kdbus_conn *monitor, *conn;
28         unsigned int cookie = 0xdeadbeef;
29         struct kdbus_msg *msg;
30         uint64_t offset = 0;
31         int ret;
32
33         conn = kdbus_hello(env->buspath, 0, NULL, 0);
34         ASSERT_RETURN(conn);
35
36         /* add matches to make sure the monitor do not trigger an item add or
37          * remove on connect and disconnect, respectively.
38          */
39         ret = kdbus_add_match_id(conn, 0x1, KDBUS_ITEM_ID_ADD,
40                                  KDBUS_MATCH_ID_ANY);
41         ASSERT_RETURN(ret == 0);
42
43         ret = kdbus_add_match_id(conn, 0x2, KDBUS_ITEM_ID_REMOVE,
44                                  KDBUS_MATCH_ID_ANY);
45         ASSERT_RETURN(ret == 0);
46
47         /* register a monitor */
48         monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0);
49         ASSERT_RETURN(monitor);
50
51         /* make sure we did not receive a monitor connect notification */
52         ret = kdbus_msg_recv(conn, &msg, &offset);
53         ASSERT_RETURN(ret == -EAGAIN);
54
55         /* check that a monitor cannot acquire a name */
56         ret = kdbus_name_acquire(monitor, "foo.bar.baz", NULL);
57         ASSERT_RETURN(ret == -EOPNOTSUPP);
58
59         ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0,  0, conn->id,
60                              0, NULL);
61         ASSERT_RETURN(ret == 0);
62
63         /* the recipient should have gotten the message */
64         ret = kdbus_msg_recv(conn, &msg, &offset);
65         ASSERT_RETURN(ret == 0);
66         ASSERT_RETURN(msg->cookie == cookie);
67         kdbus_msg_free(msg);
68         kdbus_free(conn, offset);
69
70         /* and so should the monitor */
71         ret = kdbus_msg_recv(monitor, &msg, &offset);
72         ASSERT_RETURN(ret == 0);
73         ASSERT_RETURN(msg->cookie == cookie);
74
75         kdbus_msg_free(msg);
76         kdbus_free(monitor, offset);
77
78         /* Installing matches for monitors must fais must fail */
79         ret = kdbus_add_match_empty(monitor);
80         ASSERT_RETURN(ret == -EOPNOTSUPP);
81
82         cookie++;
83         ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
84                              KDBUS_DST_ID_BROADCAST, 0, NULL);
85         ASSERT_RETURN(ret == 0);
86
87         /* The monitor should get the message. */
88         ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
89         ASSERT_RETURN(ret == 0);
90         ASSERT_RETURN(msg->cookie == cookie);
91
92         kdbus_msg_free(msg);
93         kdbus_free(monitor, offset);
94
95         /*
96          * Since we are the only monitor, update the attach flags
97          * and tell we are not interessted in attach flags recv
98          */
99
100         ret = kdbus_conn_update_attach_flags(monitor,
101                                              _KDBUS_ATTACH_ALL,
102                                              0);
103         ASSERT_RETURN(ret == 0);
104
105         cookie++;
106         ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
107                              KDBUS_DST_ID_BROADCAST, 0, NULL);
108         ASSERT_RETURN(ret == 0);
109
110         ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
111         ASSERT_RETURN(ret == 0);
112         ASSERT_RETURN(msg->cookie == cookie);
113
114         ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
115         ASSERT_RETURN(ret == 0);
116
117         kdbus_msg_free(msg);
118         kdbus_free(monitor, offset);
119
120         /*
121          * Now we are interested in KDBUS_ITEM_TIMESTAMP and
122          * KDBUS_ITEM_CREDS
123          */
124         ret = kdbus_conn_update_attach_flags(monitor,
125                                              _KDBUS_ATTACH_ALL,
126                                              KDBUS_ATTACH_TIMESTAMP |
127                                              KDBUS_ATTACH_CREDS);
128         ASSERT_RETURN(ret == 0);
129
130         cookie++;
131         ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
132                              KDBUS_DST_ID_BROADCAST, 0, NULL);
133         ASSERT_RETURN(ret == 0);
134
135         ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
136         ASSERT_RETURN(ret == 0);
137         ASSERT_RETURN(msg->cookie == cookie);
138
139         ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
140         ASSERT_RETURN(ret == 1);
141
142         ret = kdbus_item_in_message(msg, KDBUS_ITEM_CREDS);
143         ASSERT_RETURN(ret == 1);
144
145         /* the KDBUS_ITEM_PID_COMM was not requested */
146         ret = kdbus_item_in_message(msg, KDBUS_ITEM_PID_COMM);
147         ASSERT_RETURN(ret == 0);
148
149         kdbus_msg_free(msg);
150         kdbus_free(monitor, offset);
151
152         kdbus_conn_free(monitor);
153         /* make sure we did not receive a monitor disconnect notification */
154         ret = kdbus_msg_recv(conn, &msg, &offset);
155         ASSERT_RETURN(ret == -EAGAIN);
156
157         kdbus_conn_free(conn);
158
159         /* Make sure that monitor as unprivileged is not allowed */
160         ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
161         ASSERT_RETURN(ret >= 0);
162
163         if (ret && all_uids_gids_are_mapped()) {
164                 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
165                         monitor = kdbus_hello(env->buspath,
166                                               KDBUS_HELLO_MONITOR,
167                                               NULL, 0);
168                         ASSERT_EXIT(!monitor && errno == EPERM);
169
170                         _exit(EXIT_SUCCESS);
171                 }),
172                 ({ 0; }));
173                 ASSERT_RETURN(ret == 0);
174         }
175
176         return TEST_OK;
177 }