1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
33 #include "bus-internal.h"
34 #include "bus-message.h"
35 #include "bus-kernel.h"
36 #include "bus-bloom.h"
38 #include "cgroup-util.h"
40 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
42 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
48 if (!startswith(s, ":1."))
51 r = safe_atou64(s + 3, id);
58 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
64 /* Note that p can be NULL, which encodes a region full of
65 * zeroes, which is useful to optimize certain padding
68 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
69 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
70 (*d)->vec.address = PTR_TO_UINT64(p);
73 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
76 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
82 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
83 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
84 (*d)->memfd.fd = memfd;
85 (*d)->memfd.size = sz;
87 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
90 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
96 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
97 (*d)->type = KDBUS_ITEM_DST_NAME;
98 memcpy((*d)->str, s, length + 1);
100 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
103 static void* append_bloom(struct kdbus_item **d, size_t length) {
110 (*d)->size = offsetof(struct kdbus_item, data) + length;
111 (*d)->type = KDBUS_ITEM_BLOOM;
114 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
119 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
125 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
126 (*d)->type = KDBUS_ITEM_FDS;
127 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
129 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
132 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
139 memset(bloom, 0, BLOOM_SIZE);
141 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
144 bloom_add_pair(bloom, "interface", m->interface);
146 bloom_add_pair(bloom, "member", m->member);
148 bloom_add_pair(bloom, "path", m->path);
149 bloom_add_pair(bloom, "path-slash-prefix", m->path);
150 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
153 r = sd_bus_message_rewind(m, true);
157 for (i = 0; i < 64; i++) {
160 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
163 r = sd_bus_message_peek_type(m, &type, NULL);
167 if (type != SD_BUS_TYPE_STRING &&
168 type != SD_BUS_TYPE_OBJECT_PATH &&
169 type != SD_BUS_TYPE_SIGNATURE)
172 r = sd_bus_message_read_basic(m, type, &t);
176 e = stpcpy(buf, "arg");
178 *(e++) = '0' + (char) i;
180 *(e++) = '0' + (char) (i / 10);
181 *(e++) = '0' + (char) (i % 10);
185 bloom_add_pair(bloom, buf, t);
187 strcpy(e, "-dot-prefix");
188 bloom_add_prefixes(bloom, buf, t, '.');
189 strcpy(e, "-slash-prefix");
190 bloom_add_prefixes(bloom, buf, t, '/');
196 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
197 struct bus_body_part *part;
198 struct kdbus_item *d;
212 if (m->destination) {
213 r = bus_kernel_parse_unique_name(m->destination, &unique);
221 sz = offsetof(struct kdbus_msg, items);
223 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
224 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
226 /* Add in fixed header, fields header and payload */
227 sz += (1 + m->n_body_parts) *
228 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
230 /* Add space for bloom filter */
231 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
233 /* Add in well-known destination header */
235 dl = strlen(m->destination);
236 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
239 /* Add space for unix fds */
241 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
243 m->kdbus = memalign(8, sz);
249 m->free_kdbus = true;
250 memset(m->kdbus, 0, sz);
253 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
254 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
257 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
258 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
259 m->kdbus->cookie = m->header->serial;
261 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
262 m->kdbus->cookie_reply = m->reply_cookie;
264 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
269 append_destination(&d, m->destination, dl);
271 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
273 MESSAGE_FOREACH_PART(part, i, m) {
275 /* If this is padding then simply send a
276 * vector with a NULL data pointer which the
277 * kernel will just pass through. This is the
278 * most efficient way to encode zeroes */
280 append_payload_vec(&d, NULL, part->size);
284 if (part->memfd >= 0 && part->sealed && m->destination) {
285 /* Try to send a memfd, if the part is
286 * sealed and this is not a broadcast. Since we can only */
288 append_payload_memfd(&d, part->memfd, part->size);
292 /* Otherwise let's send a vector to the actual data,
293 * for that we need to map it first. */
294 r = bus_body_part_map(part);
298 append_payload_vec(&d, part->data, part->size);
301 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
304 p = append_bloom(&d, BLOOM_SIZE);
305 r = bus_message_setup_bloom(m, p);
311 append_fds(&d, m->fds, m->n_fds);
313 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
314 assert(m->kdbus->size <= sz);
323 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
324 sd_bus_message *m = NULL;
325 struct kdbus_item *d;
327 _cleanup_free_ int *fds = NULL;
328 struct bus_header *h = NULL;
329 size_t total, n_bytes = 0, idx = 0;
330 const char *destination = NULL, *seclabel = NULL;
335 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
337 KDBUS_ITEM_FOREACH(d, k, items) {
340 l = d->size - offsetof(struct kdbus_item, data);
344 case KDBUS_ITEM_PAYLOAD_OFF:
346 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
348 if (!bus_header_is_complete(h, d->vec.size))
352 n_bytes += d->vec.size;
355 case KDBUS_ITEM_PAYLOAD_MEMFD:
359 n_bytes += d->memfd.size;
362 case KDBUS_ITEM_FDS: {
367 f = realloc(fds, sizeof(int) * (n_fds + j));
372 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
377 case KDBUS_ITEM_SECLABEL:
386 r = bus_header_message_size(h, &total);
390 if (n_bytes != total)
393 /* on kdbus we only speak native endian gvariant, never dbus1
394 * marshalling or reverse endian */
395 if (h->version != 2 ||
396 h->endian != BUS_NATIVE_ENDIAN)
399 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
403 /* The well-known names list is different from the other
404 credentials. If we asked for it, but nothing is there, this
405 means that the list of well-known names is simply empty, not
406 that we lack any data */
408 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
410 KDBUS_ITEM_FOREACH(d, k, items) {
413 l = d->size - offsetof(struct kdbus_item, data);
417 case KDBUS_ITEM_PAYLOAD_OFF: {
420 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
422 if (idx + d->vec.size > begin_body) {
423 struct bus_body_part *part;
425 /* Contains body material */
427 part = message_append_part(m);
433 /* A -1 offset is NUL padding. */
434 part->is_zero = d->vec.offset == ~0ULL;
436 if (idx >= begin_body) {
438 part->data = (uint8_t *)k + d->vec.offset;
439 part->size = d->vec.size;
442 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
443 part->size = d->vec.size - (begin_body - idx);
453 case KDBUS_ITEM_PAYLOAD_MEMFD: {
454 struct bus_body_part *part;
456 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
461 part = message_append_part(m);
467 part->memfd = d->memfd.fd;
468 part->size = d->memfd.size;
471 idx += d->memfd.size;
475 case KDBUS_ITEM_CREDS:
476 /* UID/GID/PID are always valid */
477 m->creds.uid = (uid_t) d->creds.uid;
478 m->creds.gid = (gid_t) d->creds.gid;
479 m->creds.pid = (pid_t) d->creds.pid;
480 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
482 /* The PID starttime/TID might be missing
483 * however, when the data is faked by some
484 * data bus proxy and it lacks that
485 * information about the real client since
486 * SO_PEERCRED is used for that */
488 if (d->creds.starttime > 0) {
489 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
490 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
493 if (d->creds.tid > 0) {
494 m->creds.tid = (pid_t) d->creds.tid;
495 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
499 case KDBUS_ITEM_TIMESTAMP:
500 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
501 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
504 case KDBUS_ITEM_PID_COMM:
505 m->creds.comm = d->str;
506 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
509 case KDBUS_ITEM_TID_COMM:
510 m->creds.tid_comm = d->str;
511 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
515 m->creds.exe = d->str;
516 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
519 case KDBUS_ITEM_CMDLINE:
520 m->creds.cmdline = d->str;
521 m->creds.cmdline_size = l;
522 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
525 case KDBUS_ITEM_CGROUP:
526 m->creds.cgroup = d->str;
527 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;
529 if (!bus->cgroup_root) {
530 r = cg_get_root_path(&bus->cgroup_root);
535 m->creds.cgroup_root = bus->cgroup_root;
539 case KDBUS_ITEM_AUDIT:
540 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
541 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
542 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
545 case KDBUS_ITEM_CAPS:
546 m->creds.capability = d->data;
547 m->creds.capability_size = l;
548 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;
551 case KDBUS_ITEM_DST_NAME:
552 if (!service_name_is_valid(d->str))
555 destination = d->str;
558 case KDBUS_ITEM_NAME:
559 if (!service_name_is_valid(d->name.name))
562 r = strv_extend(&m->creds.well_known_names, d->name.name);
568 case KDBUS_ITEM_SECLABEL:
572 log_debug("Got unknown field from kernel %llu", d->type);
576 r = bus_message_parse_fields(m);
580 /* Override information from the user header with data from the kernel */
581 if (k->src_id == KDBUS_SRC_ID_KERNEL)
582 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
584 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
585 m->sender = m->creds.unique_name = m->sender_buffer;
589 m->destination = destination;
590 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
591 m->destination = NULL;
592 else if (k->dst_id == KDBUS_DST_ID_NAME)
593 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
595 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
596 m->destination = m->destination_buffer;
599 /* We take possession of the kmsg struct now */
601 m->release_kdbus = true;
605 bus->rqueue[bus->rqueue_size++] = m;
611 struct bus_body_part *part;
614 /* Make sure the memfds are not freed twice */
615 MESSAGE_FOREACH_PART(part, i, m)
616 if (part->memfd >= 0)
619 sd_bus_message_unref(m);
625 int bus_kernel_take_fd(sd_bus *b) {
626 struct kdbus_cmd_hello *hello;
627 struct kdbus_item *item;
638 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
640 if (b->fake_creds_valid)
641 sz += ALIGN8(offsetof(struct kdbus_item, creds)) + sizeof(struct kdbus_creds);
644 l = strlen(b->fake_label);
645 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
650 hello->conn_flags = b->hello_flags;
651 hello->attach_flags = b->attach_flags;
652 hello->pool_size = KDBUS_POOL_SIZE;
656 if (b->fake_creds_valid) {
657 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
658 item->type = KDBUS_ITEM_CREDS;
659 item->creds = b->fake_creds;
661 item = KDBUS_ITEM_NEXT(item);
665 item->size = offsetof(struct kdbus_item, str) + l + 1;
666 memcpy(item->str, b->fake_label, l+1);
669 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
673 if (!b->kdbus_buffer) {
674 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
675 if (b->kdbus_buffer == MAP_FAILED) {
676 b->kdbus_buffer = NULL;
681 /* The higher 32bit of both flags fields are considered
682 * 'incompatible flags'. Refuse them all for now. */
683 if (hello->bus_flags > 0xFFFFFFFFULL ||
684 hello->conn_flags > 0xFFFFFFFFULL)
687 if (hello->bloom_size != BLOOM_SIZE)
690 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
693 b->unique_id = hello->id;
696 b->bus_client = true;
697 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
698 b->message_version = 2;
699 b->message_endian = BUS_NATIVE_ENDIAN;
701 /* the kernel told us the UUID of the underlying bus */
702 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
704 return bus_start_running(b);
707 int bus_kernel_connect(sd_bus *b) {
709 assert(b->input_fd < 0);
710 assert(b->output_fd < 0);
716 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
720 b->output_fd = b->input_fd;
722 return bus_kernel_take_fd(b);
725 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
730 assert(bus->state == BUS_RUNNING);
732 /* If we can't deliver, we want room for the error message */
733 r = bus_rqueue_make_room(bus);
737 r = bus_message_setup_kmsg(bus, m);
741 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
743 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
744 sd_bus_message *reply;
746 if (errno == EAGAIN || errno == EINTR)
748 else if (errno == ENXIO || errno == ESRCH) {
750 /* ENXIO: unique name not known
751 * ESRCH: well-known name not known */
753 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
754 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
756 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
760 } else if (errno == EADDRNOTAVAIL) {
762 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
764 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
765 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
767 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
773 r = bus_message_new_synthetic_error(
775 BUS_MESSAGE_COOKIE(m),
782 r = bus_seal_synthetic_message(bus, reply);
786 bus->rqueue[bus->rqueue_size++] = reply;
794 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
796 struct kdbus_item *d;
801 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
802 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
804 KDBUS_ITEM_FOREACH(d, k, items) {
806 if (d->type == KDBUS_ITEM_FDS)
807 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
808 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
809 close_nointr_nofail(d->memfd.fd);
813 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
814 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
819 r = sd_bus_message_new_signal(
821 "/org/freedesktop/DBus",
822 "org.freedesktop.DBus",
828 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
832 m->sender = "org.freedesktop.DBus";
834 r = bus_seal_synthetic_message(bus, m);
838 bus->rqueue[bus->rqueue_size++] = m;
844 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
845 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
851 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
854 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old.id);
856 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
858 if (isempty(old_owner))
863 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new.id);
865 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
868 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
869 char owner[UNIQUE_NAME_MAX];
875 sprintf(owner, ":1.%llu", d->id_change.id);
877 return push_name_owner_changed(
879 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
880 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
883 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
884 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
891 r = bus_message_new_synthetic_error(
894 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
895 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
896 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
901 m->sender = "org.freedesktop.DBus";
903 r = bus_seal_synthetic_message(bus, m);
907 bus->rqueue[bus->rqueue_size++] = m;
913 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
914 struct kdbus_item *d, *found = NULL;
916 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
917 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
918 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
919 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
921 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
922 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
924 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
925 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
930 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
932 KDBUS_ITEM_FOREACH(d, k, items) {
933 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
938 log_debug("Got unknown field from kernel %llu", d->type);
942 log_debug("Didn't find a kernel message to translate.");
946 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
949 int bus_kernel_read_message(sd_bus *bus) {
950 struct kdbus_cmd_recv recv = {};
956 r = bus_rqueue_make_room(bus);
960 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
967 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
969 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
970 r = bus_kernel_make_message(bus, k);
972 /* Anybody can send us invalid messages, let's just drop them. */
973 if (r == -EBADMSG || r == -EPROTOTYPE) {
974 log_debug("Ignoring invalid message: %s", strerror(-r));
978 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
979 r = bus_kernel_translate_message(bus, k);
984 close_kdbus_msg(bus, k);
986 return r < 0 ? r : 1;
989 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
990 struct memfd_cache *c;
997 if (!bus || !bus->is_kernel)
1000 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1002 if (bus->n_memfd_cache <= 0) {
1003 struct kdbus_cmd_memfd_make cmd = {
1004 .size = sizeof(struct kdbus_cmd_memfd_make),
1008 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1010 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &cmd);
1020 c = &bus->memfd_cache[--bus->n_memfd_cache];
1023 assert(c->mapped == 0 || c->address);
1025 *address = c->address;
1026 *mapped = c->mapped;
1027 *allocated = c->allocated;
1030 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1035 static void close_and_munmap(int fd, void *address, size_t size) {
1037 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1039 close_nointr_nofail(fd);
1042 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1043 struct memfd_cache *c;
1044 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1047 assert(mapped == 0 || address);
1049 if (!bus || !bus->is_kernel) {
1050 close_and_munmap(fd, address, mapped);
1054 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1056 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1057 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1059 close_and_munmap(fd, address, mapped);
1063 c = &bus->memfd_cache[bus->n_memfd_cache++];
1065 c->address = address;
1067 /* If overly long, let's return a bit to the OS */
1068 if (mapped > max_mapped) {
1069 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_mapped) >= 0);
1070 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1071 c->mapped = c->allocated = max_mapped;
1074 c->allocated = allocated;
1077 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1080 void bus_kernel_flush_memfd(sd_bus *b) {
1085 for (i = 0; i < b->n_memfd_cache; i++)
1086 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1089 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1092 assert(kdbus_flags);
1094 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1095 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1097 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1098 f |= KDBUS_NAME_REPLACE_EXISTING;
1100 if (flags & SD_BUS_NAME_QUEUE)
1101 f |= KDBUS_NAME_QUEUE;
1107 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1112 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1113 m |= KDBUS_ATTACH_CREDS;
1115 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1116 m |= KDBUS_ATTACH_COMM;
1118 if (mask & SD_BUS_CREDS_EXE)
1119 m |= KDBUS_ATTACH_EXE;
1121 if (mask & SD_BUS_CREDS_CMDLINE)
1122 m |= KDBUS_ATTACH_CMDLINE;
1124 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))
1125 m |= KDBUS_ATTACH_CGROUP;
1127 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1128 m |= KDBUS_ATTACH_CAPS;
1130 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1131 m |= KDBUS_ATTACH_SECLABEL;
1133 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1134 m |= KDBUS_ATTACH_AUDIT;
1136 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1137 m |= KDBUS_ATTACH_NAMES;
1143 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1144 struct kdbus_cmd_make *make;
1145 struct kdbus_item *n;
1151 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1155 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1156 offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1157 offsetof(struct kdbus_item, str) +
1158 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1160 make->size = offsetof(struct kdbus_cmd_make, items);
1163 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1164 n->type = KDBUS_ITEM_BLOOM_SIZE;
1165 n->data64[0] = BLOOM_SIZE;
1166 assert_cc(BLOOM_SIZE % 8 == 0);
1167 make->size += ALIGN8(n->size);
1169 n = KDBUS_ITEM_NEXT(n);
1170 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1171 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1172 n->type = KDBUS_ITEM_MAKE_NAME;
1173 make->size += ALIGN8(n->size);
1175 make->flags = KDBUS_MAKE_POLICY_OPEN | (world ? KDBUS_MAKE_ACCESS_WORLD : 0);
1177 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1178 close_nointr_nofail(fd);
1182 /* The higher 32bit of the flags field are considered
1183 * 'incompatible flags'. Refuse them all for now. */
1184 if (make->flags > 0xFFFFFFFFULL) {
1185 close_nointr_nofail(fd);
1192 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1194 close_nointr_nofail(fd);
1204 int bus_kernel_create_starter(const char *bus, const char *name) {
1205 struct kdbus_cmd_hello *hello;
1206 struct kdbus_item *n;
1213 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1214 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1216 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1220 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1221 offsetof(struct kdbus_item, str) +
1225 strcpy(n->str, name);
1226 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1227 n->type = KDBUS_ITEM_NAME;
1229 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1230 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1231 hello->pool_size = KDBUS_POOL_SIZE;
1233 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1234 close_nointr_nofail(fd);
1238 /* The higher 32bit of both flags fields are considered
1239 * 'incompatible flags'. Refuse them all for now. */
1240 if (hello->bus_flags > 0xFFFFFFFFULL ||
1241 hello->conn_flags > 0xFFFFFFFFULL) {
1242 close_nointr_nofail(fd);
1246 if (hello->bloom_size != BLOOM_SIZE) {
1247 close_nointr_nofail(fd);
1254 int bus_kernel_create_namespace(const char *name, char **s) {
1255 struct kdbus_cmd_make *make;
1256 struct kdbus_item *n;
1262 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1266 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1267 offsetof(struct kdbus_item, str) +
1271 strcpy(n->str, name);
1272 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1273 n->type = KDBUS_ITEM_MAKE_NAME;
1275 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1276 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1278 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1279 close_nointr_nofail(fd);
1283 /* The higher 32bit of the flags field are considered
1284 * 'incompatible flags'. Refuse them all for now. */
1285 if (make->flags > 0xFFFFFFFFULL) {
1286 close_nointr_nofail(fd);
1293 p = strappend("/dev/kdbus/ns/", name);
1295 close_nointr_nofail(fd);
1305 int bus_kernel_create_monitor(const char *bus) {
1306 struct kdbus_cmd_hello *hello;
1312 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1313 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1315 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1319 hello = alloca0(sizeof(struct kdbus_cmd_hello));
1320 hello->size = sizeof(struct kdbus_cmd_hello);
1321 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1322 hello->pool_size = KDBUS_POOL_SIZE;
1324 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1325 close_nointr_nofail(fd);
1329 /* The higher 32bit of both flags fields are considered
1330 * 'incompatible flags'. Refuse them all for now. */
1331 if (hello->bus_flags > 0xFFFFFFFFULL ||
1332 hello->conn_flags > 0xFFFFFFFFULL) {
1333 close_nointr_nofail(fd);
1340 int bus_kernel_try_close(sd_bus *bus) {
1342 assert(bus->is_kernel);
1344 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)