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 POSIX
33 * version which is really broken. We prefer GNU basename(). */
39 #include "memfd-util.h"
40 #include "capability.h"
42 #include "formats-util.h"
44 #include "bus-internal.h"
45 #include "bus-message.h"
46 #include "bus-kernel.h"
47 #include "bus-bloom.h"
49 #include "bus-label.h"
51 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
53 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
59 if (!startswith(s, ":1."))
62 r = safe_atou64(s + 3, id);
69 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
75 /* Note that p can be NULL, which encodes a region full of
76 * zeroes, which is useful to optimize certain padding
79 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
80 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
81 (*d)->vec.address = PTR_TO_UINT64(p);
84 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
87 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t start, size_t sz) {
93 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
94 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
95 (*d)->memfd.fd = memfd;
96 (*d)->memfd.start = start;
97 (*d)->memfd.size = sz;
99 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
102 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
108 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
109 (*d)->type = KDBUS_ITEM_DST_NAME;
110 memcpy((*d)->str, s, length + 1);
112 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
115 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
116 struct kdbus_item *i;
122 i->size = offsetof(struct kdbus_item, bloom_filter) +
123 offsetof(struct kdbus_bloom_filter, data) +
125 i->type = KDBUS_ITEM_BLOOM_FILTER;
127 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
129 return &i->bloom_filter;
132 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
138 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
139 (*d)->type = KDBUS_ITEM_FDS;
140 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
142 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
145 static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
146 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
154 e = stpcpy(buf, "arg");
156 *(e++) = '0' + (char) i;
158 *(e++) = '0' + (char) (i / 10);
159 *(e++) = '0' + (char) (i % 10);
163 bloom_add_pair(data, size, n_hash, buf, t);
165 strcpy(e, "-dot-prefix");
166 bloom_add_prefixes(data, size, n_hash, buf, t, '.');
167 strcpy(e, "-slash-prefix");
168 bloom_add_prefixes(data, size, n_hash, buf, t, '/');
171 static void add_bloom_arg_has(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
172 char buf[sizeof("arg")-1 + 2 + sizeof("-has")];
180 e = stpcpy(buf, "arg");
182 *(e++) = '0' + (char) i;
184 *(e++) = '0' + (char) (i / 10);
185 *(e++) = '0' + (char) (i % 10);
189 bloom_add_pair(data, size, n_hash, buf, t);
192 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
201 memzero(data, m->bus->bloom_size);
202 bloom->generation = 0;
204 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
207 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
209 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
211 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
212 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
213 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
216 r = sd_bus_message_rewind(m, true);
220 for (i = 0; i < 64; i++) {
221 const char *t, *contents;
224 r = sd_bus_message_peek_type(m, &type, &contents);
228 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
230 /* The bloom filter includes simple strings of any kind */
231 r = sd_bus_message_read_basic(m, type, &t);
235 add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
238 if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
240 /* As well as array of simple strings of any kinds */
241 r = sd_bus_message_enter_container(m, type, contents);
245 while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
246 add_bloom_arg_has(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
250 r = sd_bus_message_exit_container(m);
255 /* Stop adding to bloom filter as soon as we
256 * run into the first argument we cannot add
264 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
265 struct bus_body_part *part;
266 struct kdbus_item *d;
267 const char *destination;
278 /* We put this together only once, if this message is reused
279 * we reuse the earlier-built version */
283 destination = m->destination ?: m->destination_ptr;
286 r = bus_kernel_parse_unique_name(destination, &unique);
294 sz = offsetof(struct kdbus_msg, items);
296 /* Add in fixed header, fields header and payload */
297 sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) +
298 MAX(sizeof(struct kdbus_vec),
299 sizeof(struct kdbus_memfd)));
301 /* Add space for bloom filter */
302 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
303 offsetof(struct kdbus_bloom_filter, data) +
306 /* Add in well-known destination header */
308 dl = strlen(destination);
309 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
312 /* Add space for unix fds */
314 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
316 m->kdbus = memalign(8, sz);
322 m->free_kdbus = true;
323 memzero(m->kdbus, sz);
326 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
327 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) |
328 ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0);
331 /* verify_destination_id will usually be 0, which makes the kernel driver only look
332 * at the provided well-known name. Otherwise, the kernel will make sure the provided
333 * destination id matches the owner of the provided weel-known-name, and fail if they
334 * differ. Currently, this is only needed for bus-proxyd. */
335 m->kdbus->dst_id = m->verify_destination_id;
337 m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
339 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
340 m->kdbus->cookie = m->header->dbus2.cookie;
341 m->kdbus->priority = m->priority;
343 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
344 m->kdbus->cookie_reply = m->reply_cookie;
348 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
349 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
350 m->timeout * NSEC_PER_USEC;
356 append_destination(&d, destination, dl);
358 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
360 MESSAGE_FOREACH_PART(part, i, m) {
362 /* If this is padding then simply send a
363 * vector with a NULL data pointer which the
364 * kernel will just pass through. This is the
365 * most efficient way to encode zeroes */
367 append_payload_vec(&d, NULL, part->size);
371 if (part->memfd >= 0 && part->sealed && destination) {
372 /* Try to send a memfd, if the part is
373 * sealed and this is not a broadcast. Since we can only */
375 append_payload_memfd(&d, part->memfd, part->memfd_offset, part->size);
379 /* Otherwise, let's send a vector to the actual data.
380 * For that, we need to map it first. */
381 r = bus_body_part_map(part);
385 append_payload_vec(&d, part->data, part->size);
388 if (m->header->type == SD_BUS_MESSAGE_SIGNAL) {
389 struct kdbus_bloom_filter *bloom;
391 bloom = append_bloom(&d, m->bus->bloom_size);
392 r = bus_message_setup_bloom(m, bloom);
398 append_fds(&d, m->fds, m->n_fds);
400 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
401 assert(m->kdbus->size <= sz);
410 static void unset_memfds(struct sd_bus_message *m) {
411 struct bus_body_part *part;
416 /* Make sure the memfds are not freed twice */
417 MESSAGE_FOREACH_PART(part, i, m)
418 if (part->memfd >= 0)
422 static void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) {
429 if (!(bus->attach_flags & KDBUS_ATTACH_TIMESTAMP))
432 m->realtime = ts->realtime_ns / NSEC_PER_USEC;
433 m->monotonic = ts->monotonic_ns / NSEC_PER_USEC;
434 m->seqnum = ts->seqnum;
437 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
438 sd_bus_message *m = NULL;
439 struct kdbus_item *d;
441 _cleanup_free_ int *fds = NULL;
442 struct bus_header *header = NULL;
444 size_t header_size = 0, footer_size = 0;
445 size_t n_bytes = 0, idx = 0;
446 const char *destination = NULL, *seclabel = NULL;
447 bool last_was_memfd = false;
452 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
454 KDBUS_ITEM_FOREACH(d, k, items) {
457 l = d->size - offsetof(struct kdbus_item, data);
461 case KDBUS_ITEM_PAYLOAD_OFF:
463 header = (struct bus_header*)((uint8_t*) k + d->vec.offset);
464 header_size = d->vec.size;
467 footer = (uint8_t*) k + d->vec.offset;
468 footer_size = d->vec.size;
470 n_bytes += d->vec.size;
471 last_was_memfd = false;
474 case KDBUS_ITEM_PAYLOAD_MEMFD:
475 if (!header) /* memfd cannot be first part */
478 n_bytes += d->memfd.size;
479 last_was_memfd = true;
482 case KDBUS_ITEM_FDS: {
487 f = realloc(fds, sizeof(int) * (n_fds + j));
492 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
497 case KDBUS_ITEM_SECLABEL:
503 if (last_was_memfd) /* memfd cannot be last part */
509 if (header_size < sizeof(struct bus_header))
512 /* on kdbus we only speak native endian gvariant, never dbus1
513 * marshalling or reverse endian */
514 if (header->version != 2 ||
515 header->endian != BUS_NATIVE_ENDIAN)
518 r = bus_message_from_header(
528 /* The well-known names list is different from the other
529 credentials. If we asked for it, but nothing is there, this
530 means that the list of well-known names is simply empty, not
531 that we lack any data */
533 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
535 KDBUS_ITEM_FOREACH(d, k, items) {
538 l = d->size - offsetof(struct kdbus_item, data);
542 case KDBUS_ITEM_PAYLOAD_OFF: {
545 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
547 if (idx + d->vec.size > begin_body) {
548 struct bus_body_part *part;
550 /* Contains body material */
552 part = message_append_part(m);
558 /* A -1 offset is NUL padding. */
559 part->is_zero = d->vec.offset == ~0ULL;
561 if (idx >= begin_body) {
563 part->data = (uint8_t* )k + d->vec.offset;
564 part->size = d->vec.size;
567 part->data = (uint8_t*) k + d->vec.offset + (begin_body - idx);
568 part->size = d->vec.size - (begin_body - idx);
578 case KDBUS_ITEM_PAYLOAD_MEMFD: {
579 struct bus_body_part *part;
581 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
586 part = message_append_part(m);
592 part->memfd = d->memfd.fd;
593 part->memfd_offset = d->memfd.start;
594 part->size = d->memfd.size;
597 idx += d->memfd.size;
601 case KDBUS_ITEM_PIDS:
603 /* The PID/TID might be missing, when the data
604 * is faked by a bus proxy and it lacks that
605 * information about the real client (since
606 * SO_PEERCRED is used for that). Also kernel
607 * namespacing might make some of this data
608 * unavailable when untranslatable. */
610 if (d->pids.pid > 0) {
611 m->creds.pid = (pid_t) d->pids.pid;
612 m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
615 if (d->pids.tid > 0) {
616 m->creds.tid = (pid_t) d->pids.tid;
617 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
620 if (d->pids.ppid > 0) {
621 m->creds.ppid = (pid_t) d->pids.ppid;
622 m->creds.mask |= SD_BUS_CREDS_PPID & bus->creds_mask;
623 } else if (d->pids.pid == 1) {
625 m->creds.mask |= SD_BUS_CREDS_PPID & bus->creds_mask;
630 case KDBUS_ITEM_CREDS:
632 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
633 * missing too (see above). */
635 if ((uid_t) d->creds.uid != UID_INVALID) {
636 m->creds.uid = (uid_t) d->creds.uid;
637 m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
640 if ((uid_t) d->creds.euid != UID_INVALID) {
641 m->creds.euid = (uid_t) d->creds.euid;
642 m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
645 if ((uid_t) d->creds.suid != UID_INVALID) {
646 m->creds.suid = (uid_t) d->creds.suid;
647 m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
650 if ((uid_t) d->creds.fsuid != UID_INVALID) {
651 m->creds.fsuid = (uid_t) d->creds.fsuid;
652 m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
655 if ((gid_t) d->creds.gid != GID_INVALID) {
656 m->creds.gid = (gid_t) d->creds.gid;
657 m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
660 if ((gid_t) d->creds.egid != GID_INVALID) {
661 m->creds.egid = (gid_t) d->creds.egid;
662 m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
665 if ((gid_t) d->creds.sgid != GID_INVALID) {
666 m->creds.sgid = (gid_t) d->creds.sgid;
667 m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
670 if ((gid_t) d->creds.fsgid != GID_INVALID) {
671 m->creds.fsgid = (gid_t) d->creds.fsgid;
672 m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
677 case KDBUS_ITEM_TIMESTAMP:
678 message_set_timestamp(bus, m, &d->timestamp);
681 case KDBUS_ITEM_PID_COMM:
682 m->creds.comm = d->str;
683 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
686 case KDBUS_ITEM_TID_COMM:
687 m->creds.tid_comm = d->str;
688 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
692 m->creds.exe = d->str;
693 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
696 case KDBUS_ITEM_CMDLINE:
697 m->creds.cmdline = d->str;
698 m->creds.cmdline_size = l;
699 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
702 case KDBUS_ITEM_CGROUP:
703 m->creds.cgroup = d->str;
704 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;
706 r = bus_get_root_path(bus);
710 m->creds.cgroup_root = bus->cgroup_root;
713 case KDBUS_ITEM_AUDIT:
714 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
715 m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
717 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
718 m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
721 case KDBUS_ITEM_CAPS:
722 if (d->caps.last_cap != cap_last_cap() ||
723 d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) {
728 m->creds.capability = d->caps.caps;
729 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;
732 case KDBUS_ITEM_DST_NAME:
733 if (!service_name_is_valid(d->str)) {
738 destination = d->str;
741 case KDBUS_ITEM_OWNED_NAME:
742 if (!service_name_is_valid(d->name.name)) {
747 if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
751 /* We just extend the array here, but
752 * do not allocate the strings inside
753 * of it, instead we just point to our
754 * buffer directly. */
755 n = strv_length(m->creds.well_known_names);
756 wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*));
762 wkn[n] = d->name.name;
764 m->creds.well_known_names = wkn;
766 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
770 case KDBUS_ITEM_CONN_DESCRIPTION:
771 m->creds.description = d->str;
772 m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
775 case KDBUS_ITEM_AUXGROUPS:
777 if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
781 n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
788 for (i = 0; i < n; i++)
791 m->creds.supplementary_gids = g;
792 m->creds.n_supplementary_gids = n;
793 m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
799 case KDBUS_ITEM_SECLABEL:
800 case KDBUS_ITEM_BLOOM_FILTER:
804 log_debug("Got unknown field from kernel %llu", d->type);
808 /* If we requested the list of well-known names to be appended
809 * and the sender had none no item for it will be
810 * attached. However, this does *not* mean that the kernel
811 * didn't want to provide this information to us. Hence, let's
812 * explicitly mark this information as available if it was
814 m->creds.mask |= bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES;
816 r = bus_message_parse_fields(m);
820 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
821 if ((uint64_t) m->header->dbus2.cookie != k->cookie) {
826 /* Refuse messages where the reply flag doesn't match up */
827 if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_EXPECT_REPLY)) {
832 /* Refuse reply messages where the reply cookie doesn't match up */
833 if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) {
838 /* Refuse messages where the autostart flag doesn't match up */
839 if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_NO_AUTO_START)) {
844 /* Override information from the user header with data from the kernel */
845 if (k->src_id == KDBUS_SRC_ID_KERNEL)
846 bus_message_set_sender_driver(bus, m);
848 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
849 m->sender = m->creds.unique_name = m->sender_buffer;
853 m->destination = destination;
854 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
855 m->destination = NULL;
856 else if (k->dst_id == KDBUS_DST_ID_NAME)
857 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
859 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
860 m->destination = m->destination_buffer;
863 /* We take possession of the kmsg struct now */
865 m->release_kdbus = true;
869 bus->rqueue[bus->rqueue_size++] = m;
875 sd_bus_message_unref(m);
880 int bus_kernel_take_fd(sd_bus *b) {
881 struct kdbus_bloom_parameter *bloom = NULL;
882 struct kdbus_item *items, *item;
883 struct kdbus_cmd_hello *hello;
884 _cleanup_free_ char *g = NULL;
886 size_t l = 0, m = 0, sz;
896 if (b->description) {
897 g = bus_label_escape(b->description);
905 /* If no name is explicitly set, we'll include a hint
906 * indicating the library implementation, a hint which
907 * kind of bus this is and the thread name */
909 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
912 name = b->is_system ? "sd-system" :
913 b->is_user ? "sd-user" : "sd";
915 _cleanup_free_ char *e = NULL;
917 e = bus_label_escape(pr);
921 g = strappend(b->is_system ? "sd-system-" :
922 b->is_user ? "sd-user-" : "sd-",
930 b->description = bus_label_unescape(name);
937 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
938 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
940 if (b->fake_creds_valid)
941 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
943 if (b->fake_pids_valid)
944 sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
947 l = strlen(b->fake_label);
948 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
951 hello = alloca0_align(sz, 8);
953 hello->flags = b->hello_flags;
954 hello->attach_flags_send = _KDBUS_ATTACH_ANY;
955 hello->attach_flags_recv = b->attach_flags;
956 hello->pool_size = KDBUS_POOL_SIZE;
960 item->size = offsetof(struct kdbus_item, str) + m + 1;
961 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
962 memcpy(item->str, name, m + 1);
963 item = KDBUS_ITEM_NEXT(item);
965 if (b->fake_creds_valid) {
966 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
967 item->type = KDBUS_ITEM_CREDS;
968 item->creds = b->fake_creds;
970 item = KDBUS_ITEM_NEXT(item);
973 if (b->fake_pids_valid) {
974 item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
975 item->type = KDBUS_ITEM_PIDS;
976 item->pids = b->fake_pids;
978 item = KDBUS_ITEM_NEXT(item);
982 item->size = offsetof(struct kdbus_item, str) + l + 1;
983 item->type = KDBUS_ITEM_SECLABEL;
984 memcpy(item->str, b->fake_label, l+1);
987 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
990 /* If the ioctl is not supported we assume that the
991 * API version changed in a major incompatible way,
992 * let's indicate an API incompatibility in this
994 return -ESOCKTNOSUPPORT;
999 if (!b->kdbus_buffer) {
1000 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
1001 if (b->kdbus_buffer == MAP_FAILED) {
1002 b->kdbus_buffer = NULL;
1008 /* The higher 32bit of the bus_flags fields are considered
1009 * 'incompatible flags'. Refuse them all for now. */
1010 if (hello->bus_flags > 0xFFFFFFFFULL) {
1011 r = -ESOCKTNOSUPPORT;
1015 /* extract bloom parameters from items */
1016 items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset);
1017 KDBUS_FOREACH(item, items, hello->items_size) {
1018 switch (item->type) {
1019 case KDBUS_ITEM_BLOOM_PARAMETER:
1020 bloom = &item->bloom_parameter;
1025 if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) {
1030 b->bloom_size = (size_t) bloom->size;
1031 b->bloom_n_hash = (unsigned) bloom->n_hash;
1033 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
1038 b->unique_id = hello->id;
1040 b->is_kernel = true;
1041 b->bus_client = true;
1042 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
1043 b->message_version = 2;
1044 b->message_endian = BUS_NATIVE_ENDIAN;
1046 /* the kernel told us the UUID of the underlying bus */
1047 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
1049 /* free returned items */
1050 (void) bus_kernel_cmd_free(b, hello->offset);
1051 return bus_start_running(b);
1054 (void) bus_kernel_cmd_free(b, hello->offset);
1058 int bus_kernel_connect(sd_bus *b) {
1060 assert(b->input_fd < 0);
1061 assert(b->output_fd < 0);
1067 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
1068 if (b->input_fd < 0)
1071 b->output_fd = b->input_fd;
1073 return bus_kernel_take_fd(b);
1076 int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) {
1077 struct kdbus_cmd_free cmd = {
1078 .size = sizeof(cmd),
1084 assert(bus->is_kernel);
1086 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
1093 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
1094 struct kdbus_item *d;
1099 KDBUS_ITEM_FOREACH(d, k, items) {
1100 if (d->type == KDBUS_ITEM_FDS)
1101 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
1102 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1103 safe_close(d->memfd.fd);
1106 bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer);
1109 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
1110 struct kdbus_cmd_send cmd = { };
1115 assert(bus->state == BUS_RUNNING);
1117 /* If we can't deliver, we want room for the error message */
1118 r = bus_rqueue_make_room(bus);
1122 r = bus_message_setup_kmsg(bus, m);
1126 cmd.size = sizeof(cmd);
1127 cmd.msg_address = (uintptr_t)m->kdbus;
1129 /* If this is a synchronous method call, then let's tell the
1130 * kernel, so that it can pass CPU time/scheduling to the
1131 * destination for the time, if it wants to. If we
1132 * synchronously wait for the result anyway, we won't need CPU
1134 if (hint_sync_call) {
1135 m->kdbus->flags |= KDBUS_MSG_EXPECT_REPLY;
1136 cmd.flags |= KDBUS_SEND_SYNC_REPLY;
1139 r = ioctl(bus->output_fd, KDBUS_CMD_SEND, &cmd);
1141 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1142 sd_bus_message *reply;
1144 if (errno == EAGAIN || errno == EINTR)
1146 else if (errno == ENXIO || errno == ESRCH) {
1148 /* ENXIO: unique name not known
1149 * ESRCH: well-known name not known */
1151 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1152 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
1154 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
1158 } else if (errno == EADDRNOTAVAIL) {
1160 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1162 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1163 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
1165 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
1171 r = bus_message_new_synthetic_error(
1173 BUS_MESSAGE_COOKIE(m),
1180 r = bus_seal_synthetic_message(bus, reply);
1184 bus->rqueue[bus->rqueue_size++] = reply;
1186 } else if (hint_sync_call) {
1187 struct kdbus_msg *k;
1189 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + cmd.reply.offset);
1192 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1194 r = bus_kernel_make_message(bus, k);
1196 close_kdbus_msg(bus, k);
1198 /* Anybody can send us invalid messages, let's just drop them. */
1199 if (r == -EBADMSG || r == -EPROTOTYPE)
1200 log_debug_errno(r, "Ignoring invalid synchronous reply: %m");
1205 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1206 close_kdbus_msg(bus, k);
1213 static int push_name_owner_changed(
1216 const char *old_owner,
1217 const char *new_owner,
1218 const struct kdbus_timestamp *ts) {
1220 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1225 r = sd_bus_message_new_signal(
1228 "/org/freedesktop/DBus",
1229 "org.freedesktop.DBus",
1230 "NameOwnerChanged");
1234 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
1238 bus_message_set_sender_driver(bus, m);
1239 message_set_timestamp(bus, m, ts);
1241 r = bus_seal_synthetic_message(bus, m);
1245 bus->rqueue[bus->rqueue_size++] = m;
1251 static int translate_name_change(
1253 const struct kdbus_msg *k,
1254 const struct kdbus_item *d,
1255 const struct kdbus_timestamp *ts) {
1257 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
1263 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
1266 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
1268 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
1270 if (isempty(old_owner))
1275 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
1277 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts);
1280 static int translate_id_change(
1282 const struct kdbus_msg *k,
1283 const struct kdbus_item *d,
1284 const struct kdbus_timestamp *ts) {
1286 char owner[UNIQUE_NAME_MAX];
1292 sprintf(owner, ":1.%llu", d->id_change.id);
1294 return push_name_owner_changed(
1296 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1297 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL,
1301 static int translate_reply(
1303 const struct kdbus_msg *k,
1304 const struct kdbus_item *d,
1305 const struct kdbus_timestamp *ts) {
1307 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1314 r = bus_message_new_synthetic_error(
1317 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1318 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1319 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1324 message_set_timestamp(bus, m, ts);
1326 r = bus_seal_synthetic_message(bus, m);
1330 bus->rqueue[bus->rqueue_size++] = m;
1336 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1337 static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = {
1338 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1339 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1340 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1342 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1343 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1345 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1346 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1349 struct kdbus_item *d, *found = NULL;
1350 struct kdbus_timestamp *ts = NULL;
1354 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1356 KDBUS_ITEM_FOREACH(d, k, items) {
1357 if (d->type == KDBUS_ITEM_TIMESTAMP)
1359 else if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1364 log_debug("Got unknown field from kernel %llu", d->type);
1368 log_debug("Didn't find a kernel message to translate.");
1372 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found, ts);
1375 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1376 struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
1377 struct kdbus_msg *k;
1382 r = bus_rqueue_make_room(bus);
1386 if (hint_priority) {
1387 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1388 recv.priority = priority;
1391 r = ioctl(bus->input_fd, KDBUS_CMD_RECV, &recv);
1392 if (recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS)
1393 log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
1395 if (errno == EAGAIN)
1401 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.msg.offset);
1402 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1403 r = bus_kernel_make_message(bus, k);
1405 /* Anybody can send us invalid messages, let's just drop them. */
1406 if (r == -EBADMSG || r == -EPROTOTYPE) {
1407 log_debug_errno(r, "Ignoring invalid message: %m");
1412 close_kdbus_msg(bus, k);
1413 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL) {
1414 r = bus_kernel_translate_message(bus, k);
1415 close_kdbus_msg(bus, k);
1417 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1419 close_kdbus_msg(bus, k);
1422 return r < 0 ? r : 1;
1425 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1426 struct memfd_cache *c;
1433 if (!bus || !bus->is_kernel)
1436 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1438 if (bus->n_memfd_cache <= 0) {
1441 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1443 r = memfd_new(bus->description);
1453 c = &bus->memfd_cache[--bus->n_memfd_cache];
1456 assert(c->mapped == 0 || c->address);
1458 *address = c->address;
1459 *mapped = c->mapped;
1460 *allocated = c->allocated;
1463 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1468 static void close_and_munmap(int fd, void *address, size_t size) {
1470 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1475 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1476 struct memfd_cache *c;
1477 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1480 assert(mapped == 0 || address);
1482 if (!bus || !bus->is_kernel) {
1483 close_and_munmap(fd, address, mapped);
1487 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1489 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1490 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1492 close_and_munmap(fd, address, mapped);
1496 c = &bus->memfd_cache[bus->n_memfd_cache++];
1498 c->address = address;
1500 /* If overly long, let's return a bit to the OS */
1501 if (mapped > max_mapped) {
1502 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1503 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1504 c->mapped = c->allocated = max_mapped;
1507 c->allocated = allocated;
1510 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1513 void bus_kernel_flush_memfd(sd_bus *b) {
1518 for (i = 0; i < b->n_memfd_cache; i++)
1519 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1522 uint64_t request_name_flags_to_kdbus(uint64_t flags) {
1525 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1526 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1528 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1529 f |= KDBUS_NAME_REPLACE_EXISTING;
1531 if (flags & SD_BUS_NAME_QUEUE)
1532 f |= KDBUS_NAME_QUEUE;
1537 uint64_t attach_flags_to_kdbus(uint64_t mask) {
1540 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
1541 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
1542 m |= KDBUS_ATTACH_CREDS;
1544 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID))
1545 m |= KDBUS_ATTACH_PIDS;
1547 if (mask & SD_BUS_CREDS_COMM)
1548 m |= KDBUS_ATTACH_PID_COMM;
1550 if (mask & SD_BUS_CREDS_TID_COMM)
1551 m |= KDBUS_ATTACH_TID_COMM;
1553 if (mask & SD_BUS_CREDS_EXE)
1554 m |= KDBUS_ATTACH_EXE;
1556 if (mask & SD_BUS_CREDS_CMDLINE)
1557 m |= KDBUS_ATTACH_CMDLINE;
1559 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))
1560 m |= KDBUS_ATTACH_CGROUP;
1562 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1563 m |= KDBUS_ATTACH_CAPS;
1565 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1566 m |= KDBUS_ATTACH_SECLABEL;
1568 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1569 m |= KDBUS_ATTACH_AUDIT;
1571 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1572 m |= KDBUS_ATTACH_NAMES;
1574 if (mask & SD_BUS_CREDS_DESCRIPTION)
1575 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1577 if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
1578 m |= KDBUS_ATTACH_AUXGROUPS;
1583 /// UNNEEDED by elogind
1585 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1586 struct kdbus_cmd *make;
1587 struct kdbus_item *n;
1594 fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1599 make = alloca0_align(offsetof(struct kdbus_cmd, items) +
1600 ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
1601 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
1602 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
1605 make->size = offsetof(struct kdbus_cmd, items);
1607 /* Set the bloom parameters */
1609 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1610 sizeof(struct kdbus_bloom_parameter);
1611 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1612 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1613 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1615 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1616 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1618 make->size += ALIGN8(n->size);
1620 /* Provide all metadata via bus-owner queries */
1621 n = KDBUS_ITEM_NEXT(n);
1622 n->type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
1623 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1624 n->data64[0] = _KDBUS_ATTACH_ANY;
1625 make->size += ALIGN8(n->size);
1627 /* Set the a good name */
1628 n = KDBUS_ITEM_NEXT(n);
1629 sprintf(n->str, UID_FMT "-%s", getuid(), name);
1630 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1631 n->type = KDBUS_ITEM_MAKE_NAME;
1632 make->size += ALIGN8(n->size);
1634 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1636 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1639 /* Major API change? then the ioctls got shuffled around. */
1640 if (errno == ENOTTY)
1641 return -ESOCKTNOSUPPORT;
1649 p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
1662 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1669 len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1676 p = newa(char, len);
1678 sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1680 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1694 /// UNNEEDED by elogind
1696 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1697 _cleanup_free_ char *path = NULL;
1698 struct kdbus_cmd *make;
1699 struct kdbus_item *n;
1703 fd = bus_kernel_open_bus_fd(bus_name, &path);
1707 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd, items)) +
1708 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
1710 make->size = ALIGN8(offsetof(struct kdbus_cmd, items));
1711 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1714 sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
1715 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1716 n->type = KDBUS_ITEM_MAKE_NAME;
1717 make->size += ALIGN8(n->size);
1720 if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1728 p = strjoin(dirname(path), "/", name, NULL);
1741 int bus_kernel_try_close(sd_bus *bus) {
1742 struct kdbus_cmd byebye = { .size = sizeof(byebye) };
1745 assert(bus->is_kernel);
1747 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE, &byebye) < 0)
1753 /// UNNEEDED by elogind
1755 int bus_kernel_drop_one(int fd) {
1756 struct kdbus_cmd_recv recv = {
1757 .size = sizeof(recv),
1758 .flags = KDBUS_RECV_DROP,
1763 if (ioctl(fd, KDBUS_CMD_RECV, &recv) < 0)
1770 int bus_kernel_realize_attach_flags(sd_bus *bus) {
1771 struct kdbus_cmd *update;
1772 struct kdbus_item *n;
1775 assert(bus->is_kernel);
1777 update = alloca0_align(offsetof(struct kdbus_cmd, items) +
1778 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
1782 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1783 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1784 n->data64[0] = bus->attach_flags;
1787 offsetof(struct kdbus_cmd, items) +
1790 if (ioctl(bus->input_fd, KDBUS_CMD_UPDATE, update) < 0)
1796 int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
1797 struct kdbus_cmd_info cmd = {
1798 .size = sizeof(struct kdbus_cmd_info),
1800 struct kdbus_info *info;
1801 struct kdbus_item *item;
1807 assert(bus->is_kernel);
1809 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
1813 info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset);
1815 KDBUS_ITEM_FOREACH(item, info, items)
1816 if (item->type == KDBUS_ITEM_MAKE_NAME) {
1817 r = free_and_strdup(&n, item->str);
1821 bus_kernel_cmd_free(bus, cmd.offset);