13 #include <sys/capability.h>
14 #include <sys/types.h>
17 #include "kdbus-test.h"
18 #include "kdbus-util.h"
19 #include "kdbus-enum.h"
21 static int kdbus_starter_poll(struct kdbus_conn *conn)
27 fd.events = POLLIN | POLLPRI | POLLHUP;
30 ret = poll(&fd, 1, 100);
34 if (fd.revents & POLLIN)
37 if (fd.revents & (POLLHUP | POLLERR))
44 /* Ensure that kdbus activator logic is safe */
45 static int kdbus_priv_activator(struct kdbus_test_env *env)
48 struct kdbus_msg *msg = NULL;
49 uint64_t cookie = 0xdeadbeef;
50 uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
51 struct kdbus_conn *activator;
52 struct kdbus_conn *service;
53 struct kdbus_conn *client;
54 struct kdbus_conn *holder;
55 struct kdbus_policy_access *access;
57 access = (struct kdbus_policy_access[]){
59 .type = KDBUS_POLICY_ACCESS_USER,
61 .access = KDBUS_POLICY_OWN,
64 .type = KDBUS_POLICY_ACCESS_USER,
66 .access = KDBUS_POLICY_TALK,
70 activator = kdbus_hello_activator(env->buspath, "foo.priv.activator",
72 ASSERT_RETURN(activator);
74 service = kdbus_hello(env->buspath, 0, NULL, 0);
75 ASSERT_RETURN(service);
77 client = kdbus_hello(env->buspath, 0, NULL, 0);
78 ASSERT_RETURN(client);
81 * Make sure that other users can't TALK to the activator
84 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
85 /* Try to talk using the ID */
86 ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, 0, 0,
87 0, activator->id, 0, NULL);
88 ASSERT_EXIT(ret == -ENXIO);
90 /* Try to talk to the name */
91 ret = kdbus_msg_send(unpriv, "foo.priv.activator",
93 KDBUS_DST_ID_NAME, 0, NULL);
94 ASSERT_EXIT(ret == -EPERM);
96 ASSERT_RETURN(ret >= 0);
99 * Make sure that we did not receive anything, so the
100 * service will not be started automatically
103 ret = kdbus_starter_poll(activator);
104 ASSERT_RETURN(ret == -ETIMEDOUT);
107 * Now try to emulate the starter/service logic and
112 ret = kdbus_msg_send(service, "foo.priv.activator", cookie,
113 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
114 ASSERT_RETURN(ret == 0);
116 ret = kdbus_starter_poll(activator);
117 ASSERT_RETURN(ret == 0);
119 /* Policies are still checked, access denied */
121 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
122 ret = kdbus_name_acquire(unpriv, "foo.priv.activator",
124 ASSERT_RETURN(ret == -EPERM);
126 ASSERT_RETURN(ret >= 0);
128 ret = kdbus_name_acquire(service, "foo.priv.activator",
130 ASSERT_RETURN(ret == 0);
132 /* We read our previous starter message */
134 ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
135 ASSERT_RETURN(ret == 0);
137 /* Try to talk, we still fail */
140 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
141 /* Try to talk to the name */
142 ret = kdbus_msg_send(unpriv, "foo.priv.activator",
144 KDBUS_DST_ID_NAME, 0, NULL);
145 ASSERT_EXIT(ret == -EPERM);
147 ASSERT_RETURN(ret >= 0);
149 /* Still nothing to read */
151 ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
152 ASSERT_RETURN(ret == -ETIMEDOUT);
154 /* We receive every thing now */
157 ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
158 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
159 ASSERT_RETURN(ret == 0);
160 ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
161 ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
165 /* Policies default to deny TALK now */
166 kdbus_conn_free(activator);
169 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
170 /* Try to talk to the name */
171 ret = kdbus_msg_send(unpriv, "foo.priv.activator",
175 ASSERT_EXIT(ret == -EPERM);
177 ASSERT_RETURN(ret >= 0);
179 ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
180 ASSERT_RETURN(ret == -ETIMEDOUT);
182 /* Same user is able to TALK */
184 ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
185 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
186 ASSERT_RETURN(ret == 0);
187 ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
188 ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
192 access = (struct kdbus_policy_access []){
194 .type = KDBUS_POLICY_ACCESS_WORLD,
196 .access = KDBUS_POLICY_TALK,
200 holder = kdbus_hello_registrar(env->buspath, "foo.priv.activator",
201 access, 1, KDBUS_HELLO_POLICY_HOLDER);
202 ASSERT_RETURN(holder);
204 /* Now we are able to TALK to the name */
207 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
208 /* Try to talk to the name */
209 ret = kdbus_msg_send(unpriv, "foo.priv.activator",
213 ASSERT_EXIT(ret == 0);
215 ASSERT_RETURN(ret >= 0);
217 ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
218 ASSERT_RETURN(ret == 0);
220 ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
221 ret = kdbus_name_acquire(unpriv, "foo.priv.activator",
223 ASSERT_RETURN(ret == -EPERM);
225 ASSERT_RETURN(ret >= 0);
227 kdbus_conn_free(service);
228 kdbus_conn_free(client);
229 kdbus_conn_free(holder);
234 int kdbus_test_activator(struct kdbus_test_env *env)
237 struct kdbus_conn *activator;
238 struct pollfd fds[2];
239 bool activator_done = false;
240 struct kdbus_policy_access access[2];
242 access[0].type = KDBUS_POLICY_ACCESS_USER;
243 access[0].id = getuid();
244 access[0].access = KDBUS_POLICY_OWN;
246 access[1].type = KDBUS_POLICY_ACCESS_WORLD;
247 access[1].access = KDBUS_POLICY_TALK;
249 activator = kdbus_hello_activator(env->buspath, "foo.test.activator",
251 ASSERT_RETURN(activator);
253 ret = kdbus_add_match_empty(env->conn);
254 ASSERT_RETURN(ret == 0);
256 ret = kdbus_list(env->conn, KDBUS_LIST_NAMES |
258 KDBUS_LIST_ACTIVATORS |
260 ASSERT_RETURN(ret == 0);
262 ret = kdbus_msg_send(env->conn, "foo.test.activator", 0xdeafbeef,
263 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
264 ASSERT_RETURN(ret == 0);
266 fds[0].fd = activator->fd;
267 fds[1].fd = env->conn->fd;
269 kdbus_printf("-- entering poll loop ...\n");
272 int i, nfds = sizeof(fds) / sizeof(fds[0]);
274 for (i = 0; i < nfds; i++) {
275 fds[i].events = POLLIN | POLLPRI;
279 ret = poll(fds, nfds, 3000);
280 ASSERT_RETURN(ret >= 0);
282 ret = kdbus_list(env->conn, KDBUS_LIST_NAMES);
283 ASSERT_RETURN(ret == 0);
285 if ((fds[0].revents & POLLIN) && !activator_done) {
286 uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
288 kdbus_printf("Starter was called back!\n");
290 ret = kdbus_name_acquire(env->conn,
291 "foo.test.activator", &flags);
292 ASSERT_RETURN(ret == 0);
294 activator_done = true;
297 if (fds[1].revents & POLLIN) {
298 kdbus_msg_recv(env->conn, NULL, NULL);
303 /* Check if all uids/gids are mapped */
304 if (!all_uids_gids_are_mapped())
307 /* Check now capabilities, so we run the previous tests */
308 ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
309 ASSERT_RETURN(ret >= 0);
314 ret = kdbus_priv_activator(env);
315 ASSERT_RETURN(ret == 0);
317 kdbus_conn_free(activator);