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"
35 #include "capability.h"
36 #include "cgroup-util.h"
39 #include "bus-internal.h"
40 #include "bus-message.h"
41 #include "bus-kernel.h"
42 #include "bus-bloom.h"
44 #include "bus-label.h"
46 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
48 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
54 if (!startswith(s, ":1."))
57 r = safe_atou64(s + 3, id);
64 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
70 /* Note that p can be NULL, which encodes a region full of
71 * zeroes, which is useful to optimize certain padding
74 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
75 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
76 (*d)->vec.address = PTR_TO_UINT64(p);
79 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
82 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t start, size_t sz) {
88 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
89 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
90 (*d)->memfd.fd = memfd;
91 (*d)->memfd.start = start;
92 (*d)->memfd.size = sz;
94 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
97 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
103 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
104 (*d)->type = KDBUS_ITEM_DST_NAME;
105 memcpy((*d)->str, s, length + 1);
107 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
110 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
111 struct kdbus_item *i;
117 i->size = offsetof(struct kdbus_item, bloom_filter) +
118 offsetof(struct kdbus_bloom_filter, data) +
120 i->type = KDBUS_ITEM_BLOOM_FILTER;
122 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
124 return &i->bloom_filter;
127 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
133 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
134 (*d)->type = KDBUS_ITEM_FDS;
135 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
137 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
140 static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
141 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
149 e = stpcpy(buf, "arg");
151 *(e++) = '0' + (char) i;
153 *(e++) = '0' + (char) (i / 10);
154 *(e++) = '0' + (char) (i % 10);
158 bloom_add_pair(data, size, n_hash, buf, t);
160 strcpy(e, "-dot-prefix");
161 bloom_add_prefixes(data, size, n_hash, buf, t, '.');
162 strcpy(e, "-slash-prefix");
163 bloom_add_prefixes(data, size, n_hash, buf, t, '/');
166 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
175 memzero(data, m->bus->bloom_size);
176 bloom->generation = 0;
178 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
181 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
183 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
185 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
186 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
187 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
190 r = sd_bus_message_rewind(m, true);
194 for (i = 0; i < 64; i++) {
195 const char *t, *contents;
198 r = sd_bus_message_peek_type(m, &type, &contents);
202 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
204 /* The bloom filter includes simple strings of any kind */
205 r = sd_bus_message_read_basic(m, type, &t);
209 add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
210 } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
212 /* As well as array of simple strings of any kinds */
213 r = sd_bus_message_enter_container(m, type, contents);
217 while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
218 add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
222 r = sd_bus_message_exit_container(m);
227 /* Stop adding to bloom filter as soon as we
228 * run into the first argument we cannot add
236 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
237 struct bus_body_part *part;
238 struct kdbus_item *d;
239 const char *destination;
250 /* We put this together only once, if this message is reused
251 * we reuse the earlier-built version */
255 destination = m->destination ?: m->destination_ptr;
258 r = bus_kernel_parse_unique_name(destination, &unique);
266 sz = offsetof(struct kdbus_msg, items);
268 /* Add in fixed header, fields header and payload */
269 sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) +
270 MAX(sizeof(struct kdbus_vec),
271 sizeof(struct kdbus_memfd)));
273 /* Add space for bloom filter */
274 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
275 offsetof(struct kdbus_bloom_filter, data) +
278 /* Add in well-known destination header */
280 dl = strlen(destination);
281 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
284 /* Add space for unix fds */
286 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
288 m->kdbus = memalign(8, sz);
294 m->free_kdbus = true;
295 memzero(m->kdbus, sz);
298 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
299 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) |
300 ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0);
303 /* verify_destination_id will usually be 0, which makes the kernel driver only look
304 * at the provided well-known name. Otherwise, the kernel will make sure the provided
305 * destination id matches the owner of the provided weel-known-name, and fail if they
306 * differ. Currently, this is only needed for bus-proxyd. */
307 m->kdbus->dst_id = m->verify_destination_id;
309 m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
311 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
312 m->kdbus->cookie = m->header->dbus2.cookie;
313 m->kdbus->priority = m->priority;
315 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
316 m->kdbus->cookie_reply = m->reply_cookie;
320 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
321 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
322 m->timeout * NSEC_PER_USEC;
328 append_destination(&d, destination, dl);
330 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
332 MESSAGE_FOREACH_PART(part, i, m) {
334 /* If this is padding then simply send a
335 * vector with a NULL data pointer which the
336 * kernel will just pass through. This is the
337 * most efficient way to encode zeroes */
339 append_payload_vec(&d, NULL, part->size);
343 if (part->memfd >= 0 && part->sealed && destination) {
344 /* Try to send a memfd, if the part is
345 * sealed and this is not a broadcast. Since we can only */
347 append_payload_memfd(&d, part->memfd, part->memfd_offset, part->size);
351 /* Otherwise, let's send a vector to the actual data.
352 * For that, we need to map it first. */
353 r = bus_body_part_map(part);
357 append_payload_vec(&d, part->data, part->size);
360 if (m->header->type == SD_BUS_MESSAGE_SIGNAL) {
361 struct kdbus_bloom_filter *bloom;
363 bloom = append_bloom(&d, m->bus->bloom_size);
364 r = bus_message_setup_bloom(m, bloom);
370 append_fds(&d, m->fds, m->n_fds);
372 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
373 assert(m->kdbus->size <= sz);
382 static void unset_memfds(struct sd_bus_message *m) {
383 struct bus_body_part *part;
388 /* Make sure the memfds are not freed twice */
389 MESSAGE_FOREACH_PART(part, i, m)
390 if (part->memfd >= 0)
394 static void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) {
401 if (!(bus->attach_flags & KDBUS_ATTACH_TIMESTAMP))
404 m->realtime = ts->realtime_ns / NSEC_PER_USEC;
405 m->monotonic = ts->monotonic_ns / NSEC_PER_USEC;
406 m->seqnum = ts->seqnum;
409 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
410 sd_bus_message *m = NULL;
411 struct kdbus_item *d;
413 _cleanup_free_ int *fds = NULL;
414 struct bus_header *header = NULL;
416 size_t header_size = 0, footer_size = 0;
417 size_t n_bytes = 0, idx = 0;
418 const char *destination = NULL, *seclabel = NULL;
419 bool last_was_memfd = false;
424 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
426 KDBUS_ITEM_FOREACH(d, k, items) {
429 l = d->size - offsetof(struct kdbus_item, data);
433 case KDBUS_ITEM_PAYLOAD_OFF:
435 header = (struct bus_header *)((uint8_t *) bus->kdbus_buffer + d->vec.offset);
436 header_size = d->vec.size;
439 footer = (uint8_t*) bus->kdbus_buffer + d->vec.offset;
440 footer_size = d->vec.size;
442 n_bytes += d->vec.size;
443 last_was_memfd = false;
446 case KDBUS_ITEM_PAYLOAD_MEMFD:
447 if (!header) /* memfd cannot be first part */
450 n_bytes += d->memfd.size;
451 last_was_memfd = true;
454 case KDBUS_ITEM_FDS: {
459 f = realloc(fds, sizeof(int) * (n_fds + j));
464 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
469 case KDBUS_ITEM_SECLABEL:
475 if (last_was_memfd) /* memfd cannot be last part */
481 if (header_size < sizeof(struct bus_header))
484 /* on kdbus we only speak native endian gvariant, never dbus1
485 * marshalling or reverse endian */
486 if (header->version != 2 ||
487 header->endian != BUS_NATIVE_ENDIAN)
490 r = bus_message_from_header(
501 /* The well-known names list is different from the other
502 credentials. If we asked for it, but nothing is there, this
503 means that the list of well-known names is simply empty, not
504 that we lack any data */
506 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
508 KDBUS_ITEM_FOREACH(d, k, items) {
511 l = d->size - offsetof(struct kdbus_item, data);
515 case KDBUS_ITEM_PAYLOAD_OFF: {
518 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
520 if (idx + d->vec.size > begin_body) {
521 struct bus_body_part *part;
523 /* Contains body material */
525 part = message_append_part(m);
531 /* A -1 offset is NUL padding. */
532 part->is_zero = d->vec.offset == ~0ULL;
534 if (idx >= begin_body) {
536 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
537 part->size = d->vec.size;
540 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
541 part->size = d->vec.size - (begin_body - idx);
551 case KDBUS_ITEM_PAYLOAD_MEMFD: {
552 struct bus_body_part *part;
554 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
559 part = message_append_part(m);
565 part->memfd = d->memfd.fd;
566 part->memfd_offset = d->memfd.start;
567 part->size = d->memfd.size;
570 idx += d->memfd.size;
574 case KDBUS_ITEM_PIDS:
576 /* The PID/TID might be missing, when the data
577 * is faked by a bus proxy and it lacks that
578 * information about the real client (since
579 * SO_PEERCRED is used for that). Also kernel
580 * namespacing might make some of this data
581 * unavailable when untranslatable. */
583 if (d->pids.pid > 0) {
584 m->creds.pid = (pid_t) d->pids.pid;
585 m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
588 if (d->pids.tid > 0) {
589 m->creds.tid = (pid_t) d->pids.tid;
590 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
595 case KDBUS_ITEM_CREDS:
597 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
598 * missing too (see above). */
600 if ((uid_t) d->creds.uid != UID_INVALID) {
601 m->creds.uid = (uid_t) d->creds.uid;
602 m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
605 if ((uid_t) d->creds.euid != UID_INVALID) {
606 m->creds.euid = (uid_t) d->creds.euid;
607 m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
610 if ((uid_t) d->creds.suid != UID_INVALID) {
611 m->creds.suid = (uid_t) d->creds.suid;
612 m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
615 if ((uid_t) d->creds.fsuid != UID_INVALID) {
616 m->creds.fsuid = (uid_t) d->creds.fsuid;
617 m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
620 if ((gid_t) d->creds.gid != GID_INVALID) {
621 m->creds.gid = (gid_t) d->creds.gid;
622 m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
625 if ((gid_t) d->creds.egid != GID_INVALID) {
626 m->creds.egid = (gid_t) d->creds.egid;
627 m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
630 if ((gid_t) d->creds.sgid != GID_INVALID) {
631 m->creds.sgid = (gid_t) d->creds.sgid;
632 m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
635 if ((gid_t) d->creds.fsgid != GID_INVALID) {
636 m->creds.fsgid = (gid_t) d->creds.fsgid;
637 m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
642 case KDBUS_ITEM_TIMESTAMP:
643 message_set_timestamp(bus, m, &d->timestamp);
646 case KDBUS_ITEM_PID_COMM:
647 m->creds.comm = d->str;
648 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
651 case KDBUS_ITEM_TID_COMM:
652 m->creds.tid_comm = d->str;
653 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
657 m->creds.exe = d->str;
658 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
661 case KDBUS_ITEM_CMDLINE:
662 m->creds.cmdline = d->str;
663 m->creds.cmdline_size = l;
664 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
667 case KDBUS_ITEM_CGROUP:
668 m->creds.cgroup = d->str;
669 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;
671 r = bus_get_root_path(bus);
675 m->creds.cgroup_root = bus->cgroup_root;
678 case KDBUS_ITEM_AUDIT:
679 if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
680 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
681 m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
684 if ((uid_t) d->audit.loginuid != UID_INVALID) {
685 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
686 m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
690 case KDBUS_ITEM_CAPS:
691 if (d->caps.last_cap != cap_last_cap() ||
692 d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) {
697 m->creds.capability = d->caps.caps;
698 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;
701 case KDBUS_ITEM_DST_NAME:
702 if (!service_name_is_valid(d->str)) {
707 destination = d->str;
710 case KDBUS_ITEM_OWNED_NAME:
711 if (!service_name_is_valid(d->name.name)) {
716 if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
720 /* We just extend the array here, but
721 * do not allocate the strings inside
722 * of it, instead we just point to our
723 * buffer directly. */
724 n = strv_length(m->creds.well_known_names);
725 wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*));
731 wkn[n] = d->name.name;
733 m->creds.well_known_names = wkn;
735 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
739 case KDBUS_ITEM_CONN_DESCRIPTION:
740 m->creds.description = d->str;
741 m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
744 case KDBUS_ITEM_AUXGROUPS:
746 if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
747 assert_cc(sizeof(gid_t) == sizeof(uint32_t));
749 m->creds.n_supplementary_gids = (d->size - offsetof(struct kdbus_item, data32)) / sizeof(uint32_t);
750 m->creds.supplementary_gids = (gid_t*) d->data32;
751 m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
757 case KDBUS_ITEM_SECLABEL:
761 log_debug("Got unknown field from kernel %llu", d->type);
765 /* If we requested the list of well-known names to be appended
766 * and the sender had none no item for it will be
767 * attached. However, this does *not* mean that the kernel
768 * didn't want to provide this information to us. Hence, let's
769 * explicitly mark this information as available if it was
771 m->creds.mask |= bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES;
773 r = bus_message_parse_fields(m);
777 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
778 if ((uint64_t) m->header->dbus2.cookie != k->cookie) {
783 /* Refuse messages where the reply flag doesn't match up */
784 if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_EXPECT_REPLY)) {
789 /* Refuse reply messages where the reply cookie doesn't match up */
790 if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) {
795 /* Refuse messages where the autostart flag doesn't match up */
796 if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_NO_AUTO_START)) {
801 /* Override information from the user header with data from the kernel */
802 if (k->src_id == KDBUS_SRC_ID_KERNEL)
803 bus_message_set_sender_driver(bus, m);
805 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
806 m->sender = m->creds.unique_name = m->sender_buffer;
810 m->destination = destination;
811 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
812 m->destination = NULL;
813 else if (k->dst_id == KDBUS_DST_ID_NAME)
814 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
816 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
817 m->destination = m->destination_buffer;
820 /* We take possession of the kmsg struct now */
822 m->release_kdbus = true;
826 bus->rqueue[bus->rqueue_size++] = m;
832 sd_bus_message_unref(m);
837 int bus_kernel_take_fd(sd_bus *b) {
838 struct kdbus_bloom_parameter *bloom = NULL;
839 struct kdbus_cmd_hello *hello;
840 struct kdbus_item_list *items;
841 struct kdbus_item *item;
842 _cleanup_free_ char *g = NULL;
844 size_t l = 0, m = 0, sz;
854 if (b->description) {
855 g = bus_label_escape(b->description);
863 /* If no name is explicitly set, we'll include a hint
864 * indicating the library implementation, a hint which
865 * kind of bus this is and the thread name */
867 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
870 name = b->is_system ? "sd-system" :
871 b->is_user ? "sd-user" : "sd";
873 _cleanup_free_ char *e = NULL;
875 e = bus_label_escape(pr);
879 g = strappend(b->is_system ? "sd-system-" :
880 b->is_user ? "sd-user-" : "sd-",
888 b->description = bus_label_unescape(name);
895 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
896 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
898 if (b->fake_creds_valid)
899 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
901 if (b->fake_pids_valid)
902 sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
905 l = strlen(b->fake_label);
906 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
909 hello = alloca0_align(sz, 8);
911 hello->flags = b->hello_flags;
912 hello->attach_flags_send = _KDBUS_ATTACH_ANY;
913 hello->attach_flags_recv = b->attach_flags;
914 hello->pool_size = KDBUS_POOL_SIZE;
918 item->size = offsetof(struct kdbus_item, str) + m + 1;
919 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
920 memcpy(item->str, name, m + 1);
921 item = KDBUS_ITEM_NEXT(item);
923 if (b->fake_creds_valid) {
924 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
925 item->type = KDBUS_ITEM_CREDS;
926 item->creds = b->fake_creds;
928 item = KDBUS_ITEM_NEXT(item);
931 if (b->fake_pids_valid) {
932 item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
933 item->type = KDBUS_ITEM_PIDS;
934 item->pids = b->fake_pids;
936 item = KDBUS_ITEM_NEXT(item);
940 item->size = offsetof(struct kdbus_item, str) + l + 1;
941 item->type = KDBUS_ITEM_SECLABEL;
942 memcpy(item->str, b->fake_label, l+1);
945 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
949 if (!b->kdbus_buffer) {
950 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
951 if (b->kdbus_buffer == MAP_FAILED) {
952 b->kdbus_buffer = NULL;
958 /* The higher 32bit of the bus_flags fields are considered
959 * 'incompatible flags'. Refuse them all for now. */
960 if (hello->bus_flags > 0xFFFFFFFFULL) {
965 /* extract bloom parameters from items */
966 items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset);
967 KDBUS_ITEM_FOREACH(item, items, items) {
968 switch (item->type) {
969 case KDBUS_ITEM_BLOOM_PARAMETER:
970 bloom = &item->bloom_parameter;
975 if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) {
980 b->bloom_size = (size_t) bloom->size;
981 b->bloom_n_hash = (unsigned) bloom->n_hash;
983 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
988 b->unique_id = hello->id;
991 b->bus_client = true;
992 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
993 b->message_version = 2;
994 b->message_endian = BUS_NATIVE_ENDIAN;
996 /* the kernel told us the UUID of the underlying bus */
997 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
999 /* free returned items */
1000 (void) bus_kernel_cmd_free(b, hello->offset);
1001 return bus_start_running(b);
1004 (void) bus_kernel_cmd_free(b, hello->offset);
1008 int bus_kernel_connect(sd_bus *b) {
1010 assert(b->input_fd < 0);
1011 assert(b->output_fd < 0);
1017 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
1018 if (b->input_fd < 0)
1021 b->output_fd = b->input_fd;
1023 return bus_kernel_take_fd(b);
1026 int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) {
1027 struct kdbus_cmd_free cmd = {
1028 .size = sizeof(cmd),
1034 assert(bus->is_kernel);
1036 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
1043 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
1044 struct kdbus_item *d;
1049 KDBUS_ITEM_FOREACH(d, k, items) {
1050 if (d->type == KDBUS_ITEM_FDS)
1051 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
1052 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1053 safe_close(d->memfd.fd);
1056 bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer);
1059 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
1060 struct kdbus_cmd_send cmd = { };
1065 assert(bus->state == BUS_RUNNING);
1067 /* If we can't deliver, we want room for the error message */
1068 r = bus_rqueue_make_room(bus);
1072 r = bus_message_setup_kmsg(bus, m);
1076 cmd.size = sizeof(cmd);
1077 cmd.msg_address = (uintptr_t)m->kdbus;
1079 /* If this is a synchronous method call, then let's tell the
1080 * kernel, so that it can pass CPU time/scheduling to the
1081 * destination for the time, if it wants to. If we
1082 * synchronously wait for the result anyway, we won't need CPU
1084 if (hint_sync_call) {
1085 m->kdbus->flags |= KDBUS_MSG_EXPECT_REPLY;
1086 cmd.flags |= KDBUS_SEND_SYNC_REPLY;
1089 r = ioctl(bus->output_fd, KDBUS_CMD_SEND, &cmd);
1091 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1092 sd_bus_message *reply;
1094 if (errno == EAGAIN || errno == EINTR)
1096 else if (errno == ENXIO || errno == ESRCH) {
1098 /* ENXIO: unique name not known
1099 * ESRCH: well-known name not known */
1101 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1102 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
1104 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
1108 } else if (errno == EADDRNOTAVAIL) {
1110 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1112 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1113 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
1115 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
1121 r = bus_message_new_synthetic_error(
1123 BUS_MESSAGE_COOKIE(m),
1130 r = bus_seal_synthetic_message(bus, reply);
1134 bus->rqueue[bus->rqueue_size++] = reply;
1136 } else if (hint_sync_call) {
1137 struct kdbus_msg *k;
1139 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + cmd.reply.offset);
1142 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1144 r = bus_kernel_make_message(bus, k);
1146 close_kdbus_msg(bus, k);
1148 /* Anybody can send us invalid messages, let's just drop them. */
1149 if (r == -EBADMSG || r == -EPROTOTYPE)
1150 log_debug_errno(r, "Ignoring invalid message: %m");
1155 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1156 close_kdbus_msg(bus, k);
1163 static int push_name_owner_changed(
1166 const char *old_owner,
1167 const char *new_owner,
1168 const struct kdbus_timestamp *ts) {
1170 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1175 r = sd_bus_message_new_signal(
1178 "/org/freedesktop/DBus",
1179 "org.freedesktop.DBus",
1180 "NameOwnerChanged");
1184 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
1188 bus_message_set_sender_driver(bus, m);
1189 message_set_timestamp(bus, m, ts);
1191 r = bus_seal_synthetic_message(bus, m);
1195 bus->rqueue[bus->rqueue_size++] = m;
1201 static int translate_name_change(
1203 const struct kdbus_msg *k,
1204 const struct kdbus_item *d,
1205 const struct kdbus_timestamp *ts) {
1207 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
1213 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
1216 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
1218 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
1220 if (isempty(old_owner))
1225 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
1227 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts);
1230 static int translate_id_change(
1232 const struct kdbus_msg *k,
1233 const struct kdbus_item *d,
1234 const struct kdbus_timestamp *ts) {
1236 char owner[UNIQUE_NAME_MAX];
1242 sprintf(owner, ":1.%llu", d->id_change.id);
1244 return push_name_owner_changed(
1246 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1247 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL,
1251 static int translate_reply(
1253 const struct kdbus_msg *k,
1254 const struct kdbus_item *d,
1255 const struct kdbus_timestamp *ts) {
1257 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1264 r = bus_message_new_synthetic_error(
1267 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1268 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1269 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1274 message_set_timestamp(bus, m, ts);
1276 r = bus_seal_synthetic_message(bus, m);
1280 bus->rqueue[bus->rqueue_size++] = m;
1286 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1287 static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = {
1288 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1289 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1290 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1292 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1293 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1295 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1296 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1299 struct kdbus_item *d, *found = NULL;
1300 struct kdbus_timestamp *ts = NULL;
1304 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1306 KDBUS_ITEM_FOREACH(d, k, items) {
1307 if (d->type == KDBUS_ITEM_TIMESTAMP)
1310 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1315 log_debug("Got unknown field from kernel %llu", d->type);
1319 log_debug("Didn't find a kernel message to translate.");
1323 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found, ts);
1326 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1327 struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
1328 struct kdbus_msg *k;
1333 r = bus_rqueue_make_room(bus);
1337 if (hint_priority) {
1338 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1339 recv.priority = priority;
1342 r = ioctl(bus->input_fd, KDBUS_CMD_RECV, &recv);
1344 if (errno == EAGAIN)
1347 if (errno == EOVERFLOW) {
1348 log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
1355 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.msg.offset);
1356 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1357 r = bus_kernel_make_message(bus, k);
1359 /* Anybody can send us invalid messages, let's just drop them. */
1360 if (r == -EBADMSG || r == -EPROTOTYPE) {
1361 log_debug_errno(r, "Ignoring invalid message: %m");
1365 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1366 r = bus_kernel_translate_message(bus, k);
1368 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1373 close_kdbus_msg(bus, k);
1375 return r < 0 ? r : 1;
1378 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1379 struct memfd_cache *c;
1386 if (!bus || !bus->is_kernel)
1389 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1391 if (bus->n_memfd_cache <= 0) {
1394 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1396 r = memfd_new(bus->description);
1406 c = &bus->memfd_cache[--bus->n_memfd_cache];
1409 assert(c->mapped == 0 || c->address);
1411 *address = c->address;
1412 *mapped = c->mapped;
1413 *allocated = c->allocated;
1416 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1421 static void close_and_munmap(int fd, void *address, size_t size) {
1423 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1428 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1429 struct memfd_cache *c;
1430 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1433 assert(mapped == 0 || address);
1435 if (!bus || !bus->is_kernel) {
1436 close_and_munmap(fd, address, mapped);
1440 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1442 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1443 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1445 close_and_munmap(fd, address, mapped);
1449 c = &bus->memfd_cache[bus->n_memfd_cache++];
1451 c->address = address;
1453 /* If overly long, let's return a bit to the OS */
1454 if (mapped > max_mapped) {
1455 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1456 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1457 c->mapped = c->allocated = max_mapped;
1460 c->allocated = allocated;
1463 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1466 void bus_kernel_flush_memfd(sd_bus *b) {
1471 for (i = 0; i < b->n_memfd_cache; i++)
1472 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1475 uint64_t request_name_flags_to_kdbus(uint64_t flags) {
1478 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1479 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1481 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1482 f |= KDBUS_NAME_REPLACE_EXISTING;
1484 if (flags & SD_BUS_NAME_QUEUE)
1485 f |= KDBUS_NAME_QUEUE;
1490 uint64_t attach_flags_to_kdbus(uint64_t mask) {
1493 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
1494 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
1495 m |= KDBUS_ATTACH_CREDS;
1497 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID))
1498 m |= KDBUS_ATTACH_PIDS;
1500 if (mask & SD_BUS_CREDS_COMM)
1501 m |= KDBUS_ATTACH_PID_COMM;
1503 if (mask & SD_BUS_CREDS_TID_COMM)
1504 m |= KDBUS_ATTACH_TID_COMM;
1506 if (mask & SD_BUS_CREDS_EXE)
1507 m |= KDBUS_ATTACH_EXE;
1509 if (mask & SD_BUS_CREDS_CMDLINE)
1510 m |= KDBUS_ATTACH_CMDLINE;
1512 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))
1513 m |= KDBUS_ATTACH_CGROUP;
1515 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1516 m |= KDBUS_ATTACH_CAPS;
1518 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1519 m |= KDBUS_ATTACH_SECLABEL;
1521 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1522 m |= KDBUS_ATTACH_AUDIT;
1524 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1525 m |= KDBUS_ATTACH_NAMES;
1527 if (mask & SD_BUS_CREDS_DESCRIPTION)
1528 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1530 if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
1531 m |= KDBUS_ATTACH_AUXGROUPS;
1536 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1537 struct kdbus_cmd_make *make;
1538 struct kdbus_item *n;
1545 fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1550 make = alloca0_align(offsetof(struct kdbus_cmd_make, items) +
1551 ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
1552 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
1553 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
1554 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
1557 make->size = offsetof(struct kdbus_cmd_make, items);
1559 /* Set the bloom parameters */
1561 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1562 sizeof(struct kdbus_bloom_parameter);
1563 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1564 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1565 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1567 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1568 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1570 make->size += ALIGN8(n->size);
1572 /* The busses we create make no restrictions on what metadata
1573 * peers can read from incoming messages. */
1574 n = KDBUS_ITEM_NEXT(n);
1575 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1576 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1577 n->data64[0] = _KDBUS_ATTACH_ANY;
1578 make->size += ALIGN8(n->size);
1580 /* Provide all metadata via bus-owner queries */
1581 n = KDBUS_ITEM_NEXT(n);
1582 n->type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
1583 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1584 n->data64[0] = _KDBUS_ATTACH_ANY;
1585 make->size += ALIGN8(n->size);
1587 /* Set the a good name */
1588 n = KDBUS_ITEM_NEXT(n);
1589 sprintf(n->str, UID_FMT "-%s", getuid(), name);
1590 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1591 n->type = KDBUS_ITEM_MAKE_NAME;
1592 make->size += ALIGN8(n->size);
1594 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1596 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1604 p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
1616 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1623 len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1630 p = newa(char, len);
1632 sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1634 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1648 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1649 _cleanup_free_ char *path = NULL;
1650 struct kdbus_cmd_make *make;
1651 struct kdbus_item *n;
1655 fd = bus_kernel_open_bus_fd(bus_name, &path);
1659 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items)) +
1660 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
1662 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1663 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1666 sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
1667 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1668 n->type = KDBUS_ITEM_MAKE_NAME;
1669 make->size += ALIGN8(n->size);
1672 if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1680 p = strjoin(dirname(path), "/", name, NULL);
1692 int bus_kernel_try_close(sd_bus *bus) {
1694 assert(bus->is_kernel);
1696 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1702 int bus_kernel_drop_one(int fd) {
1703 struct kdbus_cmd_recv recv = {
1704 .size = sizeof(recv),
1705 .flags = KDBUS_RECV_DROP,
1710 if (ioctl(fd, KDBUS_CMD_RECV, &recv) < 0)
1716 int bus_kernel_realize_attach_flags(sd_bus *bus) {
1717 struct kdbus_cmd_update *update;
1718 struct kdbus_item *n;
1721 assert(bus->is_kernel);
1723 update = alloca0_align(offsetof(struct kdbus_cmd_update, items) +
1724 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
1728 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1729 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1730 n->data64[0] = bus->attach_flags;
1733 offsetof(struct kdbus_cmd_update, items) +
1736 if (ioctl(bus->input_fd, KDBUS_CMD_CONN_UPDATE, update) < 0)
1742 int bus_kernel_fix_attach_mask(void) {
1743 _cleanup_free_ char *mask = NULL;
1744 uint64_t m = (uint64_t) -1;
1748 /* By default we don't want any kdbus metadata fields to be
1749 * suppressed, hence we reset the kernel mask for it to
1750 * (uint64_t) -1. If the module argument was overwritten by
1751 * the kernel cmdline, we leave it as is. */
1753 r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask);
1755 return log_warning_errno(r, "Failed to read kernel command line: %m");
1758 sprintf(buf, "0x%" PRIx64 "\n", m);
1759 r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf);
1761 return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
1762 "Failed to write kdbus attach mask: %m");
1768 int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
1769 struct kdbus_cmd_info cmd = {
1770 .size = sizeof(struct kdbus_cmd_info),
1772 struct kdbus_info *info;
1773 struct kdbus_item *item;
1779 assert(bus->is_kernel);
1781 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
1785 info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset);
1787 KDBUS_ITEM_FOREACH(item, info, items)
1788 if (item->type == KDBUS_ITEM_MAKE_NAME) {
1789 r = free_and_strdup(&n, item->str);
1793 bus_kernel_cmd_free(bus, cmd.offset);