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>
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-kernel.h"
35 #include "bus-bloom.h"
38 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
40 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
46 if (!startswith(s, ":1."))
49 r = safe_atou64(s + 3, id);
56 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
62 /* Note that p can be NULL, which encodes a region full of
63 * zeroes, which is useful to optimize certain padding
66 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
67 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
68 (*d)->vec.address = PTR_TO_UINT64(p);
71 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
74 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
80 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
81 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
82 (*d)->memfd.fd = memfd;
83 (*d)->memfd.size = sz;
85 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
88 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
94 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
95 (*d)->type = KDBUS_ITEM_DST_NAME;
96 memcpy((*d)->str, s, length + 1);
98 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
101 static void* append_bloom(struct kdbus_item **d, size_t length) {
108 (*d)->size = offsetof(struct kdbus_item, data) + length;
109 (*d)->type = KDBUS_ITEM_BLOOM;
112 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
117 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
123 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
124 (*d)->type = KDBUS_ITEM_FDS;
125 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
127 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
130 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
137 memset(bloom, 0, BLOOM_SIZE);
139 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
142 bloom_add_pair(bloom, "interface", m->interface);
144 bloom_add_pair(bloom, "member", m->member);
146 bloom_add_pair(bloom, "path", m->path);
147 bloom_add_pair(bloom, "path-slash-prefix", m->path);
148 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
151 r = sd_bus_message_rewind(m, true);
155 for (i = 0; i < 64; i++) {
158 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
161 r = sd_bus_message_peek_type(m, &type, NULL);
165 if (type != SD_BUS_TYPE_STRING &&
166 type != SD_BUS_TYPE_OBJECT_PATH &&
167 type != SD_BUS_TYPE_SIGNATURE)
170 r = sd_bus_message_read_basic(m, type, &t);
174 e = stpcpy(buf, "arg");
178 *(e++) = '0' + (i / 10);
179 *(e++) = '0' + (i % 10);
183 bloom_add_pair(bloom, buf, t);
185 strcpy(e, "-dot-prefix");
186 bloom_add_prefixes(bloom, buf, t, '.');
187 strcpy(e, "-slash-prefix");
188 bloom_add_prefixes(bloom, buf, t, '/');
194 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
195 struct bus_body_part *part;
196 struct kdbus_item *d;
210 if (m->destination) {
211 r = bus_kernel_parse_unique_name(m->destination, &unique);
219 sz = offsetof(struct kdbus_msg, items);
221 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
222 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
224 /* Add in fixed header, fields header and payload */
225 sz += (1 + m->n_body_parts) *
226 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
228 /* Add space for bloom filter */
229 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
231 /* Add in well-known destination header */
233 dl = strlen(m->destination);
234 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
237 /* Add space for unix fds */
239 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
241 m->kdbus = memalign(8, sz);
247 m->free_kdbus = true;
248 memset(m->kdbus, 0, sz);
251 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
252 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
255 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
256 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
257 m->kdbus->cookie = m->header->serial;
259 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
264 append_destination(&d, m->destination, dl);
266 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
268 MESSAGE_FOREACH_PART(part, i, m) {
270 /* If this is padding then simply send a
271 * vector with a NULL data pointer which the
272 * kernel will just pass through. This is the
273 * most efficient way to encode zeroes */
275 append_payload_vec(&d, NULL, part->size);
279 if (part->memfd >= 0 && part->sealed && m->destination) {
280 /* Try to send a memfd, if the part is
281 * sealed and this is not a broadcast. Since we can only */
283 append_payload_memfd(&d, part->memfd, part->size);
287 /* Otherwise let's send a vector to the actual data,
288 * for that we need to map it first. */
289 r = bus_body_part_map(part);
293 append_payload_vec(&d, part->data, part->size);
296 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
299 p = append_bloom(&d, BLOOM_SIZE);
300 r = bus_message_setup_bloom(m, p);
306 append_fds(&d, m->fds, m->n_fds);
308 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
309 assert(m->kdbus->size <= sz);
318 int bus_kernel_take_fd(sd_bus *b) {
319 struct kdbus_cmd_hello hello;
330 hello.size = sizeof(hello);
331 hello.conn_flags = b->hello_flags;
332 hello.attach_flags = b->attach_flags;
333 hello.pool_size = KDBUS_POOL_SIZE;
335 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
339 if (!b->kdbus_buffer) {
340 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
341 if (b->kdbus_buffer == MAP_FAILED) {
342 b->kdbus_buffer = NULL;
347 /* The higher 32bit of both flags fields are considered
348 * 'incompatible flags'. Refuse them all for now. */
349 if (hello.bus_flags > 0xFFFFFFFFULL ||
350 hello.conn_flags > 0xFFFFFFFFULL)
353 if (hello.bloom_size != BLOOM_SIZE)
356 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
359 b->unique_id = hello.id;
362 b->bus_client = true;
363 b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
365 /* the kernel told us the UUID of the underlying bus */
366 memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
368 r = bus_start_running(b);
375 int bus_kernel_connect(sd_bus *b) {
377 assert(b->input_fd < 0);
378 assert(b->output_fd < 0);
384 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
388 b->output_fd = b->input_fd;
390 return bus_kernel_take_fd(b);
393 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
398 assert(bus->state == BUS_RUNNING);
400 r = bus_message_setup_kmsg(bus, m);
404 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
406 return errno == EAGAIN ? 0 : -errno;
411 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
413 struct kdbus_item *d;
418 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
419 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
421 KDBUS_PART_FOREACH(d, k, items) {
423 if (d->type == KDBUS_ITEM_FDS)
424 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
425 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
426 close_nointr_nofail(d->memfd.fd);
430 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
431 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
436 r = sd_bus_message_new_signal(
438 "/org/freedesktop/DBus",
439 "org.freedesktop.DBus",
445 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
449 m->sender = "org.freedesktop.DBus";
451 r = bus_seal_message(bus, m);
455 r = bus_rqueue_push(bus, m);
463 static int push_name_name_acquired(sd_bus *bus, const char *signal, const char *name) {
464 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
469 r = sd_bus_message_new_signal(
471 "/org/freedesktop/DBus",
472 "org.freedesktop.DBus",
479 r = sd_bus_message_append(m, "ss", name);
483 m->sender = "org.freedesktop.DBus";
485 r = bus_seal_message(bus, m);
489 r = bus_rqueue_push(bus, m);
497 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
498 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
505 if (d->name_change.flags != 0)
508 /* First generate NameAcquired/NameList messages */
509 if (d->type == KDBUS_ITEM_NAME_ADD && d->name_change.new_id == bus->unique_id) {
510 r = push_name_name_acquired(bus, "NameAcquired", d->name_change.name);
514 } else if (d->type == KDBUS_ITEM_NAME_REMOVE && d->name_change.old_id == bus->unique_id) {
515 r = push_name_name_acquired(bus, "NameLost", d->name_change.name);
520 /* Then, generate NameOwnerChanged messages */
521 if (d->type == KDBUS_ITEM_NAME_ADD)
524 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
526 if (d->type == KDBUS_ITEM_NAME_REMOVE)
529 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
531 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
534 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
535 char owner[UNIQUE_NAME_MAX];
541 sprintf(owner, ":1.%llu", d->id_change.id);
543 return push_name_owner_changed(
545 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
546 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
549 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
550 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
557 r = bus_message_new_synthetic_error(
560 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
561 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
562 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
567 m->sender = "org.freedesktop.DBus";
569 r = bus_seal_message(bus, m);
573 r = bus_rqueue_push(bus, m);
581 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
582 struct kdbus_item *d, *found = NULL;
584 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
585 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
586 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
587 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
589 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
590 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
592 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
593 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
598 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
600 KDBUS_PART_FOREACH(d, k, items) {
601 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
606 log_debug("Got unknown field from kernel %llu", d->type);
610 log_debug("Didn't find a kernel message to translate.");
614 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
617 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
621 SET_FLAG(m, KDBUS_ATTACH_CREDS,
622 !!(mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID)));
624 SET_FLAG(m, KDBUS_ATTACH_COMM,
625 !!(mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)));
627 SET_FLAG(m, KDBUS_ATTACH_EXE,
628 !!(mask & SD_BUS_CREDS_EXE));
630 SET_FLAG(m, KDBUS_ATTACH_CMDLINE,
631 !!(mask & SD_BUS_CREDS_CMDLINE));
633 SET_FLAG(m, KDBUS_ATTACH_CGROUP,
634 !!(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)));
636 SET_FLAG(m, KDBUS_ATTACH_CAPS,
637 !!(mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)));
639 SET_FLAG(m, KDBUS_ATTACH_SECLABEL,
640 !!(mask & SD_BUS_CREDS_SELINUX_CONTEXT));
642 SET_FLAG(m, KDBUS_ATTACH_AUDIT,
643 !!(mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
650 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
651 sd_bus_message *m = NULL;
652 struct kdbus_item *d;
654 _cleanup_free_ int *fds = NULL;
655 struct bus_header *h = NULL;
656 size_t total, n_bytes = 0, idx = 0;
657 const char *destination = NULL, *seclabel = NULL;
662 assert(k->payload_type == KDBUS_PAYLOAD_DBUS1);
664 KDBUS_PART_FOREACH(d, k, items) {
667 l = d->size - offsetof(struct kdbus_item, data);
671 case KDBUS_ITEM_PAYLOAD_OFF:
673 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
675 if (!bus_header_is_complete(h, d->vec.size))
679 n_bytes += d->vec.size;
682 case KDBUS_ITEM_PAYLOAD_MEMFD:
686 n_bytes += d->memfd.size;
689 case KDBUS_ITEM_FDS: {
694 f = realloc(fds, sizeof(int) * (n_fds + j));
699 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
704 case KDBUS_ITEM_SECLABEL:
713 r = bus_header_message_size(h, &total);
717 if (n_bytes != total)
720 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
724 KDBUS_PART_FOREACH(d, k, items) {
727 l = d->size - offsetof(struct kdbus_item, data);
731 case KDBUS_ITEM_PAYLOAD_OFF: {
734 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
736 if (idx + d->vec.size > begin_body) {
737 struct bus_body_part *part;
739 /* Contains body material */
741 part = message_append_part(m);
747 /* A -1 offset is NUL padding. */
748 part->is_zero = d->vec.offset == ~0ULL;
750 if (idx >= begin_body) {
752 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
753 part->size = d->vec.size;
756 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
757 part->size = d->vec.size - (begin_body - idx);
767 case KDBUS_ITEM_PAYLOAD_MEMFD: {
768 struct bus_body_part *part;
770 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
775 part = message_append_part(m);
781 part->memfd = d->memfd.fd;
782 part->size = d->memfd.size;
785 idx += d->memfd.size;
789 case KDBUS_ITEM_CREDS:
790 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
791 m->creds.uid = d->creds.uid;
792 m->creds.gid = d->creds.gid;
793 m->creds.pid = d->creds.pid;
794 m->creds.tid = d->creds.tid;
795 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID) & bus->creds_mask;
798 case KDBUS_ITEM_TIMESTAMP:
799 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
800 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
803 case KDBUS_ITEM_PID_COMM:
804 m->creds.comm = d->str;
805 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
808 case KDBUS_ITEM_TID_COMM:
809 m->creds.tid_comm = d->str;
810 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
814 m->creds.exe = d->str;
815 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
818 case KDBUS_ITEM_CMDLINE:
819 m->creds.cmdline = d->str;
820 m->creds.cmdline_length = l;
821 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
824 case KDBUS_ITEM_CGROUP:
825 m->creds.cgroup = d->str;
826 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;
829 case KDBUS_ITEM_AUDIT:
830 m->creds.audit_session_id = d->audit.sessionid;
831 m->creds.audit_login_uid = d->audit.loginuid;
832 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
835 case KDBUS_ITEM_CAPS:
836 m->creds.capability = d->data;
837 m->creds.capability_size = l;
838 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;
841 case KDBUS_ITEM_DST_NAME:
842 destination = d->str;
846 case KDBUS_ITEM_SECLABEL:
847 case KDBUS_ITEM_NAMES:
851 log_debug("Got unknown field from kernel %llu", d->type);
855 r = bus_message_parse_fields(m);
859 if (k->src_id == KDBUS_SRC_ID_KERNEL)
860 m->sender = "org.freedesktop.DBus";
862 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
863 m->sender = m->sender_buffer;
866 if (!m->destination) {
868 m->destination = destination;
869 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
870 k->dst_id != KDBUS_DST_ID_BROADCAST) {
871 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
872 m->destination = m->destination_buffer;
876 /* We take possession of the kmsg struct now */
878 m->release_kdbus = true;
883 r = bus_rqueue_push(bus, m);
891 struct bus_body_part *part;
894 /* Make sure the memfds are not freed twice */
895 MESSAGE_FOREACH_PART(part, i, m)
896 if (part->memfd >= 0)
899 sd_bus_message_unref(m);
905 int bus_kernel_read_message(sd_bus *bus) {
912 /* Kernel messages might result in 2 new queued messages in
913 * the worst case (NameOwnerChange and LostName for the same
914 * well-known name, for example). Let's make room in
917 r = bus_rqueue_make_room(bus, 2);
921 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
928 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
930 if (k->payload_type == KDBUS_PAYLOAD_DBUS1)
931 r = bus_kernel_make_message(bus, k);
932 else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
933 r = bus_kernel_translate_message(bus, k);
938 close_kdbus_msg(bus, k);
940 return r < 0 ? r : 1;
943 int bus_kernel_create(const char *name, char **s) {
944 struct kdbus_cmd_bus_make *make;
945 struct kdbus_item *n;
953 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
958 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
959 KDBUS_PART_HEADER_SIZE + sizeof(uint64_t) +
960 KDBUS_PART_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
963 n->type = KDBUS_MAKE_NAME;
964 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
965 n->size = KDBUS_PART_HEADER_SIZE + strlen(n->str) + 1;
967 make->size = offsetof(struct kdbus_cmd_bus_make, items) + n->size;
968 make->flags = KDBUS_MAKE_POLICY_OPEN;
970 make->bloom_size = BLOOM_SIZE;
971 assert_cc(BLOOM_SIZE % 8 == 0);
973 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
977 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
978 close_nointr_nofail(fd);
989 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
990 struct memfd_cache *c;
996 if (!bus || !bus->is_kernel)
999 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1001 if (bus->n_memfd_cache <= 0) {
1004 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1006 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
1015 c = &bus->memfd_cache[--bus->n_memfd_cache];
1018 assert(c->size == 0 || c->address);
1020 *address = c->address;
1024 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1029 static void close_and_munmap(int fd, void *address, size_t size) {
1031 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1033 close_nointr_nofail(fd);
1036 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
1037 struct memfd_cache *c;
1038 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1041 assert(size == 0 || address);
1043 if (!bus || !bus->is_kernel) {
1044 close_and_munmap(fd, address, size);
1048 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1050 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1051 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1053 close_and_munmap(fd, address, size);
1057 c = &bus->memfd_cache[bus->n_memfd_cache++];
1059 c->address = address;
1061 /* If overly long, let's return a bit to the OS */
1062 if (size > max_sz) {
1063 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
1064 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
1069 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1072 void bus_kernel_flush_memfd(sd_bus *b) {
1077 for (i = 0; i < b->n_memfd_cache; i++)
1078 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
1081 int kdbus_translate_request_name_flags(uint64_t sd_bus_flags, uint64_t *kdbus_flags) {
1083 assert_return(kdbus_flags != NULL, -EINVAL);
1087 if (sd_bus_flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1088 *kdbus_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
1090 if (sd_bus_flags & SD_BUS_NAME_REPLACE_EXISTING)
1091 *kdbus_flags |= KDBUS_NAME_REPLACE_EXISTING;
1093 if (!(sd_bus_flags & SD_BUS_NAME_DO_NOT_QUEUE))
1094 *kdbus_flags |= KDBUS_NAME_QUEUE;