1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
30 #include <sys/prctl.h>
34 #include "memfd-util.h"
36 #include "bus-internal.h"
37 #include "bus-message.h"
38 #include "bus-kernel.h"
39 #include "bus-bloom.h"
41 #include "bus-label.h"
42 #include "cgroup-util.h"
44 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
46 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
52 if (!startswith(s, ":1."))
55 r = safe_atou64(s + 3, id);
62 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
68 /* Note that p can be NULL, which encodes a region full of
69 * zeroes, which is useful to optimize certain padding
72 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
73 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
74 (*d)->vec.address = PTR_TO_UINT64(p);
77 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
80 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
86 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
87 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
88 (*d)->memfd.fd = memfd;
89 (*d)->memfd.size = sz;
91 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
94 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
100 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
101 (*d)->type = KDBUS_ITEM_DST_NAME;
102 memcpy((*d)->str, s, length + 1);
104 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
107 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
108 struct kdbus_item *i;
114 i->size = offsetof(struct kdbus_item, bloom_filter) +
115 offsetof(struct kdbus_bloom_filter, data) +
117 i->type = KDBUS_ITEM_BLOOM_FILTER;
119 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
121 return &i->bloom_filter;
124 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
130 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
131 (*d)->type = KDBUS_ITEM_FDS;
132 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
134 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
137 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
146 memzero(data, m->bus->bloom_size);
147 bloom->generation = 0;
149 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
152 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
154 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
156 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
157 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
158 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
161 r = sd_bus_message_rewind(m, true);
165 for (i = 0; i < 64; i++) {
168 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
171 r = sd_bus_message_peek_type(m, &type, NULL);
175 if (type != SD_BUS_TYPE_STRING &&
176 type != SD_BUS_TYPE_OBJECT_PATH &&
177 type != SD_BUS_TYPE_SIGNATURE)
180 r = sd_bus_message_read_basic(m, type, &t);
184 e = stpcpy(buf, "arg");
186 *(e++) = '0' + (char) i;
188 *(e++) = '0' + (char) (i / 10);
189 *(e++) = '0' + (char) (i % 10);
193 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
195 strcpy(e, "-dot-prefix");
196 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
197 strcpy(e, "-slash-prefix");
198 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
204 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
205 struct bus_body_part *part;
206 struct kdbus_item *d;
207 const char *destination;
218 /* We put this together only once, if this message is reused
219 * we reuse the earlier-built version */
223 destination = m->destination ?: m->destination_ptr;
226 r = bus_kernel_parse_unique_name(destination, &unique);
234 sz = offsetof(struct kdbus_msg, items);
236 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
237 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
239 /* Add in fixed header, fields header and payload */
240 sz += (1 + m->n_body_parts) *
241 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
243 /* Add space for bloom filter */
244 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
245 offsetof(struct kdbus_bloom_filter, data) +
248 /* Add in well-known destination header */
250 dl = strlen(destination);
251 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
254 /* Add space for unix fds */
256 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
258 m->kdbus = memalign(8, sz);
264 m->free_kdbus = true;
265 memzero(m->kdbus, sz);
268 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
269 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
272 /* verify_destination_id will usually be 0, which makes the kernel driver only look
273 * at the provided well-known name. Otherwise, the kernel will make sure the provided
274 * destination id matches the owner of the provided weel-known-name, and fail if they
275 * differ. Currently, this is only needed for bus-proxyd. */
276 m->kdbus->dst_id = m->verify_destination_id;
278 m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
280 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
281 m->kdbus->cookie = (uint64_t) m->header->serial;
282 m->kdbus->priority = m->priority;
284 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
285 m->kdbus->cookie_reply = m->reply_cookie;
289 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
290 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
291 m->timeout * NSEC_PER_USEC;
297 append_destination(&d, destination, dl);
299 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
301 MESSAGE_FOREACH_PART(part, i, m) {
303 /* If this is padding then simply send a
304 * vector with a NULL data pointer which the
305 * kernel will just pass through. This is the
306 * most efficient way to encode zeroes */
308 append_payload_vec(&d, NULL, part->size);
312 if (part->memfd >= 0 && part->sealed && destination) {
313 /* Try to send a memfd, if the part is
314 * sealed and this is not a broadcast. Since we can only */
316 append_payload_memfd(&d, part->memfd, part->size);
320 /* Otherwise, let's send a vector to the actual data.
321 * For that, we need to map it first. */
322 r = bus_body_part_map(part);
326 append_payload_vec(&d, part->data, part->size);
329 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
330 struct kdbus_bloom_filter *bloom;
332 bloom = append_bloom(&d, m->bus->bloom_size);
333 r = bus_message_setup_bloom(m, bloom);
339 append_fds(&d, m->fds, m->n_fds);
341 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
342 assert(m->kdbus->size <= sz);
351 static void unset_memfds(struct sd_bus_message *m) {
352 struct bus_body_part *part;
357 /* Make sure the memfds are not freed twice */
358 MESSAGE_FOREACH_PART(part, i, m)
359 if (part->memfd >= 0)
363 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
364 sd_bus_message *m = NULL;
365 struct kdbus_item *d;
367 _cleanup_free_ int *fds = NULL;
368 struct bus_header *h = NULL;
369 size_t total, n_bytes = 0, idx = 0;
370 const char *destination = NULL, *seclabel = NULL;
375 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
377 KDBUS_ITEM_FOREACH(d, k, items) {
380 l = d->size - offsetof(struct kdbus_item, data);
384 case KDBUS_ITEM_PAYLOAD_OFF:
386 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
388 if (!bus_header_is_complete(h, d->vec.size))
392 n_bytes += d->vec.size;
395 case KDBUS_ITEM_PAYLOAD_MEMFD:
399 n_bytes += d->memfd.size;
402 case KDBUS_ITEM_FDS: {
407 f = realloc(fds, sizeof(int) * (n_fds + j));
412 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
417 case KDBUS_ITEM_SECLABEL:
426 r = bus_header_message_size(h, &total);
430 if (n_bytes != total)
433 /* on kdbus we only speak native endian gvariant, never dbus1
434 * marshalling or reverse endian */
435 if (h->version != 2 ||
436 h->endian != BUS_NATIVE_ENDIAN)
439 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
443 /* The well-known names list is different from the other
444 credentials. If we asked for it, but nothing is there, this
445 means that the list of well-known names is simply empty, not
446 that we lack any data */
448 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
450 KDBUS_ITEM_FOREACH(d, k, items) {
453 l = d->size - offsetof(struct kdbus_item, data);
457 case KDBUS_ITEM_PAYLOAD_OFF: {
460 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
462 if (idx + d->vec.size > begin_body) {
463 struct bus_body_part *part;
465 /* Contains body material */
467 part = message_append_part(m);
473 /* A -1 offset is NUL padding. */
474 part->is_zero = d->vec.offset == ~0ULL;
476 if (idx >= begin_body) {
478 part->data = (uint8_t *)k + d->vec.offset;
479 part->size = d->vec.size;
482 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
483 part->size = d->vec.size - (begin_body - idx);
493 case KDBUS_ITEM_PAYLOAD_MEMFD: {
494 struct bus_body_part *part;
496 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
501 part = message_append_part(m);
507 part->memfd = d->memfd.fd;
508 part->size = d->memfd.size;
511 idx += d->memfd.size;
515 case KDBUS_ITEM_PIDS:
517 /* The PID starttime/TID might be missing,
518 * when the data is faked by some data bus
519 * proxy and it lacks that information about
520 * the real client since SO_PEERCRED is used
523 if (d->pids.pid > 0) {
524 m->creds.pid = (pid_t) d->pids.pid;
525 m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
528 if (d->pids.starttime > 0) {
529 m->creds.pid_starttime = d->pids.starttime / NSEC_PER_USEC;
530 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
533 if (d->pids.tid > 0) {
534 m->creds.tid = (pid_t) d->pids.tid;
535 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
540 case KDBUS_ITEM_CREDS:
542 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
544 if ((uid_t) d->creds.uid != (uid_t) -1) {
545 m->creds.uid = (uid_t) d->creds.uid;
546 m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
549 if ((uid_t) d->creds.euid != (uid_t) -1) {
550 m->creds.euid = (uid_t) d->creds.euid;
551 m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
554 if ((uid_t) d->creds.suid != (uid_t) -1) {
555 m->creds.suid = (uid_t) d->creds.suid;
556 m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
559 if ((uid_t) d->creds.fsuid != (uid_t) -1) {
560 m->creds.fsuid = (uid_t) d->creds.fsuid;
561 m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
564 if ((gid_t) d->creds.gid != (gid_t) -1) {
565 m->creds.gid = (gid_t) d->creds.gid;
566 m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
569 if ((gid_t) d->creds.egid != (gid_t) -1) {
570 m->creds.egid = (gid_t) d->creds.egid;
571 m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
574 if ((gid_t) d->creds.sgid != (gid_t) -1) {
575 m->creds.sgid = (gid_t) d->creds.sgid;
576 m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
579 if ((gid_t) d->creds.fsgid != (gid_t) -1) {
580 m->creds.fsgid = (gid_t) d->creds.fsgid;
581 m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
586 case KDBUS_ITEM_TIMESTAMP:
588 if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
589 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
590 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
591 m->seqnum = d->timestamp.seqnum;
596 case KDBUS_ITEM_PID_COMM:
597 m->creds.comm = d->str;
598 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
601 case KDBUS_ITEM_TID_COMM:
602 m->creds.tid_comm = d->str;
603 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
607 m->creds.exe = d->str;
608 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
611 case KDBUS_ITEM_CMDLINE:
612 m->creds.cmdline = d->str;
613 m->creds.cmdline_size = l;
614 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
617 case KDBUS_ITEM_CGROUP:
618 m->creds.cgroup = d->str;
619 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;
621 r = bus_get_root_path(bus);
625 m->creds.cgroup_root = bus->cgroup_root;
629 case KDBUS_ITEM_AUDIT:
630 if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
631 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
632 m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
635 if ((uid_t) d->audit.loginuid != (uid_t) -1) {
636 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
637 m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
641 case KDBUS_ITEM_CAPS:
642 m->creds.capability = (uint8_t *) d->caps.caps;
643 m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps);
644 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;
647 case KDBUS_ITEM_DST_NAME:
648 if (!service_name_is_valid(d->str)) {
653 destination = d->str;
656 case KDBUS_ITEM_OWNED_NAME:
657 if (!service_name_is_valid(d->name.name)) {
662 if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
666 /* We just extend the array here, but
667 * do not allocate the strings inside
668 * of it, instead we just point to our
669 * buffer directly. */
670 n = strv_length(m->creds.well_known_names);
671 wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*));
677 wkn[n] = d->name.name;
679 m->creds.well_known_names = wkn;
681 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
685 case KDBUS_ITEM_CONN_DESCRIPTION:
686 m->creds.description = d->str;
687 m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
690 case KDBUS_ITEM_AUXGROUPS:
692 if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
693 assert_cc(sizeof(gid_t) == sizeof(uint32_t));
695 m->creds.n_supplementary_gids = (d->size - offsetof(struct kdbus_item, data32)) / sizeof(uint32_t);
696 m->creds.supplementary_gids = (gid_t*) d->data32;
697 m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
703 case KDBUS_ITEM_SECLABEL:
707 log_debug("Got unknown field from kernel %llu", d->type);
711 r = bus_message_parse_fields(m);
715 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
716 if ((uint64_t) m->header->serial != k->cookie) {
721 /* Refuse messages where the reply flag doesn't match up */
722 if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_FLAGS_EXPECT_REPLY)) {
727 /* Refuse reply messages where the reply cookie doesn't match up */
728 if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) {
733 /* Refuse messages where the autostart flag doesn't match up */
734 if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)) {
739 /* Override information from the user header with data from the kernel */
740 if (k->src_id == KDBUS_SRC_ID_KERNEL) {
741 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
742 m->creds.well_known_names_driver = true;
743 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
745 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
746 m->sender = m->creds.unique_name = m->sender_buffer;
750 m->destination = destination;
751 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
752 m->destination = NULL;
753 else if (k->dst_id == KDBUS_DST_ID_NAME)
754 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
756 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
757 m->destination = m->destination_buffer;
760 /* We take possession of the kmsg struct now */
762 m->release_kdbus = true;
766 bus->rqueue[bus->rqueue_size++] = m;
772 sd_bus_message_unref(m);
777 int bus_kernel_take_fd(sd_bus *b) {
778 struct kdbus_cmd_hello *hello;
779 struct kdbus_item *item;
780 _cleanup_free_ char *g = NULL;
782 size_t l = 0, m = 0, sz;
792 if (b->description) {
793 g = bus_label_escape(b->description);
801 /* If no name is explicitly set, we'll include a hint
802 * indicating the library implementation, a hint which
803 * kind of bus this is and the thread name */
805 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
808 name = b->is_system ? "sd-system" :
809 b->is_user ? "sd-user" : "sd";
811 _cleanup_free_ char *e = NULL;
813 e = bus_label_escape(pr);
817 g = strappend(b->is_system ? "sd-system-" :
818 b->is_user ? "sd-user-" : "sd-",
826 b->description = bus_label_unescape(name);
833 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
834 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
836 if (b->fake_creds_valid)
837 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
839 if (b->fake_pids_valid)
840 sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
843 l = strlen(b->fake_label);
844 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
847 hello = alloca0_align(sz, 8);
849 hello->flags = b->hello_flags;
850 hello->attach_flags_send = _KDBUS_ATTACH_ANY;
851 hello->attach_flags_recv = b->attach_flags;
852 hello->pool_size = KDBUS_POOL_SIZE;
856 item->size = offsetof(struct kdbus_item, str) + m + 1;
857 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
858 memcpy(item->str, name, m + 1);
859 item = KDBUS_ITEM_NEXT(item);
861 if (b->fake_creds_valid) {
862 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
863 item->type = KDBUS_ITEM_CREDS;
864 item->creds = b->fake_creds;
866 item = KDBUS_ITEM_NEXT(item);
869 if (b->fake_pids_valid) {
870 item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
871 item->type = KDBUS_ITEM_PIDS;
872 item->pids = b->fake_pids;
874 item = KDBUS_ITEM_NEXT(item);
878 item->size = offsetof(struct kdbus_item, str) + l + 1;
879 item->type = KDBUS_ITEM_SECLABEL;
880 memcpy(item->str, b->fake_label, l+1);
883 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
887 if (!b->kdbus_buffer) {
888 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
889 if (b->kdbus_buffer == MAP_FAILED) {
890 b->kdbus_buffer = NULL;
895 /* The higher 32bit of the bus_flags fields are considered
896 * 'incompatible flags'. Refuse them all for now. */
897 if (hello->bus_flags > 0xFFFFFFFFULL)
900 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
903 b->bloom_size = (size_t) hello->bloom.size;
904 b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
906 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
909 b->unique_id = hello->id;
912 b->bus_client = true;
913 b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
914 b->message_version = 2;
915 b->message_endian = BUS_NATIVE_ENDIAN;
917 /* the kernel told us the UUID of the underlying bus */
918 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
920 return bus_start_running(b);
923 int bus_kernel_connect(sd_bus *b) {
925 assert(b->input_fd < 0);
926 assert(b->output_fd < 0);
932 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
936 b->output_fd = b->input_fd;
938 return bus_kernel_take_fd(b);
941 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
942 struct kdbus_cmd_free cmd = {};
943 struct kdbus_item *d;
948 cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
950 KDBUS_ITEM_FOREACH(d, k, items) {
952 if (d->type == KDBUS_ITEM_FDS)
953 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
954 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
955 safe_close(d->memfd.fd);
958 (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
961 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
966 assert(bus->state == BUS_RUNNING);
968 /* If we can't deliver, we want room for the error message */
969 r = bus_rqueue_make_room(bus);
973 r = bus_message_setup_kmsg(bus, m);
977 /* If this is a synchronous method call, then let's tell the
978 * kernel, so that it can pass CPU time/scheduling to the
979 * destination for the time, if it wants to. If we
980 * synchronously wait for the result anyway, we won't need CPU
983 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
985 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
987 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
988 sd_bus_message *reply;
990 if (errno == EAGAIN || errno == EINTR)
992 else if (errno == ENXIO || errno == ESRCH) {
994 /* ENXIO: unique name not known
995 * ESRCH: well-known name not known */
997 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
998 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
1000 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
1004 } else if (errno == EADDRNOTAVAIL) {
1006 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1008 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1009 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
1011 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
1017 r = bus_message_new_synthetic_error(
1019 BUS_MESSAGE_COOKIE(m),
1026 r = bus_seal_synthetic_message(bus, reply);
1030 bus->rqueue[bus->rqueue_size++] = reply;
1032 } else if (hint_sync_call) {
1033 struct kdbus_msg *k;
1035 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
1038 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1040 r = bus_kernel_make_message(bus, k);
1042 close_kdbus_msg(bus, k);
1044 /* Anybody can send us invalid messages, let's just drop them. */
1045 if (r == -EBADMSG || r == -EPROTOTYPE)
1046 log_debug("Ignoring invalid message: %s", strerror(-r));
1051 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1052 close_kdbus_msg(bus, k);
1059 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
1060 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1065 r = sd_bus_message_new_signal(
1068 "/org/freedesktop/DBus",
1069 "org.freedesktop.DBus",
1070 "NameOwnerChanged");
1074 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
1078 m->sender = "org.freedesktop.DBus";
1079 m->creds.well_known_names_driver = true;
1080 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
1082 r = bus_seal_synthetic_message(bus, m);
1086 bus->rqueue[bus->rqueue_size++] = m;
1092 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1093 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
1099 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
1102 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
1104 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
1106 if (isempty(old_owner))
1111 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
1113 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
1116 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1117 char owner[UNIQUE_NAME_MAX];
1123 sprintf(owner, ":1.%llu", d->id_change.id);
1125 return push_name_owner_changed(
1127 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1128 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
1131 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1132 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1139 r = bus_message_new_synthetic_error(
1142 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1143 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1144 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1149 m->sender = "org.freedesktop.DBus";
1150 m->creds.well_known_names_driver = true;
1151 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
1153 r = bus_seal_synthetic_message(bus, m);
1157 bus->rqueue[bus->rqueue_size++] = m;
1163 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1164 struct kdbus_item *d, *found = NULL;
1166 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1167 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1168 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1169 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1171 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1172 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1174 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1175 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1180 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1182 KDBUS_ITEM_FOREACH(d, k, items) {
1183 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1188 log_debug("Got unknown field from kernel %llu", d->type);
1192 log_debug("Didn't find a kernel message to translate.");
1196 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
1199 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1200 struct kdbus_cmd_recv recv = {};
1201 struct kdbus_msg *k;
1206 r = bus_rqueue_make_room(bus);
1210 if (hint_priority) {
1211 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1212 recv.priority = priority;
1215 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1217 if (errno == EAGAIN)
1220 if (errno == EOVERFLOW) {
1221 log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
1228 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1229 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1230 r = bus_kernel_make_message(bus, k);
1232 /* Anybody can send us invalid messages, let's just drop them. */
1233 if (r == -EBADMSG || r == -EPROTOTYPE) {
1234 log_debug("Ignoring invalid message: %s", strerror(-r));
1238 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1239 r = bus_kernel_translate_message(bus, k);
1241 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1246 close_kdbus_msg(bus, k);
1248 return r < 0 ? r : 1;
1251 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1252 struct memfd_cache *c;
1259 if (!bus || !bus->is_kernel)
1262 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1264 if (bus->n_memfd_cache <= 0) {
1267 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1269 r = memfd_new(bus->description);
1279 c = &bus->memfd_cache[--bus->n_memfd_cache];
1282 assert(c->mapped == 0 || c->address);
1284 *address = c->address;
1285 *mapped = c->mapped;
1286 *allocated = c->allocated;
1289 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1294 static void close_and_munmap(int fd, void *address, size_t size) {
1296 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1301 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1302 struct memfd_cache *c;
1303 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1306 assert(mapped == 0 || address);
1308 if (!bus || !bus->is_kernel) {
1309 close_and_munmap(fd, address, mapped);
1313 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1315 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1316 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1318 close_and_munmap(fd, address, mapped);
1322 c = &bus->memfd_cache[bus->n_memfd_cache++];
1324 c->address = address;
1326 /* If overly long, let's return a bit to the OS */
1327 if (mapped > max_mapped) {
1328 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1329 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1330 c->mapped = c->allocated = max_mapped;
1333 c->allocated = allocated;
1336 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1339 void bus_kernel_flush_memfd(sd_bus *b) {
1344 for (i = 0; i < b->n_memfd_cache; i++)
1345 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1348 uint64_t request_name_flags_to_kdbus(uint64_t flags) {
1351 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1352 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1354 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1355 f |= KDBUS_NAME_REPLACE_EXISTING;
1357 if (flags & SD_BUS_NAME_QUEUE)
1358 f |= KDBUS_NAME_QUEUE;
1363 uint64_t attach_flags_to_kdbus(uint64_t mask) {
1366 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
1367 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
1368 m |= KDBUS_ATTACH_CREDS;
1370 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1371 m |= KDBUS_ATTACH_PIDS;
1373 if (mask & SD_BUS_CREDS_COMM)
1374 m |= KDBUS_ATTACH_PID_COMM;
1376 if (mask & SD_BUS_CREDS_TID_COMM)
1377 m |= KDBUS_ATTACH_TID_COMM;
1379 if (mask & SD_BUS_CREDS_EXE)
1380 m |= KDBUS_ATTACH_EXE;
1382 if (mask & SD_BUS_CREDS_CMDLINE)
1383 m |= KDBUS_ATTACH_CMDLINE;
1385 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))
1386 m |= KDBUS_ATTACH_CGROUP;
1388 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1389 m |= KDBUS_ATTACH_CAPS;
1391 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1392 m |= KDBUS_ATTACH_SECLABEL;
1394 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1395 m |= KDBUS_ATTACH_AUDIT;
1397 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1398 m |= KDBUS_ATTACH_NAMES;
1400 if (mask & SD_BUS_CREDS_DESCRIPTION)
1401 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1403 if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
1404 m |= KDBUS_ATTACH_AUXGROUPS;
1409 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1410 struct kdbus_cmd_make *make;
1411 struct kdbus_item *n;
1418 fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1423 make = alloca0_align(offsetof(struct kdbus_cmd_make, items) +
1424 ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
1425 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
1426 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
1429 make->size = offsetof(struct kdbus_cmd_make, items);
1431 /* Set the bloom parameters */
1433 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1434 sizeof(struct kdbus_bloom_parameter);
1435 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1436 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1437 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1439 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1440 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1442 make->size += ALIGN8(n->size);
1444 /* The busses we create make no restrictions on what metadata
1445 * peers can read from incoming messages. */
1446 n = KDBUS_ITEM_NEXT(n);
1447 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1448 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1449 n->data64[0] = _KDBUS_ATTACH_ANY;
1450 make->size += ALIGN8(n->size);
1452 /* Set the a good name */
1453 n = KDBUS_ITEM_NEXT(n);
1454 sprintf(n->str, UID_FMT "-%s", getuid(), name);
1455 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1456 n->type = KDBUS_ITEM_MAKE_NAME;
1457 make->size += ALIGN8(n->size);
1459 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1461 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1469 p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
1481 static int bus_kernel_translate_access(BusPolicyAccess access) {
1482 assert(access >= 0);
1483 assert(access < _BUS_POLICY_ACCESS_MAX);
1487 case BUS_POLICY_ACCESS_SEE:
1488 return KDBUS_POLICY_SEE;
1490 case BUS_POLICY_ACCESS_TALK:
1491 return KDBUS_POLICY_TALK;
1493 case BUS_POLICY_ACCESS_OWN:
1494 return KDBUS_POLICY_OWN;
1497 assert_not_reached("Unknown policy access");
1501 static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
1507 switch (policy->type) {
1509 case BUSNAME_POLICY_TYPE_USER: {
1510 const char *user = policy->name;
1513 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
1517 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1518 item->policy_access.id = uid;
1522 case BUSNAME_POLICY_TYPE_GROUP: {
1523 const char *group = policy->name;
1526 r = get_group_creds(&group, &gid);
1530 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1531 item->policy_access.id = gid;
1536 assert_not_reached("Unknown policy type");
1539 item->policy_access.access = bus_kernel_translate_access(policy->access);
1544 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1551 len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1558 p = newa(char, len);
1560 sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1562 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1576 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1577 _cleanup_free_ char *path = NULL;
1578 struct kdbus_cmd_make *make;
1579 struct kdbus_item *n;
1583 fd = bus_kernel_open_bus_fd(bus_name, &path);
1587 make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items)) +
1588 ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
1590 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1591 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1594 sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
1595 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1596 n->type = KDBUS_ITEM_MAKE_NAME;
1597 make->size += ALIGN8(n->size);
1600 if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1608 p = strjoin(dirname(path), "/", name, NULL);
1620 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
1622 struct kdbus_cmd_update *update;
1623 struct kdbus_item *n;
1624 BusEndpointPolicy *po;
1629 size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
1631 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1632 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
1633 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1636 update = alloca0_align(size, 8);
1637 update->size = size;
1641 HASHMAP_FOREACH(po, ep->policy_hash, i) {
1642 n->type = KDBUS_ITEM_NAME;
1643 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
1644 strcpy(n->str, po->name);
1645 n = KDBUS_ITEM_NEXT(n);
1647 n->type = KDBUS_ITEM_POLICY_ACCESS;
1648 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1650 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1651 n->policy_access.access = bus_kernel_translate_access(po->access);
1652 n->policy_access.id = uid;
1654 n = KDBUS_ITEM_NEXT(n);
1657 r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
1664 int bus_kernel_make_starter(
1669 BusNamePolicy *policy,
1670 BusPolicyAccess world_policy) {
1672 struct kdbus_cmd_hello *hello;
1673 struct kdbus_item *n;
1674 size_t policy_cnt = 0;
1682 LIST_FOREACH(policy, po, policy)
1685 if (world_policy >= 0)
1688 size = offsetof(struct kdbus_cmd_hello, items) +
1689 ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1690 policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1692 hello = alloca0_align(size, 8);
1695 strcpy(n->str, name);
1696 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1697 n->type = KDBUS_ITEM_NAME;
1698 n = KDBUS_ITEM_NEXT(n);
1700 LIST_FOREACH(policy, po, policy) {
1701 n->type = KDBUS_ITEM_POLICY_ACCESS;
1702 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1704 r = bus_kernel_translate_policy(po, n);
1708 n = KDBUS_ITEM_NEXT(n);
1711 if (world_policy >= 0) {
1712 n->type = KDBUS_ITEM_POLICY_ACCESS;
1713 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1714 n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1715 n->policy_access.access = bus_kernel_translate_access(world_policy);
1720 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1721 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
1722 hello->pool_size = KDBUS_POOL_SIZE;
1723 hello->attach_flags_send = _KDBUS_ATTACH_ANY;
1724 hello->attach_flags_recv = _KDBUS_ATTACH_ANY;
1726 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
1729 /* The higher 32bit of the bus_flags fields are considered
1730 * 'incompatible flags'. Refuse them all for now. */
1731 if (hello->bus_flags > 0xFFFFFFFFULL)
1734 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
1740 int bus_kernel_try_close(sd_bus *bus) {
1742 assert(bus->is_kernel);
1744 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1750 int bus_kernel_drop_one(int fd) {
1751 struct kdbus_cmd_recv recv = {
1752 .flags = KDBUS_RECV_DROP
1757 if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1763 int bus_kernel_realize_attach_flags(sd_bus *bus) {
1764 struct kdbus_cmd_update *update;
1765 struct kdbus_item *n;
1768 assert(bus->is_kernel);
1770 update = alloca0_align(offsetof(struct kdbus_cmd_update, items) +
1771 ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
1775 n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
1776 n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
1777 n->data64[0] = bus->attach_flags;
1780 offsetof(struct kdbus_cmd_update, items) +
1783 if (ioctl(bus->input_fd, KDBUS_CMD_CONN_UPDATE, update) < 0)