]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-bus/bus-kernel.c
nspawn: set up a kdbus namespace when starting a container
[thirdparty/systemd.git] / src / libsystemd-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 <sys/mman.h>
29
30 #include "util.h"
31
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-kernel.h"
35 #include "bus-bloom.h"
36 #include "bus-util.h"
37
38 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
39
40 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
41 int r;
42
43 assert(s);
44 assert(id);
45
46 if (!startswith(s, ":1."))
47 return 0;
48
49 r = safe_atou64(s + 3, id);
50 if (r < 0)
51 return r;
52
53 return 1;
54 }
55
56 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
57 assert(d);
58 assert(sz > 0);
59
60 *d = ALIGN8_PTR(*d);
61
62 /* Note that p can be NULL, which encodes a region full of
63 * zeroes, which is useful to optimize certain padding
64 * conditions */
65
66 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
67 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
68 (*d)->vec.address = PTR_TO_UINT64(p);
69 (*d)->vec.size = sz;
70
71 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
72 }
73
74 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
75 assert(d);
76 assert(memfd >= 0);
77 assert(sz > 0);
78
79 *d = ALIGN8_PTR(*d);
80 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
81 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
82 (*d)->memfd.fd = memfd;
83 (*d)->memfd.size = sz;
84
85 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
86 }
87
88 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
89 assert(d);
90 assert(s);
91
92 *d = ALIGN8_PTR(*d);
93
94 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
95 (*d)->type = KDBUS_ITEM_DST_NAME;
96 memcpy((*d)->str, s, length + 1);
97
98 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
99 }
100
101 static void* append_bloom(struct kdbus_item **d, size_t length) {
102 void *r;
103
104 assert(d);
105
106 *d = ALIGN8_PTR(*d);
107
108 (*d)->size = offsetof(struct kdbus_item, data) + length;
109 (*d)->type = KDBUS_ITEM_BLOOM;
110 r = (*d)->data;
111
112 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
113
114 return r;
115 }
116
117 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
118 assert(d);
119 assert(fds);
120 assert(n_fds > 0);
121
122 *d = ALIGN8_PTR(*d);
123 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
124 (*d)->type = KDBUS_ITEM_FDS;
125 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
126
127 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
128 }
129
130 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
131 unsigned i;
132 int r;
133
134 assert(m);
135 assert(bloom);
136
137 memset(bloom, 0, BLOOM_SIZE);
138
139 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
140
141 if (m->interface)
142 bloom_add_pair(bloom, "interface", m->interface);
143 if (m->member)
144 bloom_add_pair(bloom, "member", m->member);
145 if (m->path) {
146 bloom_add_pair(bloom, "path", m->path);
147 bloom_add_pair(bloom, "path-slash-prefix", m->path);
148 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
149 }
150
151 r = sd_bus_message_rewind(m, true);
152 if (r < 0)
153 return r;
154
155 for (i = 0; i < 64; i++) {
156 char type;
157 const char *t;
158 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
159 char *e;
160
161 r = sd_bus_message_peek_type(m, &type, NULL);
162 if (r < 0)
163 return r;
164
165 if (type != SD_BUS_TYPE_STRING &&
166 type != SD_BUS_TYPE_OBJECT_PATH &&
167 type != SD_BUS_TYPE_SIGNATURE)
168 break;
169
170 r = sd_bus_message_read_basic(m, type, &t);
171 if (r < 0)
172 return r;
173
174 e = stpcpy(buf, "arg");
175 if (i < 10)
176 *(e++) = '0' + i;
177 else {
178 *(e++) = '0' + (i / 10);
179 *(e++) = '0' + (i % 10);
180 }
181
182 *e = 0;
183 bloom_add_pair(bloom, buf, t);
184
185 strcpy(e, "-dot-prefix");
186 bloom_add_prefixes(bloom, buf, t, '.');
187 strcpy(e, "-slash-prefix");
188 bloom_add_prefixes(bloom, buf, t, '/');
189 }
190
191 return 0;
192 }
193
194 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
195 struct bus_body_part *part;
196 struct kdbus_item *d;
197 bool well_known;
198 uint64_t unique;
199 size_t sz, dl;
200 unsigned i;
201 int r;
202
203 assert(b);
204 assert(m);
205 assert(m->sealed);
206
207 if (m->kdbus)
208 return 0;
209
210 if (m->destination) {
211 r = bus_kernel_parse_unique_name(m->destination, &unique);
212 if (r < 0)
213 return r;
214
215 well_known = r == 0;
216 } else
217 well_known = false;
218
219 sz = offsetof(struct kdbus_msg, items);
220
221 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
222 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
223
224 /* Add in fixed header, fields header and payload */
225 sz += (1 + m->n_body_parts) *
226 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
227
228 /* Add space for bloom filter */
229 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
230
231 /* Add in well-known destination header */
232 if (well_known) {
233 dl = strlen(m->destination);
234 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
235 }
236
237 /* Add space for unix fds */
238 if (m->n_fds > 0)
239 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
240
241 m->kdbus = memalign(8, sz);
242 if (!m->kdbus) {
243 r = -ENOMEM;
244 goto fail;
245 }
246
247 m->free_kdbus = true;
248 memset(m->kdbus, 0, sz);
249
250 m->kdbus->flags =
251 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
252 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
253 m->kdbus->dst_id =
254 well_known ? 0 :
255 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
256 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
257 m->kdbus->cookie = m->header->serial;
258
259 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
260
261 d = m->kdbus->items;
262
263 if (well_known)
264 append_destination(&d, m->destination, dl);
265
266 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
267
268 MESSAGE_FOREACH_PART(part, i, m) {
269 if (part->is_zero) {
270 /* If this is padding then simply send a
271 * vector with a NULL data pointer which the
272 * kernel will just pass through. This is the
273 * most efficient way to encode zeroes */
274
275 append_payload_vec(&d, NULL, part->size);
276 continue;
277 }
278
279 if (part->memfd >= 0 && part->sealed && m->destination) {
280 /* Try to send a memfd, if the part is
281 * sealed and this is not a broadcast. Since we can only */
282
283 append_payload_memfd(&d, part->memfd, part->size);
284 continue;
285 }
286
287 /* Otherwise let's send a vector to the actual data,
288 * for that we need to map it first. */
289 r = bus_body_part_map(part);
290 if (r < 0)
291 goto fail;
292
293 append_payload_vec(&d, part->data, part->size);
294 }
295
296 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
297 void *p;
298
299 p = append_bloom(&d, BLOOM_SIZE);
300 r = bus_message_setup_bloom(m, p);
301 if (r < 0)
302 goto fail;
303 }
304
305 if (m->n_fds > 0)
306 append_fds(&d, m->fds, m->n_fds);
307
308 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
309 assert(m->kdbus->size <= sz);
310
311 return 0;
312
313 fail:
314 m->poisoned = true;
315 return r;
316 }
317
318 int bus_kernel_take_fd(sd_bus *b) {
319 struct kdbus_cmd_hello hello;
320 int r;
321
322 assert(b);
323
324 if (b->is_server)
325 return -EINVAL;
326
327 b->use_memfd = 1;
328
329 zero(hello);
330 hello.size = sizeof(hello);
331 hello.conn_flags = b->hello_flags;
332 hello.attach_flags = b->attach_flags;
333 hello.pool_size = KDBUS_POOL_SIZE;
334
335 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
336 if (r < 0)
337 return -errno;
338
339 if (!b->kdbus_buffer) {
340 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
341 if (b->kdbus_buffer == MAP_FAILED) {
342 b->kdbus_buffer = NULL;
343 return -errno;
344 }
345 }
346
347 /* The higher 32bit of both flags fields are considered
348 * 'incompatible flags'. Refuse them all for now. */
349 if (hello.bus_flags > 0xFFFFFFFFULL ||
350 hello.conn_flags > 0xFFFFFFFFULL)
351 return -ENOTSUP;
352
353 if (hello.bloom_size != BLOOM_SIZE)
354 return -ENOTSUP;
355
356 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
357 return -ENOMEM;
358
359 b->unique_id = hello.id;
360
361 b->is_kernel = true;
362 b->bus_client = true;
363 b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
364
365 /* the kernel told us the UUID of the underlying bus */
366 memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
367
368 return bus_start_running(b);
369 }
370
371 int bus_kernel_connect(sd_bus *b) {
372 assert(b);
373 assert(b->input_fd < 0);
374 assert(b->output_fd < 0);
375 assert(b->kernel);
376
377 if (b->is_server)
378 return -EINVAL;
379
380 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
381 if (b->input_fd < 0)
382 return -errno;
383
384 b->output_fd = b->input_fd;
385
386 return bus_kernel_take_fd(b);
387 }
388
389 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
390 int r;
391
392 assert(bus);
393 assert(m);
394 assert(bus->state == BUS_RUNNING);
395
396 /* If we can't deliver, we want room for the error message */
397 r = bus_rqueue_make_room(bus);
398 if (r < 0)
399 return r;
400
401 r = bus_message_setup_kmsg(bus, m);
402 if (r < 0)
403 return r;
404
405 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
406 if (r < 0) {
407 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
408 sd_bus_message *reply;
409
410 if (errno == EAGAIN || errno == EINTR)
411 return 0;
412 else if (errno == ENXIO || errno == ESRCH) {
413
414 /* ENXIO: unique name not known
415 * ESRCH: well-known name not known */
416
417 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
418 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
419 else
420 return 0;
421
422 } else if (errno == EADDRNOTAVAIL) {
423
424 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
425
426 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
427 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
428 else
429 return 0;
430 } else
431 return -errno;
432
433 r = bus_message_new_synthetic_error(
434 bus,
435 BUS_MESSAGE_SERIAL(m),
436 &error,
437 &reply);
438
439 if (r < 0)
440 return r;
441
442 r = bus_seal_synthetic_message(bus, reply);
443 if (r < 0)
444 return r;
445
446 bus->rqueue[bus->rqueue_size++] = reply;
447
448 return 0;
449 }
450
451 return 1;
452 }
453
454 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
455 uint64_t off;
456 struct kdbus_item *d;
457
458 assert(bus);
459 assert(k);
460
461 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
462 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
463
464 KDBUS_PART_FOREACH(d, k, items) {
465
466 if (d->type == KDBUS_ITEM_FDS)
467 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
468 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
469 close_nointr_nofail(d->memfd.fd);
470 }
471 }
472
473 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
474 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
475 int r;
476
477 assert(bus);
478
479 r = sd_bus_message_new_signal(
480 bus,
481 "/org/freedesktop/DBus",
482 "org.freedesktop.DBus",
483 "NameOwnerChanged",
484 &m);
485 if (r < 0)
486 return r;
487
488 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
489 if (r < 0)
490 return r;
491
492 m->sender = "org.freedesktop.DBus";
493
494 r = bus_seal_synthetic_message(bus, m);
495 if (r < 0)
496 return r;
497
498 bus->rqueue[bus->rqueue_size++] = m;
499 m = NULL;
500
501 return 1;
502 }
503
504 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
505 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
506
507 assert(bus);
508 assert(k);
509 assert(d);
510
511 if (d->name_change.flags != 0)
512 return 0;
513
514 if (d->type == KDBUS_ITEM_NAME_ADD)
515 old_owner[0] = 0;
516 else
517 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
518
519 if (d->type == KDBUS_ITEM_NAME_REMOVE)
520 new_owner[0] = 0;
521 else
522 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
523
524 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
525 }
526
527 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
528 char owner[UNIQUE_NAME_MAX];
529
530 assert(bus);
531 assert(k);
532 assert(d);
533
534 sprintf(owner, ":1.%llu", d->id_change.id);
535
536 return push_name_owner_changed(
537 bus, owner,
538 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
539 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
540 }
541
542 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
543 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
544 int r;
545
546 assert(bus);
547 assert(k);
548 assert(d);
549
550 r = bus_message_new_synthetic_error(
551 bus,
552 k->cookie_reply,
553 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
554 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
555 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
556 &m);
557 if (r < 0)
558 return r;
559
560 m->sender = "org.freedesktop.DBus";
561
562 r = bus_seal_synthetic_message(bus, m);
563 if (r < 0)
564 return r;
565
566 bus->rqueue[bus->rqueue_size++] = m;
567 m = NULL;
568
569 return 1;
570 }
571
572 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
573 struct kdbus_item *d, *found = NULL;
574
575 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
576 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
577 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
578 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
579
580 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
581 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
582
583 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
584 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
585 };
586
587 assert(bus);
588 assert(k);
589 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
590
591 KDBUS_PART_FOREACH(d, k, items) {
592 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
593 if (found)
594 return -EBADMSG;
595 found = d;
596 } else
597 log_debug("Got unknown field from kernel %llu", d->type);
598 }
599
600 if (!found) {
601 log_debug("Didn't find a kernel message to translate.");
602 return 0;
603 }
604
605 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
606 }
607
608 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
609 sd_bus_message *m = NULL;
610 struct kdbus_item *d;
611 unsigned n_fds = 0;
612 _cleanup_free_ int *fds = NULL;
613 struct bus_header *h = NULL;
614 size_t total, n_bytes = 0, idx = 0;
615 const char *destination = NULL, *seclabel = NULL;
616 int r;
617
618 assert(bus);
619 assert(k);
620 assert(k->payload_type == KDBUS_PAYLOAD_DBUS1);
621
622 KDBUS_PART_FOREACH(d, k, items) {
623 size_t l;
624
625 l = d->size - offsetof(struct kdbus_item, data);
626
627 switch (d->type) {
628
629 case KDBUS_ITEM_PAYLOAD_OFF:
630 if (!h) {
631 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
632
633 if (!bus_header_is_complete(h, d->vec.size))
634 return -EBADMSG;
635 }
636
637 n_bytes += d->vec.size;
638 break;
639
640 case KDBUS_ITEM_PAYLOAD_MEMFD:
641 if (!h)
642 return -EBADMSG;
643
644 n_bytes += d->memfd.size;
645 break;
646
647 case KDBUS_ITEM_FDS: {
648 int *f;
649 unsigned j;
650
651 j = l / sizeof(int);
652 f = realloc(fds, sizeof(int) * (n_fds + j));
653 if (!f)
654 return -ENOMEM;
655
656 fds = f;
657 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
658 n_fds += j;
659 break;
660 }
661
662 case KDBUS_ITEM_SECLABEL:
663 seclabel = d->str;
664 break;
665 }
666 }
667
668 if (!h)
669 return -EBADMSG;
670
671 r = bus_header_message_size(h, &total);
672 if (r < 0)
673 return r;
674
675 if (n_bytes != total)
676 return -EBADMSG;
677
678 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
679 if (r < 0)
680 return r;
681
682 KDBUS_PART_FOREACH(d, k, items) {
683 size_t l;
684
685 l = d->size - offsetof(struct kdbus_item, data);
686
687 switch (d->type) {
688
689 case KDBUS_ITEM_PAYLOAD_OFF: {
690 size_t begin_body;
691
692 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
693
694 if (idx + d->vec.size > begin_body) {
695 struct bus_body_part *part;
696
697 /* Contains body material */
698
699 part = message_append_part(m);
700 if (!part) {
701 r = -ENOMEM;
702 goto fail;
703 }
704
705 /* A -1 offset is NUL padding. */
706 part->is_zero = d->vec.offset == ~0ULL;
707
708 if (idx >= begin_body) {
709 if (!part->is_zero)
710 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
711 part->size = d->vec.size;
712 } else {
713 if (!part->is_zero)
714 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
715 part->size = d->vec.size - (begin_body - idx);
716 }
717
718 part->sealed = true;
719 }
720
721 idx += d->vec.size;
722 break;
723 }
724
725 case KDBUS_ITEM_PAYLOAD_MEMFD: {
726 struct bus_body_part *part;
727
728 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
729 r = -EBADMSG;
730 goto fail;
731 }
732
733 part = message_append_part(m);
734 if (!part) {
735 r = -ENOMEM;
736 goto fail;
737 }
738
739 part->memfd = d->memfd.fd;
740 part->size = d->memfd.size;
741 part->sealed = true;
742
743 idx += d->memfd.size;
744 break;
745 }
746
747 case KDBUS_ITEM_CREDS:
748 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
749 m->creds.uid = d->creds.uid;
750 m->creds.gid = d->creds.gid;
751 m->creds.pid = d->creds.pid;
752 m->creds.tid = d->creds.tid;
753 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID) & bus->creds_mask;
754 break;
755
756 case KDBUS_ITEM_TIMESTAMP:
757 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
758 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
759 break;
760
761 case KDBUS_ITEM_PID_COMM:
762 m->creds.comm = d->str;
763 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
764 break;
765
766 case KDBUS_ITEM_TID_COMM:
767 m->creds.tid_comm = d->str;
768 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
769 break;
770
771 case KDBUS_ITEM_EXE:
772 m->creds.exe = d->str;
773 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
774 break;
775
776 case KDBUS_ITEM_CMDLINE:
777 m->creds.cmdline = d->str;
778 m->creds.cmdline_size = l;
779 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
780 break;
781
782 case KDBUS_ITEM_CGROUP:
783 m->creds.cgroup = d->str;
784 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;
785 break;
786
787 case KDBUS_ITEM_AUDIT:
788 m->creds.audit_session_id = d->audit.sessionid;
789 m->creds.audit_login_uid = d->audit.loginuid;
790 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
791 break;
792
793 case KDBUS_ITEM_CAPS:
794 m->creds.capability = d->data;
795 m->creds.capability_size = l;
796 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;
797 break;
798
799 case KDBUS_ITEM_DST_NAME:
800 destination = d->str;
801 break;
802
803 case KDBUS_ITEM_NAMES:
804 m->creds.well_known_names = d->str;
805 m->creds.well_known_names_size = l;
806 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
807 break;
808
809 case KDBUS_ITEM_FDS:
810 case KDBUS_ITEM_SECLABEL:
811 break;
812
813 default:
814 log_debug("Got unknown field from kernel %llu", d->type);
815 }
816 }
817
818 r = bus_message_parse_fields(m);
819 if (r < 0)
820 goto fail;
821
822 if (k->src_id == KDBUS_SRC_ID_KERNEL)
823 m->sender = "org.freedesktop.DBus";
824 else {
825 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
826 m->sender = m->creds.unique_name = m->sender_buffer;
827 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
828 }
829
830 if (!m->destination) {
831 if (destination)
832 m->destination = destination;
833 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
834 k->dst_id != KDBUS_DST_ID_BROADCAST) {
835 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
836 m->destination = m->destination_buffer;
837 }
838 }
839
840 /* We take possession of the kmsg struct now */
841 m->kdbus = k;
842 m->release_kdbus = true;
843 m->free_fds = true;
844 fds = NULL;
845
846 bus->rqueue[bus->rqueue_size++] = m;
847
848 return 1;
849
850 fail:
851 if (m) {
852 struct bus_body_part *part;
853 unsigned i;
854
855 /* Make sure the memfds are not freed twice */
856 MESSAGE_FOREACH_PART(part, i, m)
857 if (part->memfd >= 0)
858 part->memfd = -1;
859
860 sd_bus_message_unref(m);
861 }
862
863 return r;
864 }
865
866 int bus_kernel_read_message(sd_bus *bus) {
867 struct kdbus_msg *k;
868 uint64_t off;
869 int r;
870
871 assert(bus);
872
873 r = bus_rqueue_make_room(bus);
874 if (r < 0)
875 return r;
876
877 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
878 if (r < 0) {
879 if (errno == EAGAIN)
880 return 0;
881
882 return -errno;
883 }
884 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
885
886 if (k->payload_type == KDBUS_PAYLOAD_DBUS1)
887 r = bus_kernel_make_message(bus, k);
888 else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
889 r = bus_kernel_translate_message(bus, k);
890 else
891 r = 0;
892
893 if (r <= 0)
894 close_kdbus_msg(bus, k);
895
896 return r < 0 ? r : 1;
897 }
898
899 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
900 struct memfd_cache *c;
901 int fd;
902
903 assert(address);
904 assert(size);
905
906 if (!bus || !bus->is_kernel)
907 return -ENOTSUP;
908
909 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
910
911 if (bus->n_memfd_cache <= 0) {
912 int r;
913
914 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
915
916 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
917 if (r < 0)
918 return -errno;
919
920 *address = NULL;
921 *size = 0;
922 return fd;
923 }
924
925 c = &bus->memfd_cache[--bus->n_memfd_cache];
926
927 assert(c->fd >= 0);
928 assert(c->size == 0 || c->address);
929
930 *address = c->address;
931 *size = c->size;
932 fd = c->fd;
933
934 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
935
936 return fd;
937 }
938
939 static void close_and_munmap(int fd, void *address, size_t size) {
940 if (size > 0)
941 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
942
943 close_nointr_nofail(fd);
944 }
945
946 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
947 struct memfd_cache *c;
948 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
949
950 assert(fd >= 0);
951 assert(size == 0 || address);
952
953 if (!bus || !bus->is_kernel) {
954 close_and_munmap(fd, address, size);
955 return;
956 }
957
958 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
959
960 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
961 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
962
963 close_and_munmap(fd, address, size);
964 return;
965 }
966
967 c = &bus->memfd_cache[bus->n_memfd_cache++];
968 c->fd = fd;
969 c->address = address;
970
971 /* If overly long, let's return a bit to the OS */
972 if (size > max_sz) {
973 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
974 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
975 c->size = max_sz;
976 } else
977 c->size = size;
978
979 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
980 }
981
982 void bus_kernel_flush_memfd(sd_bus *b) {
983 unsigned i;
984
985 assert(b);
986
987 for (i = 0; i < b->n_memfd_cache; i++)
988 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
989 }
990
991 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
992 uint64_t f = 0;
993
994 assert(kdbus_flags);
995
996 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
997 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
998
999 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1000 f |= KDBUS_NAME_REPLACE_EXISTING;
1001
1002 if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1003 f |= KDBUS_NAME_QUEUE;
1004
1005 *kdbus_flags = f;
1006 return 0;
1007 }
1008
1009 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1010 uint64_t m = 0;
1011
1012 assert(kdbus_mask);
1013
1014 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1015 m |= KDBUS_ATTACH_CREDS;
1016
1017 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1018 m |= KDBUS_ATTACH_COMM;
1019
1020 if (mask & SD_BUS_CREDS_EXE)
1021 m |= KDBUS_ATTACH_EXE;
1022
1023 if (mask & SD_BUS_CREDS_CMDLINE)
1024 m |= KDBUS_ATTACH_CMDLINE;
1025
1026 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))
1027 m |= KDBUS_ATTACH_CGROUP;
1028
1029 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1030 m |= KDBUS_ATTACH_CAPS;
1031
1032 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1033 m |= KDBUS_ATTACH_SECLABEL;
1034
1035 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1036 m |= KDBUS_ATTACH_AUDIT;
1037
1038 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1039 m |= KDBUS_ATTACH_NAMES;
1040
1041 *kdbus_mask = m;
1042 return 0;
1043 }
1044
1045 int bus_kernel_create_bus(const char *name, char **s) {
1046 struct kdbus_cmd_bus_make *make;
1047 struct kdbus_item *n;
1048 int fd;
1049
1050 assert(name);
1051 assert(s);
1052
1053 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1054 if (fd < 0)
1055 return -errno;
1056
1057 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1058 offsetof(struct kdbus_item, str) +
1059 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1060
1061 n = make->items;
1062 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1063 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1064 n->type = KDBUS_MAKE_NAME;
1065
1066 make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1067 make->flags = KDBUS_MAKE_POLICY_OPEN;
1068 make->bus_flags = 0;
1069 make->bloom_size = BLOOM_SIZE;
1070 assert_cc(BLOOM_SIZE % 8 == 0);
1071
1072 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1073 close_nointr_nofail(fd);
1074 return -errno;
1075 }
1076
1077 if (s) {
1078 char *p;
1079
1080 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1081 if (!p) {
1082 close_nointr_nofail(fd);
1083 return -ENOMEM;
1084 }
1085
1086 *s = p;
1087 }
1088
1089 return fd;
1090 }
1091
1092 int bus_kernel_create_namespace(const char *name, char **s) {
1093 struct kdbus_cmd_ns_make *make;
1094 struct kdbus_item *n;
1095 int fd;
1096
1097 assert(name);
1098 assert(s);
1099
1100 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1101 if (fd < 0)
1102 return -errno;
1103
1104 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) +
1105 offsetof(struct kdbus_item, str) +
1106 strlen(name) + 1));
1107
1108 n = make->items;
1109 strcpy(n->str, name);
1110 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1111 n->type = KDBUS_MAKE_NAME;
1112
1113 make->size = ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) + n->size);
1114 make->flags = KDBUS_MAKE_POLICY_OPEN;
1115
1116 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1117 close_nointr_nofail(fd);
1118 return -errno;
1119 }
1120
1121 if (s) {
1122 char *p;
1123
1124 p = strappend("/dev/kdbus/", name);
1125 if (!p) {
1126 close_nointr_nofail(fd);
1127 return -ENOMEM;
1128 }
1129
1130 *s = p;
1131 }
1132
1133 return fd;
1134 }