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>
29 #include <sys/prctl.h>
31 /* When we include libgen.h because we need dirname() we immediately
32 * undefine basename() since libgen.h defines it as a macro to the XDG
33 * version which is really broken. */
39 #include "memfd-util.h"
40 #include "capability.h"
43 #include "bus-internal.h"
44 #include "bus-message.h"
45 #include "bus-kernel.h"
46 #include "bus-bloom.h"
48 #include "bus-label.h"
50 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
52 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
58 if (!startswith(s, ":1."))
61 r = safe_atou64(s + 3, id);
68 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
74 /* Note that p can be NULL, which encodes a region full of
75 * zeroes, which is useful to optimize certain padding
78 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
79 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
80 (*d)->vec.address = PTR_TO_UINT64(p);
83 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
86 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t start, size_t sz) {
92 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
93 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
94 (*d)->memfd.fd = memfd;
95 (*d)->memfd.start = start;
96 (*d)->memfd.size = sz;
98 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
101 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
107 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
108 (*d)->type = KDBUS_ITEM_DST_NAME;
109 memcpy((*d)->str, s, length + 1);
111 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
114 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
115 struct kdbus_item *i;
121 i->size = offsetof(struct kdbus_item, bloom_filter) +
122 offsetof(struct kdbus_bloom_filter, data) +
124 i->type = KDBUS_ITEM_BLOOM_FILTER;
126 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
128 return &i->bloom_filter;
131 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
137 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
138 (*d)->type = KDBUS_ITEM_FDS;
139 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
141 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
144 static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
145 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
153 e = stpcpy(buf, "arg");
155 *(e++) = '0' + (char) i;
157 *(e++) = '0' + (char) (i / 10);
158 *(e++) = '0' + (char) (i % 10);
162 bloom_add_pair(data, size, n_hash, buf, t);
164 strcpy(e, "-dot-prefix");
165 bloom_add_prefixes(data, size, n_hash, buf, t, '.');
166 strcpy(e, "-slash-prefix");
167 bloom_add_prefixes(data, size, n_hash, buf, t, '/');
170 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
179 memzero(data, m->bus->bloom_size);
180 bloom->generation = 0;
182 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
185 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
187 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
189 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
190 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
191 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
194 r = sd_bus_message_rewind(m, true);
198 for (i = 0; i < 64; i++) {
199 const char *t, *contents;
202 r = sd_bus_message_peek_type(m, &type, &contents);
206 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
208 /* The bloom filter includes simple strings of any kind */
209 r = sd_bus_message_read_basic(m, type, &t);
213 add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
214 } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
216 /* As well as array of simple strings of any kinds */
217 r = sd_bus_message_enter_container(m, type, contents);
221 while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
222 add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
226 r = sd_bus_message_exit_container(m);
231 /* Stop adding to bloom filter as soon as we
232 * run into the first argument we cannot add
240 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
241 struct bus_body_part *part;
242 struct kdbus_item *d;
243 const char *destination;
254 /* We put this together only once, if this message is reused
255 * we reuse the earlier-built version */
259 destination = m->destination ?: m->destination_ptr;
262 r = bus_kernel_parse_unique_name(destination, &unique);
270 sz = offsetof(struct kdbus_msg, items);
272 /* Add in fixed header, fields header and payload */
273 sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) +
274 MAX(sizeof(struct kdbus_vec),
275 sizeof(struct kdbus_memfd)));
277 /* Add space for bloom filter */
278 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
279 offsetof(struct kdbus_bloom_filter, data) +
282 /* Add in well-known destination header */
284 dl = strlen(destination);
285 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
288 /* Add space for unix fds */
290 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
292 m->kdbus = memalign(8, sz);
298 m->free_kdbus = true;
299 memzero(m->kdbus, sz);
302 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
303 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) |
304 ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0);
307 /* verify_destination_id will usually be 0, which makes the kernel driver only look
308 * at the provided well-known name. Otherwise, the kernel will make sure the provided
309 * destination id matches the owner of the provided weel-known-name, and fail if they
310 * differ. Currently, this is only needed for bus-proxyd. */
311 m->kdbus->dst_id = m->verify_destination_id;
313 m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
315 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
316 m->kdbus->cookie = m->header->dbus2.cookie;
317 m->kdbus->priority = m->priority;
319 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
320 m->kdbus->cookie_reply = m->reply_cookie;
324 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
325 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
326 m->timeout * NSEC_PER_USEC;
332 append_destination(&d, destination, dl);
334 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
336 MESSAGE_FOREACH_PART(part, i, m) {
338 /* If this is padding then simply send a
339 * vector with a NULL data pointer which the
340 * kernel will just pass through. This is the
341 * most efficient way to encode zeroes */
343 append_payload_vec(&d, NULL, part->size);
347 if (part->memfd >= 0 && part->sealed && destination) {
348 /* Try to send a memfd, if the part is
349 * sealed and this is not a broadcast. Since we can only */
351 append_payload_memfd(&d, part->memfd, part->memfd_offset, part->size);
355 /* Otherwise, let's send a vector to the actual data.
356 * For that, we need to map it first. */
357 r = bus_body_part_map(part);
361 append_payload_vec(&d, part->data, part->size);
364 if (m->header->type == SD_BUS_MESSAGE_SIGNAL) {
365 struct kdbus_bloom_filter *bloom;
367 bloom = append_bloom(&d, m->bus->bloom_size);
368 r = bus_message_setup_bloom(m, bloom);
374 append_fds(&d, m->fds, m->n_fds);
376 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
377 assert(m->kdbus->size <= sz);
386 static void unset_memfds(struct sd_bus_message *m) {
387 struct bus_body_part *part;
392 /* Make sure the memfds are not freed twice */
393 MESSAGE_FOREACH_PART(part, i, m)
394 if (part->memfd >= 0)
398 static void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) {
405 if (!(bus->attach_flags & KDBUS_ATTACH_TIMESTAMP))
408 m->realtime = ts->realtime_ns / NSEC_PER_USEC;
409 m->monotonic = ts->monotonic_ns / NSEC_PER_USEC;
410 m->seqnum = ts->seqnum;
413 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
414 sd_bus_message *m = NULL;
415 struct kdbus_item *d;
417 _cleanup_free_ int *fds = NULL;
418 struct bus_header *header = NULL;
420 size_t header_size = 0, footer_size = 0;
421 size_t n_bytes = 0, idx = 0;
422 const char *destination = NULL, *seclabel = NULL;
423 bool last_was_memfd = false;
428 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
430 KDBUS_ITEM_FOREACH(d, k, items) {
433 l = d->size - offsetof(struct kdbus_item, data);
437 case KDBUS_ITEM_PAYLOAD_OFF:
439 header = (struct bus_header*)((uint8_t*) k + d->vec.offset);
440 header_size = d->vec.size;
443 footer = (uint8_t*) k + d->vec.offset;
444 footer_size = d->vec.size;
446 n_bytes += d->vec.size;
447 last_was_memfd = false;
450 case KDBUS_ITEM_PAYLOAD_MEMFD:
451 if (!header) /* memfd cannot be first part */
454 n_bytes += d->memfd.size;
455 last_was_memfd = true;
458 case KDBUS_ITEM_FDS: {
463 f = realloc(fds, sizeof(int) * (n_fds + j));
468 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
473 case KDBUS_ITEM_SECLABEL:
479 if (last_was_memfd) /* memfd cannot be last part */
485 if (header_size < sizeof(struct bus_header))
488 /* on kdbus we only speak native endian gvariant, never dbus1
489 * marshalling or reverse endian */
490 if (header->version != 2 ||
491 header->endian != BUS_NATIVE_ENDIAN)
494 r = bus_message_from_header(
505 /* The well-known names list is different from the other
506 credentials. If we asked for it, but nothing is there, this
507 means that the list of well-known names is simply empty, not
508 that we lack any data */
510 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
512 KDBUS_ITEM_FOREACH(d, k, items) {
515 l = d->size - offsetof(struct kdbus_item, data);
519 case KDBUS_ITEM_PAYLOAD_OFF: {
522 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
524 if (idx + d->vec.size > begin_body) {
525 struct bus_body_part *part;
527 /* Contains body material */
529 part = message_append_part(m);
535 /* A -1 offset is NUL padding. */
536 part->is_zero = d->vec.offset == ~0ULL;
538 if (idx >= begin_body) {
540 part->data = (uint8_t* )k + d->vec.offset;
541 part->size = d->vec.size;
544 part->data = (uint8_t*) k + d->vec.offset + (begin_body - idx);
545 part->size = d->vec.size - (begin_body - idx);
555 case KDBUS_ITEM_PAYLOAD_MEMFD: {
556 struct bus_body_part *part;
558 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
563 part = message_append_part(m);
569 part->memfd = d->memfd.fd;
570 part->memfd_offset = d->memfd.start;
571 part->size = d->memfd.size;
574 idx += d->memfd.size;
578 case KDBUS_ITEM_PIDS:
580 /* The PID/TID might be missing, when the data
581 * is faked by a bus proxy and it lacks that
582 * information about the real client (since
583 * SO_PEERCRED is used for that). Also kernel
584 * namespacing might make some of this data
585 * unavailable when untranslatable. */
587 if (d->pids.pid > 0) {
588 m->creds.pid = (pid_t) d->pids.pid;
589 m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
592 if (d->pids.tid > 0) {
593 m->creds.tid = (pid_t) d->pids.tid;
594 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
599 case KDBUS_ITEM_CREDS:
601 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
602 * missing too (see above). */
604 if ((uid_t) d->creds.uid != UID_INVALID) {
605 m->creds.uid = (uid_t) d->creds.uid;
606 m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
609 if ((uid_t) d->creds.euid != UID_INVALID) {
610 m->creds.euid = (uid_t) d->creds.euid;
611 m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
614 if ((uid_t) d->creds.suid != UID_INVALID) {
615 m->creds.suid = (uid_t) d->creds.suid;
616 m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
619 if ((uid_t) d->creds.fsuid != UID_INVALID) {
620 m->creds.fsuid = (uid_t) d->creds.fsuid;
621 m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
624 if ((gid_t) d->creds.gid != GID_INVALID) {
625 m->creds.gid = (gid_t) d->creds.gid;
626 m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
629 if ((gid_t) d->creds.egid != GID_INVALID) {
630 m->creds.egid = (gid_t) d->creds.egid;
631 m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
634 if ((gid_t) d->creds.sgid != GID_INVALID) {
635 m->creds.sgid = (gid_t) d->creds.sgid;
636 m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
639 if ((gid_t) d->creds.fsgid != GID_INVALID) {
640 m->creds.fsgid = (gid_t) d->creds.fsgid;
641 m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
646 case KDBUS_ITEM_TIMESTAMP:
647 message_set_timestamp(bus, m, &d->timestamp);
650 case KDBUS_ITEM_PID_COMM:
651 m->creds.comm = d->str;
652 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
655 case KDBUS_ITEM_TID_COMM:
656 m->creds.tid_comm = d->str;
657 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
661 m->creds.exe = d->str;
662 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
665 case KDBUS_ITEM_CMDLINE:
666 m->creds.cmdline = d->str;
667 m->creds.cmdline_size = l;
668 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
671 case KDBUS_ITEM_CGROUP:
672 m->creds.cgroup = d->str;
673 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;
675 r = bus_get_root_path(bus);
679 m->creds.cgroup_root = bus->cgroup_root;
682 case KDBUS_ITEM_AUDIT:
683 if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
684 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
685 m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
688 if ((uid_t) d->audit.loginuid != UID_INVALID) {
689 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
690 m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
694 case KDBUS_ITEM_CAPS:
695 if (d->caps.last_cap != cap_last_cap() ||
696 d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) {
701 m->creds.capability = d->caps.caps;
702 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;
705 case KDBUS_ITEM_DST_NAME:
706 if (!service_name_is_valid(d->str)) {
711 destination = d->str;
714 case KDBUS_ITEM_OWNED_NAME:
715 if (!service_name_is_valid(d->name.name)) {
720 if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
724 /* We just extend the array here, but
725 * do not allocate the strings inside
726 * of it, instead we just point to our
727 * buffer directly. */
728 n = strv_length(m->creds.well_known_names);
729 wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*));
735 wkn[n] = d->name.name;
737 m->creds.well_known_names = wkn;
739 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
743 case KDBUS_ITEM_CONN_DESCRIPTION:
744 m->creds.description = d->str;
745 m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
748 case KDBUS_ITEM_AUXGROUPS:
750 if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
751 assert_cc(sizeof(gid_t) == sizeof(uint32_t));
753 m->creds.n_supplementary_gids = (d->size - offsetof(struct kdbus_item, data32)) / sizeof(uint32_t);
754 m->creds.supplementary_gids = (gid_t*) d->data32;
755 m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
761 case KDBUS_ITEM_SECLABEL:
765 log_debug("Got unknown field from kernel %llu", d->type);
769 /* If we requested the list of well-known names to be appended
770 * and the sender had none no item for it will be
771 * attached. However, this does *not* mean that the kernel
772 * didn't want to provide this information to us. Hence, let's
773 * explicitly mark this information as available if it was
775 m->creds.mask |= bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES;
777 r = bus_message_parse_fields(m);
781 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
782 if ((uint64_t) m->header->dbus2.cookie != k->cookie) {
787 /* Refuse messages where the reply flag doesn't match up */
788 if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_EXPECT_REPLY)) {
793 /* Refuse reply messages where the reply cookie doesn't match up */
794 if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) {
799 /* Refuse messages where the autostart flag doesn't match up */
800 if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_NO_AUTO_START)) {
805 /* Override information from the user header with data from the kernel */
806 if (k->src_id == KDBUS_SRC_ID_KERNEL)
807 bus_message_set_sender_driver(bus, m);
809 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
810 m->sender = m->creds.unique_name = m->sender_buffer;
814 m->destination = destination;
815 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
816 m->destination = NULL;
817 else if (k->dst_id == KDBUS_DST_ID_NAME)
818 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
820 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
821 m->destination = m->destination_buffer;
824 /* We take possession of the kmsg struct now */
826 m->release_kdbus = true;
830 bus->rqueue[bus->rqueue_size++] = m;
836 sd_bus_message_unref(m);
841 int bus_kernel_take_fd(sd_bus *b) {
842 struct kdbus_bloom_parameter *bloom = NULL;
843 struct kdbus_item *items, *item;
844 struct kdbus_cmd_hello *hello;
845 _cleanup_free_ char *g = NULL;
847 size_t l = 0, m = 0, sz;
857 if (b->description) {
858 g = bus_label_escape(b->description);
866 /* If no name is explicitly set, we'll include a hint
867 * indicating the library implementation, a hint which
868 * kind of bus this is and the thread name */
870 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
873 name = b->is_system ? "sd-system" :
874 b->is_user ? "sd-user" : "sd";
876 _cleanup_free_ char *e = NULL;
878 e = bus_label_escape(pr);
882 g = strappend(b->is_system ? "sd-system-" :
883 b->is_user ? "sd-user-" : "sd-",
891 b->description = bus_label_unescape(name);
898 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
899 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
901 if (b->fake_creds_valid)
902 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
904 if (b->fake_pids_valid)
905 sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
908 l = strlen(b->fake_label);
909 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
912 hello = alloca0_align(sz, 8);
914 hello->flags = b->hello_flags;
915 hello->attach_flags_send = _KDBUS_ATTACH_ANY;
916 hello->attach_flags_recv = b->attach_flags;
917 hello->pool_size = KDBUS_POOL_SIZE;
921 item->size = offsetof(struct kdbus_item, str) + m + 1;
922 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
923 memcpy(item->str, name, m + 1);
924 item = KDBUS_ITEM_NEXT(item);
926 if (b->fake_creds_valid) {
927 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
928 item->type = KDBUS_ITEM_CREDS;
929 item->creds = b->fake_creds;
931 item = KDBUS_ITEM_NEXT(item);
934 if (b->fake_pids_valid) {
935 item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
936 item->type = KDBUS_ITEM_PIDS;
937 item->pids = b->fake_pids;
939 item = KDBUS_ITEM_NEXT(item);
943 item->size = offsetof(struct kdbus_item, str) + l + 1;
944 item->type = KDBUS_ITEM_SECLABEL;
945 memcpy(item->str, b->fake_label, l+1);
948 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
952 if (!b->kdbus_buffer) {
953 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
954 if (b->kdbus_buffer == MAP_FAILED) {
955 b->kdbus_buffer = NULL;
961 /* The higher 32bit of the bus_flags fields are considered
962 * 'incompatible flags'. Refuse them all for now. */
963 if (hello->bus_flags > 0xFFFFFFFFULL) {
968 /* extract bloom parameters from items */
969 items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset);
970 KDBUS_FOREACH(item, items, hello->items_size) {
971 switch (item->type) {
972 case KDBUS_ITEM_BLOOM_PARAMETER:
973 bloom = &item->bloom_parameter;
978 if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) {
983 b->bloom_size = (size_t) bloom->size;
984 b->bloom_n_hash = (unsigned) bloom->n_hash;
986 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
991 b->unique_id = hello->id;
994 b->bus_client = true;
995 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
996 b->message_version = 2;
997 b->message_endian = BUS_NATIVE_ENDIAN;
999 /* the kernel told us the UUID of the underlying bus */
1000 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
1002 /* free returned items */
1003 (void) bus_kernel_cmd_free(b, hello->offset);
1004 return bus_start_running(b);
1007 (void) bus_kernel_cmd_free(b, hello->offset);
1011 int bus_kernel_connect(sd_bus *b) {
1013 assert(b->input_fd < 0);
1014 assert(b->output_fd < 0);
1020 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
1021 if (b->input_fd < 0)
1024 b->output_fd = b->input_fd;
1026 return bus_kernel_take_fd(b);
1029 int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) {
1030 struct kdbus_cmd_free cmd = {
1031 .size = sizeof(cmd),
1037 assert(bus->is_kernel);
1039 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
1046 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
1047 struct kdbus_item *d;
1052 KDBUS_ITEM_FOREACH(d, k, items) {
1053 if (d->type == KDBUS_ITEM_FDS)
1054 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
1055 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1056 safe_close(d->memfd.fd);
1059 bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer);
1062 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
1063 struct kdbus_cmd_send cmd = { };
1068 assert(bus->state == BUS_RUNNING);
1070 /* If we can't deliver, we want room for the error message */
1071 r = bus_rqueue_make_room(bus);
1075 r = bus_message_setup_kmsg(bus, m);
1079 cmd.size = sizeof(cmd);
1080 cmd.msg_address = (uintptr_t)m->kdbus;
1082 /* If this is a synchronous method call, then let's tell the
1083 * kernel, so that it can pass CPU time/scheduling to the
1084 * destination for the time, if it wants to. If we
1085 * synchronously wait for the result anyway, we won't need CPU
1087 if (hint_sync_call) {
1088 m->kdbus->flags |= KDBUS_MSG_EXPECT_REPLY;
1089 cmd.flags |= KDBUS_SEND_SYNC_REPLY;
1092 r = ioctl(bus->output_fd, KDBUS_CMD_SEND, &cmd);
1094 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1095 sd_bus_message *reply;
1097 if (errno == EAGAIN || errno == EINTR)
1099 else if (errno == ENXIO || errno == ESRCH) {
1101 /* ENXIO: unique name not known
1102 * ESRCH: well-known name not known */
1104 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1105 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
1107 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
1111 } else if (errno == EADDRNOTAVAIL) {
1113 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1115 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1116 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
1118 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
1124 r = bus_message_new_synthetic_error(
1126 BUS_MESSAGE_COOKIE(m),
1133 r = bus_seal_synthetic_message(bus, reply);
1137 bus->rqueue[bus->rqueue_size++] = reply;
1139 } else if (hint_sync_call) {
1140 struct kdbus_msg *k;
1142 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + cmd.reply.offset);
1145 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1147 r = bus_kernel_make_message(bus, k);
1149 close_kdbus_msg(bus, k);
1151 /* Anybody can send us invalid messages, let's just drop them. */
1152 if (r == -EBADMSG || r == -EPROTOTYPE)
1153 log_debug_errno(r, "Ignoring invalid synchronous reply: %m");
1158 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1159 close_kdbus_msg(bus, k);
1166 static int push_name_owner_changed(
1169 const char *old_owner,
1170 const char *new_owner,
1171 const struct kdbus_timestamp *ts) {
1173 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1178 r = sd_bus_message_new_signal(
1181 "/org/freedesktop/DBus",
1182 "org.freedesktop.DBus",
1183 "NameOwnerChanged");
1187 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
1191 bus_message_set_sender_driver(bus, m);
1192 message_set_timestamp(bus, m, ts);
1194 r = bus_seal_synthetic_message(bus, m);
1198 bus->rqueue[bus->rqueue_size++] = m;
1204 static int translate_name_change(
1206 const struct kdbus_msg *k,
1207 const struct kdbus_item *d,
1208 const struct kdbus_timestamp *ts) {
1210 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
1216 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
1219 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
1221 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
1223 if (isempty(old_owner))
1228 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
1230 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts);
1233 static int translate_id_change(
1235 const struct kdbus_msg *k,
1236 const struct kdbus_item *d,
1237 const struct kdbus_timestamp *ts) {
1239 char owner[UNIQUE_NAME_MAX];
1245 sprintf(owner, ":1.%llu", d->id_change.id);
1247 return push_name_owner_changed(
1249 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1250 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL,
1254 static int translate_reply(
1256 const struct kdbus_msg *k,
1257 const struct kdbus_item *d,
1258 const struct kdbus_timestamp *ts) {
1260 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1267 r = bus_message_new_synthetic_error(
1270 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1271 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1272 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1277 message_set_timestamp(bus, m, ts);
1279 r = bus_seal_synthetic_message(bus, m);
1283 bus->rqueue[bus->rqueue_size++] = m;
1289 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1290 static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = {
1291 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1292 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1293 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1295 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1296 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1298 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1299 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1302 struct kdbus_item *d, *found = NULL;
1303 struct kdbus_timestamp *ts = NULL;
1307 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1309 KDBUS_ITEM_FOREACH(d, k, items) {
1310 if (d->type == KDBUS_ITEM_TIMESTAMP)
1313 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1318 log_debug("Got unknown field from kernel %llu", d->type);
1322 log_debug("Didn't find a kernel message to translate.");
1326 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found, ts);
1329 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1330 struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
1331 struct kdbus_msg *k;
1336 r = bus_rqueue_make_room(bus);
1340 if (hint_priority) {
1341 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1342 recv.priority = priority;
1345 r = ioctl(bus->input_fd, KDBUS_CMD_RECV, &recv);
1346 if (recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS)
1347 log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
1349 if (errno == EAGAIN)
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;
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, 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, 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;
1651 struct kdbus_item *n;
1655 fd = bus_kernel_open_bus_fd(bus_name, &path);
1659 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd, 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, 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) {
1693 struct kdbus_cmd byebye = { .size = sizeof(byebye) };
1696 assert(bus->is_kernel);
1698 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE, &byebye) < 0)
1704 int bus_kernel_drop_one(int fd) {
1705 struct kdbus_cmd_recv recv = {
1706 .size = sizeof(recv),
1707 .flags = KDBUS_RECV_DROP,
1712 if (ioctl(fd, KDBUS_CMD_RECV, &recv) < 0)
1718 int bus_kernel_realize_attach_flags(sd_bus *bus) {
1719 struct kdbus_cmd *update;
1720 struct kdbus_item *n;
1723 assert(bus->is_kernel);
1725 update = alloca0_align(offsetof(struct kdbus_cmd, items) +
1726 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
1730 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1731 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1732 n->data64[0] = bus->attach_flags;
1735 offsetof(struct kdbus_cmd, items) +
1738 if (ioctl(bus->input_fd, KDBUS_CMD_UPDATE, update) < 0)
1744 int bus_kernel_fix_attach_mask(void) {
1745 _cleanup_free_ char *mask = NULL;
1746 uint64_t m = (uint64_t) -1;
1750 /* By default we don't want any kdbus metadata fields to be
1751 * suppressed, hence we reset the kernel mask for it to
1752 * (uint64_t) -1. If the module argument was overwritten by
1753 * the kernel cmdline, we leave it as is. */
1755 r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask);
1757 return log_warning_errno(r, "Failed to read kernel command line: %m");
1760 sprintf(buf, "0x%" PRIx64 "\n", m);
1761 r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf);
1763 return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
1764 "Failed to write kdbus attach mask: %m");
1770 int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
1771 struct kdbus_cmd_info cmd = {
1772 .size = sizeof(struct kdbus_cmd_info),
1774 struct kdbus_info *info;
1775 struct kdbus_item *item;
1781 assert(bus->is_kernel);
1783 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
1787 info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset);
1789 KDBUS_ITEM_FOREACH(item, info, items)
1790 if (item->type == KDBUS_ITEM_MAKE_NAME) {
1791 r = free_and_strdup(&n, item->str);
1795 bus_kernel_cmd_free(bus, cmd.offset);