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) |
255 (m->reply_sync ? KDBUS_MSG_FLAGS_SYNC_REPLY : 0);
258 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
259 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
260 m->kdbus->cookie = m->header->serial;
262 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
263 m->kdbus->cookie_reply = m->reply_cookie;
265 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
270 append_destination(&d, m->destination, dl);
272 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
274 MESSAGE_FOREACH_PART(part, i, m) {
276 /* If this is padding then simply send a
277 * vector with a NULL data pointer which the
278 * kernel will just pass through. This is the
279 * most efficient way to encode zeroes */
281 append_payload_vec(&d, NULL, part->size);
285 if (part->memfd >= 0 && part->sealed && m->destination) {
286 /* Try to send a memfd, if the part is
287 * sealed and this is not a broadcast. Since we can only */
289 append_payload_memfd(&d, part->memfd, part->size);
293 /* Otherwise let's send a vector to the actual data,
294 * for that we need to map it first. */
295 r = bus_body_part_map(part);
299 append_payload_vec(&d, part->data, part->size);
302 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
305 p = append_bloom(&d, BLOOM_SIZE);
306 r = bus_message_setup_bloom(m, p);
312 append_fds(&d, m->fds, m->n_fds);
314 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
315 assert(m->kdbus->size <= sz);
324 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
325 sd_bus_message *m = NULL;
326 struct kdbus_item *d;
328 _cleanup_free_ int *fds = NULL;
329 struct bus_header *h = NULL;
330 size_t total, n_bytes = 0, idx = 0;
331 const char *destination = NULL, *seclabel = NULL;
336 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
338 KDBUS_ITEM_FOREACH(d, k, items) {
341 l = d->size - offsetof(struct kdbus_item, data);
345 case KDBUS_ITEM_PAYLOAD_OFF:
347 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
349 if (!bus_header_is_complete(h, d->vec.size))
353 n_bytes += d->vec.size;
356 case KDBUS_ITEM_PAYLOAD_MEMFD:
360 n_bytes += d->memfd.size;
363 case KDBUS_ITEM_FDS: {
368 f = realloc(fds, sizeof(int) * (n_fds + j));
373 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
378 case KDBUS_ITEM_SECLABEL:
387 r = bus_header_message_size(h, &total);
391 if (n_bytes != total)
394 /* on kdbus we only speak native endian gvariant, never dbus1
395 * marshalling or reverse endian */
396 if (h->version != 2 ||
397 h->endian != BUS_NATIVE_ENDIAN)
400 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
404 /* The well-known names list is different from the other
405 credentials. If we asked for it, but nothing is there, this
406 means that the list of well-known names is simply empty, not
407 that we lack any data */
409 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
411 KDBUS_ITEM_FOREACH(d, k, items) {
414 l = d->size - offsetof(struct kdbus_item, data);
418 case KDBUS_ITEM_PAYLOAD_OFF: {
421 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
423 if (idx + d->vec.size > begin_body) {
424 struct bus_body_part *part;
426 /* Contains body material */
428 part = message_append_part(m);
434 /* A -1 offset is NUL padding. */
435 part->is_zero = d->vec.offset == ~0ULL;
437 if (idx >= begin_body) {
439 part->data = (uint8_t *)k + d->vec.offset;
440 part->size = d->vec.size;
443 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
444 part->size = d->vec.size - (begin_body - idx);
454 case KDBUS_ITEM_PAYLOAD_MEMFD: {
455 struct bus_body_part *part;
457 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
462 part = message_append_part(m);
468 part->memfd = d->memfd.fd;
469 part->size = d->memfd.size;
472 idx += d->memfd.size;
476 case KDBUS_ITEM_CREDS:
477 /* UID/GID/PID are always valid */
478 m->creds.uid = (uid_t) d->creds.uid;
479 m->creds.gid = (gid_t) d->creds.gid;
480 m->creds.pid = (pid_t) d->creds.pid;
481 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
483 /* The PID starttime/TID might be missing
484 * however, when the data is faked by some
485 * data bus proxy and it lacks that
486 * information about the real client since
487 * SO_PEERCRED is used for that */
489 if (d->creds.starttime > 0) {
490 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
491 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
494 if (d->creds.tid > 0) {
495 m->creds.tid = (pid_t) d->creds.tid;
496 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
500 case KDBUS_ITEM_TIMESTAMP:
501 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
502 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
505 case KDBUS_ITEM_PID_COMM:
506 m->creds.comm = d->str;
507 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
510 case KDBUS_ITEM_TID_COMM:
511 m->creds.tid_comm = d->str;
512 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
516 m->creds.exe = d->str;
517 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
520 case KDBUS_ITEM_CMDLINE:
521 m->creds.cmdline = d->str;
522 m->creds.cmdline_size = l;
523 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
526 case KDBUS_ITEM_CGROUP:
527 m->creds.cgroup = d->str;
528 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;
530 if (!bus->cgroup_root) {
531 r = cg_get_root_path(&bus->cgroup_root);
536 m->creds.cgroup_root = bus->cgroup_root;
540 case KDBUS_ITEM_AUDIT:
541 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
542 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
543 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
546 case KDBUS_ITEM_CAPS:
547 m->creds.capability = d->data;
548 m->creds.capability_size = l;
549 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;
552 case KDBUS_ITEM_DST_NAME:
553 if (!service_name_is_valid(d->str))
556 destination = d->str;
559 case KDBUS_ITEM_NAME:
560 if (!service_name_is_valid(d->name.name))
563 r = strv_extend(&m->creds.well_known_names, d->name.name);
569 case KDBUS_ITEM_SECLABEL:
573 log_debug("Got unknown field from kernel %llu", d->type);
577 r = bus_message_parse_fields(m);
581 /* Override information from the user header with data from the kernel */
582 if (k->src_id == KDBUS_SRC_ID_KERNEL)
583 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
585 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
586 m->sender = m->creds.unique_name = m->sender_buffer;
590 m->destination = destination;
591 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
592 m->destination = NULL;
593 else if (k->dst_id == KDBUS_DST_ID_NAME)
594 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
596 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
597 m->destination = m->destination_buffer;
600 /* We take possession of the kmsg struct now */
602 m->release_kdbus = true;
606 bus->rqueue[bus->rqueue_size++] = m;
612 struct bus_body_part *part;
615 /* Make sure the memfds are not freed twice */
616 MESSAGE_FOREACH_PART(part, i, m)
617 if (part->memfd >= 0)
620 sd_bus_message_unref(m);
626 int bus_kernel_take_fd(sd_bus *b) {
627 struct kdbus_cmd_hello *hello;
628 struct kdbus_item *item;
639 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
641 if (b->fake_creds_valid)
642 sz += ALIGN8(offsetof(struct kdbus_item, creds)) + sizeof(struct kdbus_creds);
645 l = strlen(b->fake_label);
646 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
651 hello->conn_flags = b->hello_flags;
652 hello->attach_flags = b->attach_flags;
653 hello->pool_size = KDBUS_POOL_SIZE;
657 if (b->fake_creds_valid) {
658 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
659 item->type = KDBUS_ITEM_CREDS;
660 item->creds = b->fake_creds;
662 item = KDBUS_ITEM_NEXT(item);
666 item->size = offsetof(struct kdbus_item, str) + l + 1;
667 memcpy(item->str, b->fake_label, l+1);
670 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
674 if (!b->kdbus_buffer) {
675 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
676 if (b->kdbus_buffer == MAP_FAILED) {
677 b->kdbus_buffer = NULL;
682 /* The higher 32bit of both flags fields are considered
683 * 'incompatible flags'. Refuse them all for now. */
684 if (hello->bus_flags > 0xFFFFFFFFULL ||
685 hello->conn_flags > 0xFFFFFFFFULL)
688 if (hello->bloom_size != BLOOM_SIZE)
691 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
694 b->unique_id = hello->id;
697 b->bus_client = true;
698 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
699 b->message_version = 2;
700 b->message_endian = BUS_NATIVE_ENDIAN;
702 /* the kernel told us the UUID of the underlying bus */
703 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
705 return bus_start_running(b);
708 int bus_kernel_connect(sd_bus *b) {
710 assert(b->input_fd < 0);
711 assert(b->output_fd < 0);
717 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
721 b->output_fd = b->input_fd;
723 return bus_kernel_take_fd(b);
726 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
731 assert(bus->state == BUS_RUNNING);
733 /* If we can't deliver, we want room for the error message */
734 r = bus_rqueue_make_room(bus);
738 r = bus_message_setup_kmsg(bus, m);
742 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
744 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
745 sd_bus_message *reply;
747 if (errno == EAGAIN || errno == EINTR)
749 else if (errno == ENXIO || errno == ESRCH) {
751 /* ENXIO: unique name not known
752 * ESRCH: well-known name not known */
754 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
755 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
757 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
761 } else if (errno == EADDRNOTAVAIL) {
763 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
765 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
766 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
768 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
774 r = bus_message_new_synthetic_error(
776 BUS_MESSAGE_COOKIE(m),
783 r = bus_seal_synthetic_message(bus, reply);
787 bus->rqueue[bus->rqueue_size++] = reply;
795 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
796 r = bus_kernel_make_message(bus, k);
809 sd_bus_message **reply) {
814 m->reply_sync = !!reply;
816 r = sd_bus_send(bus, m, &cookie);
821 assert(bus->rqueue_size > 0);
822 *reply = bus->rqueue[--bus->rqueue_size];
828 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
830 struct kdbus_item *d;
835 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
836 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
838 KDBUS_ITEM_FOREACH(d, k, items) {
840 if (d->type == KDBUS_ITEM_FDS)
841 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
842 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
843 close_nointr_nofail(d->memfd.fd);
847 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
848 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
853 r = sd_bus_message_new_signal(
855 "/org/freedesktop/DBus",
856 "org.freedesktop.DBus",
862 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
866 m->sender = "org.freedesktop.DBus";
868 r = bus_seal_synthetic_message(bus, m);
872 bus->rqueue[bus->rqueue_size++] = m;
878 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
879 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
885 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
888 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old.id);
890 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
892 if (isempty(old_owner))
897 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new.id);
899 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
902 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
903 char owner[UNIQUE_NAME_MAX];
909 sprintf(owner, ":1.%llu", d->id_change.id);
911 return push_name_owner_changed(
913 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
914 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
917 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
918 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
925 r = bus_message_new_synthetic_error(
928 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
929 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
930 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
935 m->sender = "org.freedesktop.DBus";
937 r = bus_seal_synthetic_message(bus, m);
941 bus->rqueue[bus->rqueue_size++] = m;
947 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
948 struct kdbus_item *d, *found = NULL;
950 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
951 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
952 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
953 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
955 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
956 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
958 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
959 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
964 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
966 KDBUS_ITEM_FOREACH(d, k, items) {
967 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
972 log_debug("Got unknown field from kernel %llu", d->type);
976 log_debug("Didn't find a kernel message to translate.");
980 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
983 int bus_kernel_read_message(sd_bus *bus) {
984 struct kdbus_cmd_recv recv = {};
990 r = bus_rqueue_make_room(bus);
994 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1001 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1003 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1004 r = bus_kernel_make_message(bus, k);
1006 /* Anybody can send us invalid messages, let's just drop them. */
1007 if (r == -EBADMSG || r == -EPROTOTYPE) {
1008 log_debug("Ignoring invalid message: %s", strerror(-r));
1012 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1013 r = bus_kernel_translate_message(bus, k);
1018 close_kdbus_msg(bus, k);
1020 return r < 0 ? r : 1;
1023 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1024 struct memfd_cache *c;
1031 if (!bus || !bus->is_kernel)
1034 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1036 if (bus->n_memfd_cache <= 0) {
1037 struct kdbus_cmd_memfd_make cmd = {
1038 .size = sizeof(struct kdbus_cmd_memfd_make),
1042 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1044 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &cmd);
1054 c = &bus->memfd_cache[--bus->n_memfd_cache];
1057 assert(c->mapped == 0 || c->address);
1059 *address = c->address;
1060 *mapped = c->mapped;
1061 *allocated = c->allocated;
1064 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1069 static void close_and_munmap(int fd, void *address, size_t size) {
1071 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1073 close_nointr_nofail(fd);
1076 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1077 struct memfd_cache *c;
1078 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1081 assert(mapped == 0 || address);
1083 if (!bus || !bus->is_kernel) {
1084 close_and_munmap(fd, address, mapped);
1088 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1090 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1091 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1093 close_and_munmap(fd, address, mapped);
1097 c = &bus->memfd_cache[bus->n_memfd_cache++];
1099 c->address = address;
1101 /* If overly long, let's return a bit to the OS */
1102 if (mapped > max_mapped) {
1103 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_mapped) >= 0);
1104 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1105 c->mapped = c->allocated = max_mapped;
1108 c->allocated = allocated;
1111 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1114 void bus_kernel_flush_memfd(sd_bus *b) {
1119 for (i = 0; i < b->n_memfd_cache; i++)
1120 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1123 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1126 assert(kdbus_flags);
1128 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1129 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1131 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1132 f |= KDBUS_NAME_REPLACE_EXISTING;
1134 if (flags & SD_BUS_NAME_QUEUE)
1135 f |= KDBUS_NAME_QUEUE;
1141 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1146 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1147 m |= KDBUS_ATTACH_CREDS;
1149 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1150 m |= KDBUS_ATTACH_COMM;
1152 if (mask & SD_BUS_CREDS_EXE)
1153 m |= KDBUS_ATTACH_EXE;
1155 if (mask & SD_BUS_CREDS_CMDLINE)
1156 m |= KDBUS_ATTACH_CMDLINE;
1158 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))
1159 m |= KDBUS_ATTACH_CGROUP;
1161 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1162 m |= KDBUS_ATTACH_CAPS;
1164 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1165 m |= KDBUS_ATTACH_SECLABEL;
1167 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1168 m |= KDBUS_ATTACH_AUDIT;
1170 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1171 m |= KDBUS_ATTACH_NAMES;
1177 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1178 struct kdbus_cmd_make *make;
1179 struct kdbus_item *n;
1185 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1189 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1190 offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1191 offsetof(struct kdbus_item, str) +
1192 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1194 make->size = offsetof(struct kdbus_cmd_make, items);
1197 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1198 n->type = KDBUS_ITEM_BLOOM_SIZE;
1199 n->data64[0] = BLOOM_SIZE;
1200 assert_cc(BLOOM_SIZE % 8 == 0);
1201 make->size += ALIGN8(n->size);
1203 n = KDBUS_ITEM_NEXT(n);
1204 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1205 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1206 n->type = KDBUS_ITEM_MAKE_NAME;
1207 make->size += ALIGN8(n->size);
1209 make->flags = KDBUS_MAKE_POLICY_OPEN | (world ? KDBUS_MAKE_ACCESS_WORLD : 0);
1211 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1212 close_nointr_nofail(fd);
1216 /* The higher 32bit of the flags field are considered
1217 * 'incompatible flags'. Refuse them all for now. */
1218 if (make->flags > 0xFFFFFFFFULL) {
1219 close_nointr_nofail(fd);
1226 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1228 close_nointr_nofail(fd);
1238 int bus_kernel_create_starter(const char *bus, const char *name) {
1239 struct kdbus_cmd_hello *hello;
1240 struct kdbus_item *n;
1247 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1248 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1250 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1254 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1255 offsetof(struct kdbus_item, str) +
1259 strcpy(n->str, name);
1260 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1261 n->type = KDBUS_ITEM_NAME;
1263 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1264 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1265 hello->pool_size = KDBUS_POOL_SIZE;
1267 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1268 close_nointr_nofail(fd);
1272 /* The higher 32bit of both flags fields are considered
1273 * 'incompatible flags'. Refuse them all for now. */
1274 if (hello->bus_flags > 0xFFFFFFFFULL ||
1275 hello->conn_flags > 0xFFFFFFFFULL) {
1276 close_nointr_nofail(fd);
1280 if (hello->bloom_size != BLOOM_SIZE) {
1281 close_nointr_nofail(fd);
1288 int bus_kernel_create_namespace(const char *name, char **s) {
1289 struct kdbus_cmd_make *make;
1290 struct kdbus_item *n;
1296 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1300 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1301 offsetof(struct kdbus_item, str) +
1305 strcpy(n->str, name);
1306 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1307 n->type = KDBUS_ITEM_MAKE_NAME;
1309 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1310 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1312 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1313 close_nointr_nofail(fd);
1317 /* The higher 32bit of the flags field are considered
1318 * 'incompatible flags'. Refuse them all for now. */
1319 if (make->flags > 0xFFFFFFFFULL) {
1320 close_nointr_nofail(fd);
1327 p = strappend("/dev/kdbus/ns/", name);
1329 close_nointr_nofail(fd);
1339 int bus_kernel_create_monitor(const char *bus) {
1340 struct kdbus_cmd_hello *hello;
1346 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1347 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1349 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1353 hello = alloca0(sizeof(struct kdbus_cmd_hello));
1354 hello->size = sizeof(struct kdbus_cmd_hello);
1355 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1356 hello->pool_size = KDBUS_POOL_SIZE;
1358 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1359 close_nointr_nofail(fd);
1363 /* The higher 32bit of both flags fields are considered
1364 * 'incompatible flags'. Refuse them all for now. */
1365 if (hello->bus_flags > 0xFFFFFFFFULL ||
1366 hello->conn_flags > 0xFFFFFFFFULL) {
1367 close_nointr_nofail(fd);
1374 int bus_kernel_try_close(sd_bus *bus) {
1376 assert(bus->is_kernel);
1378 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)