]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-kernel.c
sd-bus: assert clock_gettime()'s return value
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-kernel.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
24 #endif
25
26 #include <fcntl.h>
27 #include <malloc.h>
28 #include <libgen.h>
29 #include <sys/mman.h>
30 #include <sys/prctl.h>
31
32 #include "util.h"
33 #include "strv.h"
34
35 #include "bus-internal.h"
36 #include "bus-message.h"
37 #include "bus-kernel.h"
38 #include "bus-bloom.h"
39 #include "bus-util.h"
40 #include "bus-label.h"
41 #include "cgroup-util.h"
42
43 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
44
45 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
46 int r;
47
48 assert(s);
49 assert(id);
50
51 if (!startswith(s, ":1."))
52 return 0;
53
54 r = safe_atou64(s + 3, id);
55 if (r < 0)
56 return r;
57
58 return 1;
59 }
60
61 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
62 assert(d);
63 assert(sz > 0);
64
65 *d = ALIGN8_PTR(*d);
66
67 /* Note that p can be NULL, which encodes a region full of
68 * zeroes, which is useful to optimize certain padding
69 * conditions */
70
71 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
72 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
73 (*d)->vec.address = PTR_TO_UINT64(p);
74 (*d)->vec.size = sz;
75
76 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
77 }
78
79 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
80 assert(d);
81 assert(memfd >= 0);
82 assert(sz > 0);
83
84 *d = ALIGN8_PTR(*d);
85 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
86 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
87 (*d)->memfd.fd = memfd;
88 (*d)->memfd.size = sz;
89
90 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
91 }
92
93 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
94 assert(d);
95 assert(s);
96
97 *d = ALIGN8_PTR(*d);
98
99 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
100 (*d)->type = KDBUS_ITEM_DST_NAME;
101 memcpy((*d)->str, s, length + 1);
102
103 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
104 }
105
106 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
107 struct kdbus_item *i;
108
109 assert(d);
110
111 i = ALIGN8_PTR(*d);
112
113 i->size = offsetof(struct kdbus_item, bloom_filter) +
114 offsetof(struct kdbus_bloom_filter, data) +
115 length;
116 i->type = KDBUS_ITEM_BLOOM_FILTER;
117
118 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
119
120 return &i->bloom_filter;
121 }
122
123 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
124 assert(d);
125 assert(fds);
126 assert(n_fds > 0);
127
128 *d = ALIGN8_PTR(*d);
129 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
130 (*d)->type = KDBUS_ITEM_FDS;
131 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
132
133 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
134 }
135
136 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
137 void *data;
138 unsigned i;
139 int r;
140
141 assert(m);
142 assert(bloom);
143
144 data = bloom->data;
145 memzero(data, m->bus->bloom_size);
146 bloom->generation = 0;
147
148 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
149
150 if (m->interface)
151 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
152 if (m->member)
153 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
154 if (m->path) {
155 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
156 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
157 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
158 }
159
160 r = sd_bus_message_rewind(m, true);
161 if (r < 0)
162 return r;
163
164 for (i = 0; i < 64; i++) {
165 char type;
166 const char *t;
167 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
168 char *e;
169
170 r = sd_bus_message_peek_type(m, &type, NULL);
171 if (r < 0)
172 return r;
173
174 if (type != SD_BUS_TYPE_STRING &&
175 type != SD_BUS_TYPE_OBJECT_PATH &&
176 type != SD_BUS_TYPE_SIGNATURE)
177 break;
178
179 r = sd_bus_message_read_basic(m, type, &t);
180 if (r < 0)
181 return r;
182
183 e = stpcpy(buf, "arg");
184 if (i < 10)
185 *(e++) = '0' + (char) i;
186 else {
187 *(e++) = '0' + (char) (i / 10);
188 *(e++) = '0' + (char) (i % 10);
189 }
190
191 *e = 0;
192 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
193
194 strcpy(e, "-dot-prefix");
195 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
196 strcpy(e, "-slash-prefix");
197 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
198 }
199
200 return 0;
201 }
202
203 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
204 struct bus_body_part *part;
205 struct kdbus_item *d;
206 bool well_known;
207 uint64_t unique;
208 size_t sz, dl;
209 unsigned i;
210 int r;
211
212 assert(b);
213 assert(m);
214 assert(m->sealed);
215
216 /* We put this together only once, if this message is reused
217 * we reuse the earlier-built version */
218 if (m->kdbus)
219 return 0;
220
221 if (m->destination) {
222 r = bus_kernel_parse_unique_name(m->destination, &unique);
223 if (r < 0)
224 return r;
225
226 well_known = r == 0;
227 } else
228 well_known = false;
229
230 sz = offsetof(struct kdbus_msg, items);
231
232 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
233 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
234
235 /* Add in fixed header, fields header and payload */
236 sz += (1 + m->n_body_parts) *
237 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
238
239 /* Add space for bloom filter */
240 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
241 offsetof(struct kdbus_bloom_filter, data) +
242 m->bus->bloom_size);
243
244 /* Add in well-known destination header */
245 if (well_known) {
246 dl = strlen(m->destination);
247 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
248 }
249
250 /* Add space for unix fds */
251 if (m->n_fds > 0)
252 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
253
254 m->kdbus = memalign(8, sz);
255 if (!m->kdbus) {
256 r = -ENOMEM;
257 goto fail;
258 }
259
260 m->free_kdbus = true;
261 memzero(m->kdbus, sz);
262
263 m->kdbus->flags =
264 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
265 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
266 m->kdbus->dst_id =
267 well_known ? 0 :
268 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
269 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
270 m->kdbus->cookie = (uint64_t) m->header->serial;
271 m->kdbus->priority = m->priority;
272
273 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) {
274 m->kdbus->cookie_reply = m->reply_cookie;
275 } else {
276 struct timespec now;
277
278 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
279 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
280 m->timeout * NSEC_PER_USEC;
281 }
282
283 d = m->kdbus->items;
284
285 if (well_known)
286 append_destination(&d, m->destination, dl);
287
288 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
289
290 MESSAGE_FOREACH_PART(part, i, m) {
291 if (part->is_zero) {
292 /* If this is padding then simply send a
293 * vector with a NULL data pointer which the
294 * kernel will just pass through. This is the
295 * most efficient way to encode zeroes */
296
297 append_payload_vec(&d, NULL, part->size);
298 continue;
299 }
300
301 if (part->memfd >= 0 && part->sealed && m->destination) {
302 /* Try to send a memfd, if the part is
303 * sealed and this is not a broadcast. Since we can only */
304
305 append_payload_memfd(&d, part->memfd, part->size);
306 continue;
307 }
308
309 /* Otherwise, let's send a vector to the actual data.
310 * For that, we need to map it first. */
311 r = bus_body_part_map(part);
312 if (r < 0)
313 goto fail;
314
315 append_payload_vec(&d, part->data, part->size);
316 }
317
318 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
319 struct kdbus_bloom_filter *bloom;
320
321 bloom = append_bloom(&d, m->bus->bloom_size);
322 r = bus_message_setup_bloom(m, bloom);
323 if (r < 0)
324 goto fail;
325 }
326
327 if (m->n_fds > 0)
328 append_fds(&d, m->fds, m->n_fds);
329
330 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
331 assert(m->kdbus->size <= sz);
332
333 return 0;
334
335 fail:
336 m->poisoned = true;
337 return r;
338 }
339
340 static void unset_memfds(struct sd_bus_message *m) {
341 struct bus_body_part *part;
342 unsigned i;
343
344 assert(m);
345
346 /* Make sure the memfds are not freed twice */
347 MESSAGE_FOREACH_PART(part, i, m)
348 if (part->memfd >= 0)
349 part->memfd = -1;
350 }
351
352 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
353 sd_bus_message *m = NULL;
354 struct kdbus_item *d;
355 unsigned n_fds = 0;
356 _cleanup_free_ int *fds = NULL;
357 struct bus_header *h = NULL;
358 size_t total, n_bytes = 0, idx = 0;
359 const char *destination = NULL, *seclabel = NULL;
360 int r;
361
362 assert(bus);
363 assert(k);
364 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
365
366 KDBUS_ITEM_FOREACH(d, k, items) {
367 size_t l;
368
369 l = d->size - offsetof(struct kdbus_item, data);
370
371 switch (d->type) {
372
373 case KDBUS_ITEM_PAYLOAD_OFF:
374 if (!h) {
375 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
376
377 if (!bus_header_is_complete(h, d->vec.size))
378 return -EBADMSG;
379 }
380
381 n_bytes += d->vec.size;
382 break;
383
384 case KDBUS_ITEM_PAYLOAD_MEMFD:
385 if (!h)
386 return -EBADMSG;
387
388 n_bytes += d->memfd.size;
389 break;
390
391 case KDBUS_ITEM_FDS: {
392 int *f;
393 unsigned j;
394
395 j = l / sizeof(int);
396 f = realloc(fds, sizeof(int) * (n_fds + j));
397 if (!f)
398 return -ENOMEM;
399
400 fds = f;
401 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
402 n_fds += j;
403 break;
404 }
405
406 case KDBUS_ITEM_SECLABEL:
407 seclabel = d->str;
408 break;
409 }
410 }
411
412 if (!h)
413 return -EBADMSG;
414
415 r = bus_header_message_size(h, &total);
416 if (r < 0)
417 return r;
418
419 if (n_bytes != total)
420 return -EBADMSG;
421
422 /* on kdbus we only speak native endian gvariant, never dbus1
423 * marshalling or reverse endian */
424 if (h->version != 2 ||
425 h->endian != BUS_NATIVE_ENDIAN)
426 return -EPROTOTYPE;
427
428 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
429 if (r < 0)
430 return r;
431
432 /* The well-known names list is different from the other
433 credentials. If we asked for it, but nothing is there, this
434 means that the list of well-known names is simply empty, not
435 that we lack any data */
436
437 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
438
439 KDBUS_ITEM_FOREACH(d, k, items) {
440 size_t l;
441
442 l = d->size - offsetof(struct kdbus_item, data);
443
444 switch (d->type) {
445
446 case KDBUS_ITEM_PAYLOAD_OFF: {
447 size_t begin_body;
448
449 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
450
451 if (idx + d->vec.size > begin_body) {
452 struct bus_body_part *part;
453
454 /* Contains body material */
455
456 part = message_append_part(m);
457 if (!part) {
458 r = -ENOMEM;
459 goto fail;
460 }
461
462 /* A -1 offset is NUL padding. */
463 part->is_zero = d->vec.offset == ~0ULL;
464
465 if (idx >= begin_body) {
466 if (!part->is_zero)
467 part->data = (uint8_t *)k + d->vec.offset;
468 part->size = d->vec.size;
469 } else {
470 if (!part->is_zero)
471 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
472 part->size = d->vec.size - (begin_body - idx);
473 }
474
475 part->sealed = true;
476 }
477
478 idx += d->vec.size;
479 break;
480 }
481
482 case KDBUS_ITEM_PAYLOAD_MEMFD: {
483 struct bus_body_part *part;
484
485 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
486 r = -EBADMSG;
487 goto fail;
488 }
489
490 part = message_append_part(m);
491 if (!part) {
492 r = -ENOMEM;
493 goto fail;
494 }
495
496 part->memfd = d->memfd.fd;
497 part->size = d->memfd.size;
498 part->sealed = true;
499
500 idx += d->memfd.size;
501 break;
502 }
503
504 case KDBUS_ITEM_CREDS:
505 /* UID/GID/PID are always valid */
506 m->creds.uid = (uid_t) d->creds.uid;
507 m->creds.gid = (gid_t) d->creds.gid;
508 m->creds.pid = (pid_t) d->creds.pid;
509 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
510
511 /* The PID starttime/TID might be missing
512 * however, when the data is faked by some
513 * data bus proxy and it lacks that
514 * information about the real client since
515 * SO_PEERCRED is used for that */
516
517 if (d->creds.starttime > 0) {
518 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
519 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
520 }
521
522 if (d->creds.tid > 0) {
523 m->creds.tid = (pid_t) d->creds.tid;
524 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
525 }
526 break;
527
528 case KDBUS_ITEM_TIMESTAMP:
529
530 if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
531 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
532 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
533 m->seqnum = d->timestamp.seqnum;
534 }
535
536 break;
537
538 case KDBUS_ITEM_PID_COMM:
539 m->creds.comm = d->str;
540 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
541 break;
542
543 case KDBUS_ITEM_TID_COMM:
544 m->creds.tid_comm = d->str;
545 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
546 break;
547
548 case KDBUS_ITEM_EXE:
549 m->creds.exe = d->str;
550 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
551 break;
552
553 case KDBUS_ITEM_CMDLINE:
554 m->creds.cmdline = d->str;
555 m->creds.cmdline_size = l;
556 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
557 break;
558
559 case KDBUS_ITEM_CGROUP:
560 m->creds.cgroup = d->str;
561 m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask;
562
563 r = bus_get_root_path(bus);
564 if (r < 0)
565 goto fail;
566
567 m->creds.cgroup_root = bus->cgroup_root;
568
569 break;
570
571 case KDBUS_ITEM_AUDIT:
572 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
573 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
574 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
575 break;
576
577 case KDBUS_ITEM_CAPS:
578 m->creds.capability = d->data;
579 m->creds.capability_size = l;
580 m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask;
581 break;
582
583 case KDBUS_ITEM_DST_NAME:
584 if (!service_name_is_valid(d->str))
585 return -EBADMSG;
586
587 destination = d->str;
588 break;
589
590 case KDBUS_ITEM_NAME:
591 if (!service_name_is_valid(d->name.name))
592 return -EBADMSG;
593
594 r = strv_extend(&m->creds.well_known_names, d->name.name);
595 if (r < 0)
596 goto fail;
597 break;
598
599 case KDBUS_ITEM_CONN_NAME:
600 m->creds.conn_name = d->str;
601 m->creds.mask |= SD_BUS_CREDS_CONNECTION_NAME & bus->creds_mask;
602 break;
603
604 case KDBUS_ITEM_FDS:
605 case KDBUS_ITEM_SECLABEL:
606 break;
607
608 default:
609 log_debug("Got unknown field from kernel %llu", d->type);
610 }
611 }
612
613 r = bus_message_parse_fields(m);
614 if (r < 0)
615 goto fail;
616
617 /* Override information from the user header with data from the kernel */
618 if (k->src_id == KDBUS_SRC_ID_KERNEL)
619 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
620 else {
621 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
622 m->sender = m->creds.unique_name = m->sender_buffer;
623 }
624
625 if (destination)
626 m->destination = destination;
627 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
628 m->destination = NULL;
629 else if (k->dst_id == KDBUS_DST_ID_NAME)
630 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
631 else {
632 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
633 m->destination = m->destination_buffer;
634 }
635
636 /* We take possession of the kmsg struct now */
637 m->kdbus = k;
638 m->release_kdbus = true;
639 m->free_fds = true;
640 fds = NULL;
641
642 bus->rqueue[bus->rqueue_size++] = m;
643
644 return 1;
645
646 fail:
647 unset_memfds(m);
648 sd_bus_message_unref(m);
649
650 return r;
651 }
652
653 int bus_kernel_take_fd(sd_bus *b) {
654 struct kdbus_cmd_hello *hello;
655 struct kdbus_item *item;
656 _cleanup_free_ char *g = NULL;
657 const char *name;
658 size_t l = 0, m = 0, sz;
659 int r;
660
661 assert(b);
662
663 if (b->is_server)
664 return -EINVAL;
665
666 b->use_memfd = 1;
667
668 if (b->connection_name) {
669 g = bus_label_escape(b->connection_name);
670 if (!g)
671 return -ENOMEM;
672
673 name = g;
674 } else {
675 char pr[17] = {};
676
677 /* If no name is explicitly set, we'll include a hint
678 * indicating the library implementation, a hint which
679 * kind of bus this is and the thread name */
680
681 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
682
683 if (isempty(pr)) {
684 name = b->is_system ? "sd-system" :
685 b->is_user ? "sd-user" : "sd";
686 } else {
687 _cleanup_free_ char *e = NULL;
688
689 e = bus_label_escape(pr);
690 if (!e)
691 return -ENOMEM;
692
693 g = strappend(b->is_system ? "sd-system-" :
694 b->is_user ? "sd-user-" : "sd-",
695 e);
696 if (!g)
697 return -ENOMEM;
698
699 name = g;
700 }
701
702 b->connection_name = bus_label_unescape(name);
703 if (!b->connection_name)
704 return -ENOMEM;
705 }
706
707 m = strlen(name);
708
709 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
710 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
711
712 if (b->fake_creds_valid)
713 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
714
715 if (b->fake_label) {
716 l = strlen(b->fake_label);
717 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
718 }
719
720 hello = alloca0_align(sz, 8);
721 hello->size = sz;
722 hello->flags = b->hello_flags;
723 hello->attach_flags = b->attach_flags;
724 hello->pool_size = KDBUS_POOL_SIZE;
725
726 item = hello->items;
727
728 item->size = offsetof(struct kdbus_item, str) + m + 1;
729 item->type = KDBUS_ITEM_CONN_NAME;
730 memcpy(item->str, name, m + 1);
731 item = KDBUS_ITEM_NEXT(item);
732
733 if (b->fake_creds_valid) {
734 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
735 item->type = KDBUS_ITEM_CREDS;
736 item->creds = b->fake_creds;
737
738 item = KDBUS_ITEM_NEXT(item);
739 }
740
741 if (b->fake_label) {
742 item->size = offsetof(struct kdbus_item, str) + l + 1;
743 item->type = KDBUS_ITEM_SECLABEL;
744 memcpy(item->str, b->fake_label, l+1);
745 }
746
747 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
748 if (r < 0)
749 return -errno;
750
751 if (!b->kdbus_buffer) {
752 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
753 if (b->kdbus_buffer == MAP_FAILED) {
754 b->kdbus_buffer = NULL;
755 return -errno;
756 }
757 }
758
759 /* The higher 32bit of the bus_flags fields are considered
760 * 'incompatible flags'. Refuse them all for now. */
761 if (hello->bus_flags > 0xFFFFFFFFULL)
762 return -ENOTSUP;
763
764 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
765 return -ENOTSUP;
766
767 b->bloom_size = (size_t) hello->bloom.size;
768 b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
769
770 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
771 return -ENOMEM;
772
773 b->unique_id = hello->id;
774
775 b->is_kernel = true;
776 b->bus_client = true;
777 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
778 b->message_version = 2;
779 b->message_endian = BUS_NATIVE_ENDIAN;
780
781 /* the kernel told us the UUID of the underlying bus */
782 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
783
784 return bus_start_running(b);
785 }
786
787 int bus_kernel_connect(sd_bus *b) {
788 assert(b);
789 assert(b->input_fd < 0);
790 assert(b->output_fd < 0);
791 assert(b->kernel);
792
793 if (b->is_server)
794 return -EINVAL;
795
796 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
797 if (b->input_fd < 0)
798 return -errno;
799
800 b->output_fd = b->input_fd;
801
802 return bus_kernel_take_fd(b);
803 }
804
805 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
806 struct kdbus_cmd_free cmd;
807 struct kdbus_item *d;
808
809 assert(bus);
810 assert(k);
811
812 cmd.flags = 0;
813 cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
814
815 KDBUS_ITEM_FOREACH(d, k, items) {
816
817 if (d->type == KDBUS_ITEM_FDS)
818 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
819 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
820 safe_close(d->memfd.fd);
821 }
822
823 (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
824 }
825
826 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
827 int r;
828
829 assert(bus);
830 assert(m);
831 assert(bus->state == BUS_RUNNING);
832
833 /* If we can't deliver, we want room for the error message */
834 r = bus_rqueue_make_room(bus);
835 if (r < 0)
836 return r;
837
838 r = bus_message_setup_kmsg(bus, m);
839 if (r < 0)
840 return r;
841
842 /* If this is a synchronous method call, then let's tell the
843 * kernel, so that it can pass CPU time/scheduling to the
844 * destination for the time, if it wants to. If we
845 * synchronously wait for the result anyway, we won't need CPU
846 * anyway. */
847 if (hint_sync_call)
848 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
849
850 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
851 if (r < 0) {
852 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
853 sd_bus_message *reply;
854
855 if (errno == EAGAIN || errno == EINTR)
856 return 0;
857 else if (errno == ENXIO || errno == ESRCH) {
858
859 /* ENXIO: unique name not known
860 * ESRCH: well-known name not known */
861
862 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
863 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
864 else {
865 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
866 return 0;
867 }
868
869 } else if (errno == EADDRNOTAVAIL) {
870
871 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
872
873 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
874 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
875 else {
876 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
877 return 0;
878 }
879 } else
880 return -errno;
881
882 r = bus_message_new_synthetic_error(
883 bus,
884 BUS_MESSAGE_COOKIE(m),
885 &error,
886 &reply);
887
888 if (r < 0)
889 return r;
890
891 r = bus_seal_synthetic_message(bus, reply);
892 if (r < 0)
893 return r;
894
895 bus->rqueue[bus->rqueue_size++] = reply;
896
897 } else if (hint_sync_call) {
898 struct kdbus_msg *k;
899
900 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
901 assert(k);
902
903 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
904
905 r = bus_kernel_make_message(bus, k);
906 if (r < 0) {
907 close_kdbus_msg(bus, k);
908
909 /* Anybody can send us invalid messages, let's just drop them. */
910 if (r == -EBADMSG || r == -EPROTOTYPE)
911 log_debug("Ignoring invalid message: %s", strerror(-r));
912 else
913 return r;
914 }
915 } else {
916 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
917 close_kdbus_msg(bus, k);
918 }
919 }
920
921 return 1;
922 }
923
924 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
925 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
926 int r;
927
928 assert(bus);
929
930 r = sd_bus_message_new_signal(
931 bus,
932 &m,
933 "/org/freedesktop/DBus",
934 "org.freedesktop.DBus",
935 "NameOwnerChanged");
936 if (r < 0)
937 return r;
938
939 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
940 if (r < 0)
941 return r;
942
943 m->sender = "org.freedesktop.DBus";
944
945 r = bus_seal_synthetic_message(bus, m);
946 if (r < 0)
947 return r;
948
949 bus->rqueue[bus->rqueue_size++] = m;
950 m = NULL;
951
952 return 1;
953 }
954
955 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
956 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
957
958 assert(bus);
959 assert(k);
960 assert(d);
961
962 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
963 old_owner[0] = 0;
964 else
965 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
966
967 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
968
969 if (isempty(old_owner))
970 return 0;
971
972 new_owner[0] = 0;
973 } else
974 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
975
976 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
977 }
978
979 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
980 char owner[UNIQUE_NAME_MAX];
981
982 assert(bus);
983 assert(k);
984 assert(d);
985
986 sprintf(owner, ":1.%llu", d->id_change.id);
987
988 return push_name_owner_changed(
989 bus, owner,
990 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
991 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
992 }
993
994 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
995 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
996 int r;
997
998 assert(bus);
999 assert(k);
1000 assert(d);
1001
1002 r = bus_message_new_synthetic_error(
1003 bus,
1004 k->cookie_reply,
1005 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1006 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1007 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1008 &m);
1009 if (r < 0)
1010 return r;
1011
1012 m->sender = "org.freedesktop.DBus";
1013
1014 r = bus_seal_synthetic_message(bus, m);
1015 if (r < 0)
1016 return r;
1017
1018 bus->rqueue[bus->rqueue_size++] = m;
1019 m = NULL;
1020
1021 return 1;
1022 }
1023
1024 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1025 struct kdbus_item *d, *found = NULL;
1026
1027 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1028 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1029 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1030 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1031
1032 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1033 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1034
1035 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1036 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1037 };
1038
1039 assert(bus);
1040 assert(k);
1041 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1042
1043 KDBUS_ITEM_FOREACH(d, k, items) {
1044 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1045 if (found)
1046 return -EBADMSG;
1047 found = d;
1048 } else
1049 log_debug("Got unknown field from kernel %llu", d->type);
1050 }
1051
1052 if (!found) {
1053 log_debug("Didn't find a kernel message to translate.");
1054 return 0;
1055 }
1056
1057 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
1058 }
1059
1060 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1061 struct kdbus_cmd_recv recv = {};
1062 struct kdbus_msg *k;
1063 int r;
1064
1065 assert(bus);
1066
1067 r = bus_rqueue_make_room(bus);
1068 if (r < 0)
1069 return r;
1070
1071 if (hint_priority) {
1072 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1073 recv.priority = priority;
1074 }
1075
1076 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1077 if (r < 0) {
1078 if (errno == EAGAIN)
1079 return 0;
1080
1081 return -errno;
1082 }
1083
1084 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1085 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1086 r = bus_kernel_make_message(bus, k);
1087
1088 /* Anybody can send us invalid messages, let's just drop them. */
1089 if (r == -EBADMSG || r == -EPROTOTYPE) {
1090 log_debug("Ignoring invalid message: %s", strerror(-r));
1091 r = 0;
1092 }
1093
1094 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1095 r = bus_kernel_translate_message(bus, k);
1096 else {
1097 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1098 r = 0;
1099 }
1100
1101 if (r <= 0)
1102 close_kdbus_msg(bus, k);
1103
1104 return r < 0 ? r : 1;
1105 }
1106
1107 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1108 struct memfd_cache *c;
1109 int fd;
1110
1111 assert(address);
1112 assert(mapped);
1113 assert(allocated);
1114
1115 if (!bus || !bus->is_kernel)
1116 return -ENOTSUP;
1117
1118 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1119
1120 if (bus->n_memfd_cache <= 0) {
1121 _cleanup_free_ char *g = NULL;
1122 int r;
1123
1124 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1125
1126 assert(bus->connection_name);
1127
1128 g = bus_label_escape(bus->connection_name);
1129 if (!g)
1130 return -ENOMEM;
1131
1132 r = memfd_create(g, MFD_ALLOW_SEALING);
1133 if (r < 0)
1134 return -errno;
1135
1136 *address = NULL;
1137 *mapped = 0;
1138 *allocated = 0;
1139 return r;
1140 }
1141
1142 c = &bus->memfd_cache[--bus->n_memfd_cache];
1143
1144 assert(c->fd >= 0);
1145 assert(c->mapped == 0 || c->address);
1146
1147 *address = c->address;
1148 *mapped = c->mapped;
1149 *allocated = c->allocated;
1150 fd = c->fd;
1151
1152 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1153
1154 return fd;
1155 }
1156
1157 static void close_and_munmap(int fd, void *address, size_t size) {
1158 if (size > 0)
1159 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1160
1161 safe_close(fd);
1162 }
1163
1164 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1165 struct memfd_cache *c;
1166 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1167
1168 assert(fd >= 0);
1169 assert(mapped == 0 || address);
1170
1171 if (!bus || !bus->is_kernel) {
1172 close_and_munmap(fd, address, mapped);
1173 return;
1174 }
1175
1176 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1177
1178 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1179 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1180
1181 close_and_munmap(fd, address, mapped);
1182 return;
1183 }
1184
1185 c = &bus->memfd_cache[bus->n_memfd_cache++];
1186 c->fd = fd;
1187 c->address = address;
1188
1189 /* If overly long, let's return a bit to the OS */
1190 if (mapped > max_mapped) {
1191 assert_se(ftruncate(fd, max_mapped) >= 0);
1192 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1193 c->mapped = c->allocated = max_mapped;
1194 } else {
1195 c->mapped = mapped;
1196 c->allocated = allocated;
1197 }
1198
1199 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1200 }
1201
1202 void bus_kernel_flush_memfd(sd_bus *b) {
1203 unsigned i;
1204
1205 assert(b);
1206
1207 for (i = 0; i < b->n_memfd_cache; i++)
1208 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1209 }
1210
1211 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1212 uint64_t f = 0;
1213
1214 assert(kdbus_flags);
1215
1216 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1217 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1218
1219 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1220 f |= KDBUS_NAME_REPLACE_EXISTING;
1221
1222 if (flags & SD_BUS_NAME_QUEUE)
1223 f |= KDBUS_NAME_QUEUE;
1224
1225 *kdbus_flags = f;
1226 return 0;
1227 }
1228
1229 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1230 uint64_t m = 0;
1231
1232 assert(kdbus_mask);
1233
1234 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1235 m |= KDBUS_ATTACH_CREDS;
1236
1237 if (mask & SD_BUS_CREDS_COMM)
1238 m |= KDBUS_ATTACH_PID_COMM;
1239
1240 if (mask & SD_BUS_CREDS_TID_COMM)
1241 m |= KDBUS_ATTACH_TID_COMM;
1242
1243 if (mask & SD_BUS_CREDS_EXE)
1244 m |= KDBUS_ATTACH_EXE;
1245
1246 if (mask & SD_BUS_CREDS_CMDLINE)
1247 m |= KDBUS_ATTACH_CMDLINE;
1248
1249 if (mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID))
1250 m |= KDBUS_ATTACH_CGROUP;
1251
1252 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1253 m |= KDBUS_ATTACH_CAPS;
1254
1255 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1256 m |= KDBUS_ATTACH_SECLABEL;
1257
1258 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1259 m |= KDBUS_ATTACH_AUDIT;
1260
1261 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1262 m |= KDBUS_ATTACH_NAMES;
1263
1264 if (mask & SD_BUS_CREDS_CONNECTION_NAME)
1265 m |= KDBUS_ATTACH_CONN_NAME;
1266
1267 *kdbus_mask = m;
1268 return 0;
1269 }
1270
1271 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1272 struct kdbus_cmd_make *make;
1273 struct kdbus_item *n;
1274 int fd;
1275
1276 assert(name);
1277 assert(s);
1278
1279 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1280 if (fd < 0)
1281 return -errno;
1282
1283 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1284 offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1285 offsetof(struct kdbus_item, str) +
1286 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
1287 8);
1288
1289 make->size = offsetof(struct kdbus_cmd_make, items);
1290
1291 n = make->items;
1292 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1293 sizeof(struct kdbus_bloom_parameter);
1294 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1295
1296 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1297 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1298
1299 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1300 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1301
1302 make->size += ALIGN8(n->size);
1303
1304 n = KDBUS_ITEM_NEXT(n);
1305 sprintf(n->str, UID_FMT "-%s", getuid(), name);
1306 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1307 n->type = KDBUS_ITEM_MAKE_NAME;
1308 make->size += ALIGN8(n->size);
1309
1310 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1311
1312 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1313 safe_close(fd);
1314 return -errno;
1315 }
1316
1317 if (s) {
1318 char *p;
1319
1320 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1321 if (!p) {
1322 safe_close(fd);
1323 return -ENOMEM;
1324 }
1325
1326 *s = p;
1327 }
1328
1329 return fd;
1330 }
1331
1332 static int bus_kernel_translate_access(BusPolicyAccess access) {
1333 assert(access >= 0);
1334 assert(access < _BUS_POLICY_ACCESS_MAX);
1335
1336 switch (access) {
1337
1338 case BUS_POLICY_ACCESS_SEE:
1339 return KDBUS_POLICY_SEE;
1340
1341 case BUS_POLICY_ACCESS_TALK:
1342 return KDBUS_POLICY_TALK;
1343
1344 case BUS_POLICY_ACCESS_OWN:
1345 return KDBUS_POLICY_OWN;
1346
1347 default:
1348 assert_not_reached("Unknown policy access");
1349 }
1350 }
1351
1352 static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
1353 int r;
1354
1355 assert(policy);
1356 assert(item);
1357
1358 switch (policy->type) {
1359
1360 case BUSNAME_POLICY_TYPE_USER: {
1361 const char *user = policy->name;
1362 uid_t uid;
1363
1364 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
1365 if (r < 0)
1366 return r;
1367
1368 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1369 item->policy_access.id = uid;
1370 break;
1371 }
1372
1373 case BUSNAME_POLICY_TYPE_GROUP: {
1374 const char *group = policy->name;
1375 gid_t gid;
1376
1377 r = get_group_creds(&group, &gid);
1378 if (r < 0)
1379 return r;
1380
1381 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1382 item->policy_access.id = gid;
1383 break;
1384 }
1385
1386 default:
1387 assert_not_reached("Unknown policy type");
1388 }
1389
1390 item->policy_access.access = bus_kernel_translate_access(policy->access);
1391
1392 return 0;
1393 }
1394
1395 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1396 char *p;
1397 int fd;
1398 size_t len;
1399
1400 len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1401
1402 if (path) {
1403 p = malloc(len);
1404 if (!p)
1405 return -ENOMEM;
1406 *path = p;
1407 } else
1408 p = alloca(len);
1409 sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1410
1411 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1412 if (fd < 0)
1413 return -errno;
1414
1415 return fd;
1416 }
1417
1418 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1419 _cleanup_free_ char *path = NULL;
1420 struct kdbus_cmd_make *make;
1421 struct kdbus_item *n;
1422 size_t size;
1423 int fd;
1424
1425 fd = bus_kernel_open_bus_fd(bus_name, &path);
1426 if (fd < 0)
1427 return fd;
1428
1429 size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1430 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
1431
1432 make = alloca0_align(size, 8);
1433 make->size = size;
1434 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1435
1436 n = make->items;
1437
1438 n->type = KDBUS_ITEM_MAKE_NAME;
1439 n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1;
1440 strcpy(n->str, ep_name);
1441
1442 if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1443 safe_close(fd);
1444 return -errno;
1445 }
1446
1447 if (ep_path) {
1448 char *p;
1449
1450 p = strjoin(dirname(path), "/", ep_name, NULL);
1451 if (!p) {
1452 safe_close(fd);
1453 return -ENOMEM;
1454 }
1455
1456 *ep_path = p;
1457 }
1458
1459 return fd;
1460 }
1461
1462 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
1463
1464 struct kdbus_cmd_update *update;
1465 struct kdbus_item *n;
1466 BusEndpointPolicy *po;
1467 Iterator i;
1468 size_t size;
1469 int r;
1470
1471 size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
1472
1473 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1474 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
1475 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1476 }
1477
1478 update = alloca0_align(size, 8);
1479 update->size = size;
1480
1481 n = update->items;
1482
1483 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1484 n->type = KDBUS_ITEM_NAME;
1485 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
1486 strcpy(n->str, po->name);
1487 n = KDBUS_ITEM_NEXT(n);
1488
1489 n->type = KDBUS_ITEM_POLICY_ACCESS;
1490 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1491
1492 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1493 n->policy_access.access = bus_kernel_translate_access(po->access);
1494 n->policy_access.id = uid;
1495
1496 n = KDBUS_ITEM_NEXT(n);
1497 }
1498
1499 r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
1500 if (r < 0)
1501 return -errno;
1502
1503 return 0;
1504 }
1505
1506 int bus_kernel_make_starter(
1507 int fd,
1508 const char *name,
1509 bool activating,
1510 bool accept_fd,
1511 BusNamePolicy *policy,
1512 BusPolicyAccess world_policy) {
1513
1514 struct kdbus_cmd_hello *hello;
1515 struct kdbus_item *n;
1516 size_t policy_cnt = 0;
1517 BusNamePolicy *po;
1518 size_t size;
1519 int r;
1520
1521 assert(fd >= 0);
1522 assert(name);
1523
1524 LIST_FOREACH(policy, po, policy)
1525 policy_cnt++;
1526
1527 if (world_policy >= 0)
1528 policy_cnt++;
1529
1530 size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1531 ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1532 policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1533
1534 hello = alloca0_align(size, 8);
1535
1536 n = hello->items;
1537 strcpy(n->str, name);
1538 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1539 n->type = KDBUS_ITEM_NAME;
1540 n = KDBUS_ITEM_NEXT(n);
1541
1542 LIST_FOREACH(policy, po, policy) {
1543 n->type = KDBUS_ITEM_POLICY_ACCESS;
1544 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1545
1546 r = bus_kernel_translate_policy(po, n);
1547 if (r < 0)
1548 return r;
1549
1550 n = KDBUS_ITEM_NEXT(n);
1551 }
1552
1553 if (world_policy >= 0) {
1554 n->type = KDBUS_ITEM_POLICY_ACCESS;
1555 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1556 n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1557 n->policy_access.access = bus_kernel_translate_access(world_policy);
1558 }
1559
1560 hello->size = size;
1561 hello->flags =
1562 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1563 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
1564 hello->pool_size = KDBUS_POOL_SIZE;
1565 hello->attach_flags = _KDBUS_ATTACH_ALL;
1566
1567 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
1568 return -errno;
1569
1570 /* The higher 32bit of the bus_flags fields are considered
1571 * 'incompatible flags'. Refuse them all for now. */
1572 if (hello->bus_flags > 0xFFFFFFFFULL)
1573 return -ENOTSUP;
1574
1575 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
1576 return -ENOTSUP;
1577
1578 return fd;
1579 }
1580
1581 int bus_kernel_create_domain(const char *name, char **s) {
1582 struct kdbus_cmd_make *make;
1583 struct kdbus_item *n;
1584 int fd;
1585
1586 assert(name);
1587 assert(s);
1588
1589 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1590 if (fd < 0)
1591 return -errno;
1592
1593 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1594 offsetof(struct kdbus_item, str) +
1595 strlen(name) + 1),
1596 8);
1597
1598 n = make->items;
1599 strcpy(n->str, name);
1600 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1601 n->type = KDBUS_ITEM_MAKE_NAME;
1602
1603 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1604 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1605
1606 if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
1607 safe_close(fd);
1608 return -errno;
1609 }
1610
1611 /* The higher 32bit of the flags field are considered
1612 * 'incompatible flags'. Refuse them all for now. */
1613 if (make->flags > 0xFFFFFFFFULL) {
1614 safe_close(fd);
1615 return -ENOTSUP;
1616 }
1617
1618 if (s) {
1619 char *p;
1620
1621 p = strappend("/dev/kdbus/domain/", name);
1622 if (!p) {
1623 safe_close(fd);
1624 return -ENOMEM;
1625 }
1626
1627 *s = p;
1628 }
1629
1630 return fd;
1631 }
1632
1633 int bus_kernel_try_close(sd_bus *bus) {
1634 assert(bus);
1635 assert(bus->is_kernel);
1636
1637 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1638 return -errno;
1639
1640 return 0;
1641 }
1642
1643 int bus_kernel_drop_one(int fd) {
1644 struct kdbus_cmd_recv recv = {
1645 .flags = KDBUS_RECV_DROP
1646 };
1647
1648 assert(fd >= 0);
1649
1650 if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1651 return -errno;
1652
1653 return 0;
1654 }