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