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>
30 #include <sys/prctl.h>
34 #include "memfd-util.h"
36 #include "bus-internal.h"
37 #include "bus-message.h"
38 #include "bus-kernel.h"
39 #include "bus-bloom.h"
41 #include "bus-label.h"
42 #include "cgroup-util.h"
44 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
46 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
52 if (!startswith(s, ":1."))
55 r = safe_atou64(s + 3, id);
62 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
68 /* Note that p can be NULL, which encodes a region full of
69 * zeroes, which is useful to optimize certain padding
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);
77 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
80 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
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;
91 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
94 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
100 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
101 (*d)->type = KDBUS_ITEM_DST_NAME;
102 memcpy((*d)->str, s, length + 1);
104 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
107 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
108 struct kdbus_item *i;
114 i->size = offsetof(struct kdbus_item, bloom_filter) +
115 offsetof(struct kdbus_bloom_filter, data) +
117 i->type = KDBUS_ITEM_BLOOM_FILTER;
119 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
121 return &i->bloom_filter;
124 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
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);
134 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
137 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
146 memzero(data, m->bus->bloom_size);
147 bloom->generation = 0;
149 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
152 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
154 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
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, '/');
161 r = sd_bus_message_rewind(m, true);
165 for (i = 0; i < 64; i++) {
168 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
171 r = sd_bus_message_peek_type(m, &type, NULL);
175 if (type != SD_BUS_TYPE_STRING &&
176 type != SD_BUS_TYPE_OBJECT_PATH &&
177 type != SD_BUS_TYPE_SIGNATURE)
180 r = sd_bus_message_read_basic(m, type, &t);
184 e = stpcpy(buf, "arg");
186 *(e++) = '0' + (char) i;
188 *(e++) = '0' + (char) (i / 10);
189 *(e++) = '0' + (char) (i % 10);
193 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
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, '/');
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;
217 /* We put this together only once, if this message is reused
218 * we reuse the earlier-built version */
222 if (m->destination) {
223 r = bus_kernel_parse_unique_name(m->destination, &unique);
231 sz = offsetof(struct kdbus_msg, items);
233 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
234 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
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));
240 /* Add space for bloom filter */
241 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
242 offsetof(struct kdbus_bloom_filter, data) +
245 /* Add in well-known destination header */
247 dl = strlen(m->destination);
248 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
251 /* Add space for unix fds */
253 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
255 m->kdbus = memalign(8, sz);
261 m->free_kdbus = true;
262 memzero(m->kdbus, sz);
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);
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;
274 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) {
275 m->kdbus->cookie_reply = m->reply_cookie;
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;
287 append_destination(&d, m->destination, dl);
289 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
291 MESSAGE_FOREACH_PART(part, i, m) {
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 */
298 append_payload_vec(&d, NULL, part->size);
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 */
306 append_payload_memfd(&d, part->memfd, part->size);
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);
316 append_payload_vec(&d, part->data, part->size);
319 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
320 struct kdbus_bloom_filter *bloom;
322 bloom = append_bloom(&d, m->bus->bloom_size);
323 r = bus_message_setup_bloom(m, bloom);
329 append_fds(&d, m->fds, m->n_fds);
331 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
332 assert(m->kdbus->size <= sz);
341 static void unset_memfds(struct sd_bus_message *m) {
342 struct bus_body_part *part;
347 /* Make sure the memfds are not freed twice */
348 MESSAGE_FOREACH_PART(part, i, m)
349 if (part->memfd >= 0)
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;
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;
365 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
367 KDBUS_ITEM_FOREACH(d, k, items) {
370 l = d->size - offsetof(struct kdbus_item, data);
374 case KDBUS_ITEM_PAYLOAD_OFF:
376 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
378 if (!bus_header_is_complete(h, d->vec.size))
382 n_bytes += d->vec.size;
385 case KDBUS_ITEM_PAYLOAD_MEMFD:
389 n_bytes += d->memfd.size;
392 case KDBUS_ITEM_FDS: {
397 f = realloc(fds, sizeof(int) * (n_fds + j));
402 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
407 case KDBUS_ITEM_SECLABEL:
416 r = bus_header_message_size(h, &total);
420 if (n_bytes != total)
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)
429 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
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 */
438 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
440 KDBUS_ITEM_FOREACH(d, k, items) {
443 l = d->size - offsetof(struct kdbus_item, data);
447 case KDBUS_ITEM_PAYLOAD_OFF: {
450 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
452 if (idx + d->vec.size > begin_body) {
453 struct bus_body_part *part;
455 /* Contains body material */
457 part = message_append_part(m);
463 /* A -1 offset is NUL padding. */
464 part->is_zero = d->vec.offset == ~0ULL;
466 if (idx >= begin_body) {
468 part->data = (uint8_t *)k + d->vec.offset;
469 part->size = d->vec.size;
472 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
473 part->size = d->vec.size - (begin_body - idx);
483 case KDBUS_ITEM_PAYLOAD_MEMFD: {
484 struct bus_body_part *part;
486 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
491 part = message_append_part(m);
497 part->memfd = d->memfd.fd;
498 part->size = d->memfd.size;
501 idx += d->memfd.size;
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;
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 */
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;
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;
529 case KDBUS_ITEM_TIMESTAMP:
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;
539 case KDBUS_ITEM_PID_COMM:
540 m->creds.comm = d->str;
541 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
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;
550 m->creds.exe = d->str;
551 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
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;
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;
564 r = bus_get_root_path(bus);
568 m->creds.cgroup_root = bus->cgroup_root;
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;
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;
584 case KDBUS_ITEM_DST_NAME:
585 if (!service_name_is_valid(d->str))
588 destination = d->str;
591 case KDBUS_ITEM_OWNED_NAME:
592 if (!service_name_is_valid(d->name.name))
595 r = strv_extend(&m->creds.well_known_names, d->name.name);
600 case KDBUS_ITEM_CONN_DESCRIPTION:
601 m->creds.description = d->str;
602 m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
606 case KDBUS_ITEM_SECLABEL:
610 log_debug("Got unknown field from kernel %llu", d->type);
614 r = bus_message_parse_fields(m);
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";
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;
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 */
633 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
634 m->destination = m->destination_buffer;
637 /* We take possession of the kmsg struct now */
639 m->release_kdbus = true;
643 bus->rqueue[bus->rqueue_size++] = m;
649 sd_bus_message_unref(m);
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;
659 size_t l = 0, m = 0, sz;
669 if (b->description) {
670 g = bus_label_escape(b->description);
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 */
682 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
685 name = b->is_system ? "sd-system" :
686 b->is_user ? "sd-user" : "sd";
688 _cleanup_free_ char *e = NULL;
690 e = bus_label_escape(pr);
694 g = strappend(b->is_system ? "sd-system-" :
695 b->is_user ? "sd-user-" : "sd-",
703 b->description = bus_label_unescape(name);
710 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
711 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
713 if (b->fake_creds_valid)
714 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
717 l = strlen(b->fake_label);
718 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
721 hello = alloca0_align(sz, 8);
723 hello->flags = b->hello_flags;
724 hello->attach_flags_send = _KDBUS_ATTACH_ALL;
725 hello->attach_flags_recv = b->attach_flags;
726 hello->pool_size = KDBUS_POOL_SIZE;
730 item->size = offsetof(struct kdbus_item, str) + m + 1;
731 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
732 memcpy(item->str, name, m + 1);
733 item = KDBUS_ITEM_NEXT(item);
735 if (b->fake_creds_valid) {
736 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
737 item->type = KDBUS_ITEM_CREDS;
738 item->creds = b->fake_creds;
740 item = KDBUS_ITEM_NEXT(item);
744 item->size = offsetof(struct kdbus_item, str) + l + 1;
745 item->type = KDBUS_ITEM_SECLABEL;
746 memcpy(item->str, b->fake_label, l+1);
749 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
753 if (!b->kdbus_buffer) {
754 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
755 if (b->kdbus_buffer == MAP_FAILED) {
756 b->kdbus_buffer = NULL;
761 /* The higher 32bit of the bus_flags fields are considered
762 * 'incompatible flags'. Refuse them all for now. */
763 if (hello->bus_flags > 0xFFFFFFFFULL)
766 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
769 b->bloom_size = (size_t) hello->bloom.size;
770 b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
772 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
775 b->unique_id = hello->id;
778 b->bus_client = true;
779 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
780 b->message_version = 2;
781 b->message_endian = BUS_NATIVE_ENDIAN;
783 /* the kernel told us the UUID of the underlying bus */
784 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
786 return bus_start_running(b);
789 int bus_kernel_connect(sd_bus *b) {
791 assert(b->input_fd < 0);
792 assert(b->output_fd < 0);
798 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
802 b->output_fd = b->input_fd;
804 return bus_kernel_take_fd(b);
807 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
808 struct kdbus_cmd_free cmd;
809 struct kdbus_item *d;
815 cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
817 KDBUS_ITEM_FOREACH(d, k, items) {
819 if (d->type == KDBUS_ITEM_FDS)
820 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
821 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
822 safe_close(d->memfd.fd);
825 (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
828 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
833 assert(bus->state == BUS_RUNNING);
835 /* If we can't deliver, we want room for the error message */
836 r = bus_rqueue_make_room(bus);
840 r = bus_message_setup_kmsg(bus, m);
844 /* If this is a synchronous method call, then let's tell the
845 * kernel, so that it can pass CPU time/scheduling to the
846 * destination for the time, if it wants to. If we
847 * synchronously wait for the result anyway, we won't need CPU
850 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
852 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
854 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
855 sd_bus_message *reply;
857 if (errno == EAGAIN || errno == EINTR)
859 else if (errno == ENXIO || errno == ESRCH) {
861 /* ENXIO: unique name not known
862 * ESRCH: well-known name not known */
864 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
865 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
867 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
871 } else if (errno == EADDRNOTAVAIL) {
873 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
875 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
876 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
878 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
884 r = bus_message_new_synthetic_error(
886 BUS_MESSAGE_COOKIE(m),
893 r = bus_seal_synthetic_message(bus, reply);
897 bus->rqueue[bus->rqueue_size++] = reply;
899 } else if (hint_sync_call) {
902 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
905 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
907 r = bus_kernel_make_message(bus, k);
909 close_kdbus_msg(bus, k);
911 /* Anybody can send us invalid messages, let's just drop them. */
912 if (r == -EBADMSG || r == -EPROTOTYPE)
913 log_debug("Ignoring invalid message: %s", strerror(-r));
918 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
919 close_kdbus_msg(bus, k);
926 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
927 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
932 r = sd_bus_message_new_signal(
935 "/org/freedesktop/DBus",
936 "org.freedesktop.DBus",
941 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
945 m->sender = "org.freedesktop.DBus";
947 r = bus_seal_synthetic_message(bus, m);
951 bus->rqueue[bus->rqueue_size++] = m;
957 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
958 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
964 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
967 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
969 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
971 if (isempty(old_owner))
976 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
978 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
981 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
982 char owner[UNIQUE_NAME_MAX];
988 sprintf(owner, ":1.%llu", d->id_change.id);
990 return push_name_owner_changed(
992 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
993 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
996 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
997 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1004 r = bus_message_new_synthetic_error(
1007 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1008 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1009 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1014 m->sender = "org.freedesktop.DBus";
1016 r = bus_seal_synthetic_message(bus, m);
1020 bus->rqueue[bus->rqueue_size++] = m;
1026 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1027 struct kdbus_item *d, *found = NULL;
1029 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1030 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1031 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1032 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1034 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1035 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1037 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1038 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1043 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1045 KDBUS_ITEM_FOREACH(d, k, items) {
1046 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1051 log_debug("Got unknown field from kernel %llu", d->type);
1055 log_debug("Didn't find a kernel message to translate.");
1059 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
1062 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1063 struct kdbus_cmd_recv recv = {};
1064 struct kdbus_msg *k;
1069 r = bus_rqueue_make_room(bus);
1073 if (hint_priority) {
1074 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1075 recv.priority = priority;
1078 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1080 if (errno == EAGAIN)
1086 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1087 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1088 r = bus_kernel_make_message(bus, k);
1090 /* Anybody can send us invalid messages, let's just drop them. */
1091 if (r == -EBADMSG || r == -EPROTOTYPE) {
1092 log_debug("Ignoring invalid message: %s", strerror(-r));
1096 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1097 r = bus_kernel_translate_message(bus, k);
1099 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1104 close_kdbus_msg(bus, k);
1106 return r < 0 ? r : 1;
1109 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1110 struct memfd_cache *c;
1117 if (!bus || !bus->is_kernel)
1120 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1122 if (bus->n_memfd_cache <= 0) {
1125 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1127 r = memfd_new(bus->description);
1137 c = &bus->memfd_cache[--bus->n_memfd_cache];
1140 assert(c->mapped == 0 || c->address);
1142 *address = c->address;
1143 *mapped = c->mapped;
1144 *allocated = c->allocated;
1147 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1152 static void close_and_munmap(int fd, void *address, size_t size) {
1154 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1159 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1160 struct memfd_cache *c;
1161 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1164 assert(mapped == 0 || address);
1166 if (!bus || !bus->is_kernel) {
1167 close_and_munmap(fd, address, mapped);
1171 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1173 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1174 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1176 close_and_munmap(fd, address, mapped);
1180 c = &bus->memfd_cache[bus->n_memfd_cache++];
1182 c->address = address;
1184 /* If overly long, let's return a bit to the OS */
1185 if (mapped > max_mapped) {
1186 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1187 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1188 c->mapped = c->allocated = max_mapped;
1191 c->allocated = allocated;
1194 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1197 void bus_kernel_flush_memfd(sd_bus *b) {
1202 for (i = 0; i < b->n_memfd_cache; i++)
1203 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1206 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1209 assert(kdbus_flags);
1211 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1212 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1214 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1215 f |= KDBUS_NAME_REPLACE_EXISTING;
1217 if (flags & SD_BUS_NAME_QUEUE)
1218 f |= KDBUS_NAME_QUEUE;
1224 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1229 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1230 m |= KDBUS_ATTACH_CREDS;
1232 if (mask & SD_BUS_CREDS_COMM)
1233 m |= KDBUS_ATTACH_PID_COMM;
1235 if (mask & SD_BUS_CREDS_TID_COMM)
1236 m |= KDBUS_ATTACH_TID_COMM;
1238 if (mask & SD_BUS_CREDS_EXE)
1239 m |= KDBUS_ATTACH_EXE;
1241 if (mask & SD_BUS_CREDS_CMDLINE)
1242 m |= KDBUS_ATTACH_CMDLINE;
1244 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))
1245 m |= KDBUS_ATTACH_CGROUP;
1247 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1248 m |= KDBUS_ATTACH_CAPS;
1250 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1251 m |= KDBUS_ATTACH_SECLABEL;
1253 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1254 m |= KDBUS_ATTACH_AUDIT;
1256 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1257 m |= KDBUS_ATTACH_NAMES;
1259 if (mask & SD_BUS_CREDS_DESCRIPTION)
1260 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1266 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1267 struct kdbus_cmd_make *make;
1268 struct kdbus_item *n;
1274 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1278 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1279 offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1280 offsetof(struct kdbus_item, str) +
1281 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
1284 make->size = offsetof(struct kdbus_cmd_make, items);
1287 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1288 sizeof(struct kdbus_bloom_parameter);
1289 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1291 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1292 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1294 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1295 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1297 make->size += ALIGN8(n->size);
1299 n = KDBUS_ITEM_NEXT(n);
1300 sprintf(n->str, UID_FMT "-%s", getuid(), name);
1301 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1302 n->type = KDBUS_ITEM_MAKE_NAME;
1303 make->size += ALIGN8(n->size);
1305 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1307 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1315 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1327 static int bus_kernel_translate_access(BusPolicyAccess access) {
1328 assert(access >= 0);
1329 assert(access < _BUS_POLICY_ACCESS_MAX);
1333 case BUS_POLICY_ACCESS_SEE:
1334 return KDBUS_POLICY_SEE;
1336 case BUS_POLICY_ACCESS_TALK:
1337 return KDBUS_POLICY_TALK;
1339 case BUS_POLICY_ACCESS_OWN:
1340 return KDBUS_POLICY_OWN;
1343 assert_not_reached("Unknown policy access");
1347 static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
1353 switch (policy->type) {
1355 case BUSNAME_POLICY_TYPE_USER: {
1356 const char *user = policy->name;
1359 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
1363 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1364 item->policy_access.id = uid;
1368 case BUSNAME_POLICY_TYPE_GROUP: {
1369 const char *group = policy->name;
1372 r = get_group_creds(&group, &gid);
1376 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1377 item->policy_access.id = gid;
1382 assert_not_reached("Unknown policy type");
1385 item->policy_access.access = bus_kernel_translate_access(policy->access);
1390 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1395 len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1404 sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1406 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1413 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1414 _cleanup_free_ char *path = NULL;
1415 struct kdbus_cmd_make *make;
1416 struct kdbus_item *n;
1420 fd = bus_kernel_open_bus_fd(bus_name, &path);
1424 size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1425 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
1427 make = alloca0_align(size, 8);
1429 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1433 n->type = KDBUS_ITEM_MAKE_NAME;
1434 n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1;
1435 strcpy(n->str, ep_name);
1437 if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1445 p = strjoin(dirname(path), "/", ep_name, NULL);
1457 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
1459 struct kdbus_cmd_update *update;
1460 struct kdbus_item *n;
1461 BusEndpointPolicy *po;
1466 size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
1468 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1469 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
1470 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1473 update = alloca0_align(size, 8);
1474 update->size = size;
1478 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1479 n->type = KDBUS_ITEM_NAME;
1480 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
1481 strcpy(n->str, po->name);
1482 n = KDBUS_ITEM_NEXT(n);
1484 n->type = KDBUS_ITEM_POLICY_ACCESS;
1485 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1487 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1488 n->policy_access.access = bus_kernel_translate_access(po->access);
1489 n->policy_access.id = uid;
1491 n = KDBUS_ITEM_NEXT(n);
1494 r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
1501 int bus_kernel_make_starter(
1506 BusNamePolicy *policy,
1507 BusPolicyAccess world_policy) {
1509 struct kdbus_cmd_hello *hello;
1510 struct kdbus_item *n;
1511 size_t policy_cnt = 0;
1519 LIST_FOREACH(policy, po, policy)
1522 if (world_policy >= 0)
1525 size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1526 ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1527 policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1529 hello = alloca0_align(size, 8);
1532 strcpy(n->str, name);
1533 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1534 n->type = KDBUS_ITEM_NAME;
1535 n = KDBUS_ITEM_NEXT(n);
1537 LIST_FOREACH(policy, po, policy) {
1538 n->type = KDBUS_ITEM_POLICY_ACCESS;
1539 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1541 r = bus_kernel_translate_policy(po, n);
1545 n = KDBUS_ITEM_NEXT(n);
1548 if (world_policy >= 0) {
1549 n->type = KDBUS_ITEM_POLICY_ACCESS;
1550 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1551 n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1552 n->policy_access.access = bus_kernel_translate_access(world_policy);
1557 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1558 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
1559 hello->pool_size = KDBUS_POOL_SIZE;
1560 hello->attach_flags_send = _KDBUS_ATTACH_ALL;
1561 hello->attach_flags_recv = _KDBUS_ATTACH_ALL;
1563 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
1566 /* The higher 32bit of the bus_flags fields are considered
1567 * 'incompatible flags'. Refuse them all for now. */
1568 if (hello->bus_flags > 0xFFFFFFFFULL)
1571 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
1577 int bus_kernel_create_domain(const char *name, char **s) {
1578 struct kdbus_cmd_make *make;
1579 struct kdbus_item *n;
1585 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1589 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1590 offsetof(struct kdbus_item, str) +
1595 strcpy(n->str, name);
1596 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1597 n->type = KDBUS_ITEM_MAKE_NAME;
1599 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1600 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1602 if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
1607 /* The higher 32bit of the flags field are considered
1608 * 'incompatible flags'. Refuse them all for now. */
1609 if (make->flags > 0xFFFFFFFFULL) {
1617 p = strappend("/dev/kdbus/domain/", name);
1629 int bus_kernel_try_close(sd_bus *bus) {
1631 assert(bus->is_kernel);
1633 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1639 int bus_kernel_drop_one(int fd) {
1640 struct kdbus_cmd_recv recv = {
1641 .flags = KDBUS_RECV_DROP
1646 if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)