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>
33 #include "bus-internal.h"
34 #include "bus-message.h"
35 #include "bus-kernel.h"
36 #include "bus-bloom.h"
39 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
41 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
47 if (!startswith(s, ":1."))
50 r = safe_atou64(s + 3, id);
57 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
63 /* Note that p can be NULL, which encodes a region full of
64 * zeroes, which is useful to optimize certain padding
67 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
68 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
69 (*d)->vec.address = PTR_TO_UINT64(p);
72 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
75 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
81 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
82 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
83 (*d)->memfd.fd = memfd;
84 (*d)->memfd.size = sz;
86 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
89 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
95 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
96 (*d)->type = KDBUS_ITEM_DST_NAME;
97 memcpy((*d)->str, s, length + 1);
99 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
102 static void* append_bloom(struct kdbus_item **d, size_t length) {
109 (*d)->size = offsetof(struct kdbus_item, data) + length;
110 (*d)->type = KDBUS_ITEM_BLOOM;
113 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
118 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
124 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
125 (*d)->type = KDBUS_ITEM_FDS;
126 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
128 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
131 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
138 memset(bloom, 0, BLOOM_SIZE);
140 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
143 bloom_add_pair(bloom, "interface", m->interface);
145 bloom_add_pair(bloom, "member", m->member);
147 bloom_add_pair(bloom, "path", m->path);
148 bloom_add_pair(bloom, "path-slash-prefix", m->path);
149 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
152 r = sd_bus_message_rewind(m, true);
156 for (i = 0; i < 64; i++) {
159 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
162 r = sd_bus_message_peek_type(m, &type, NULL);
166 if (type != SD_BUS_TYPE_STRING &&
167 type != SD_BUS_TYPE_OBJECT_PATH &&
168 type != SD_BUS_TYPE_SIGNATURE)
171 r = sd_bus_message_read_basic(m, type, &t);
175 e = stpcpy(buf, "arg");
179 *(e++) = '0' + (i / 10);
180 *(e++) = '0' + (i % 10);
184 bloom_add_pair(bloom, buf, t);
186 strcpy(e, "-dot-prefix");
187 bloom_add_prefixes(bloom, buf, t, '.');
188 strcpy(e, "-slash-prefix");
189 bloom_add_prefixes(bloom, buf, t, '/');
195 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
196 struct bus_body_part *part;
197 struct kdbus_item *d;
211 if (m->destination) {
212 r = bus_kernel_parse_unique_name(m->destination, &unique);
220 sz = offsetof(struct kdbus_msg, items);
222 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
223 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
225 /* Add in fixed header, fields header and payload */
226 sz += (1 + m->n_body_parts) *
227 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
229 /* Add space for bloom filter */
230 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
232 /* Add in well-known destination header */
234 dl = strlen(m->destination);
235 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
238 /* Add space for unix fds */
240 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
242 m->kdbus = memalign(8, sz);
248 m->free_kdbus = true;
249 memset(m->kdbus, 0, sz);
252 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
253 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
256 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
257 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
258 m->kdbus->cookie = m->header->serial;
260 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
265 append_destination(&d, m->destination, dl);
267 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
269 MESSAGE_FOREACH_PART(part, i, m) {
271 /* If this is padding then simply send a
272 * vector with a NULL data pointer which the
273 * kernel will just pass through. This is the
274 * most efficient way to encode zeroes */
276 append_payload_vec(&d, NULL, part->size);
280 if (part->memfd >= 0 && part->sealed && m->destination) {
281 /* Try to send a memfd, if the part is
282 * sealed and this is not a broadcast. Since we can only */
284 append_payload_memfd(&d, part->memfd, part->size);
288 /* Otherwise let's send a vector to the actual data,
289 * for that we need to map it first. */
290 r = bus_body_part_map(part);
294 append_payload_vec(&d, part->data, part->size);
297 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
300 p = append_bloom(&d, BLOOM_SIZE);
301 r = bus_message_setup_bloom(m, p);
307 append_fds(&d, m->fds, m->n_fds);
309 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
310 assert(m->kdbus->size <= sz);
319 int bus_kernel_take_fd(sd_bus *b) {
320 struct kdbus_cmd_hello hello;
331 hello.size = sizeof(hello);
332 hello.conn_flags = b->hello_flags;
333 hello.attach_flags = b->attach_flags;
334 hello.pool_size = KDBUS_POOL_SIZE;
336 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
340 if (!b->kdbus_buffer) {
341 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
342 if (b->kdbus_buffer == MAP_FAILED) {
343 b->kdbus_buffer = NULL;
348 /* The higher 32bit of both flags fields are considered
349 * 'incompatible flags'. Refuse them all for now. */
350 if (hello.bus_flags > 0xFFFFFFFFULL ||
351 hello.conn_flags > 0xFFFFFFFFULL)
354 if (hello.bloom_size != BLOOM_SIZE)
357 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
360 b->unique_id = hello.id;
363 b->bus_client = true;
364 b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
365 b->message_version = 2;
367 /* the kernel told us the UUID of the underlying bus */
368 memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
370 return bus_start_running(b);
373 int bus_kernel_connect(sd_bus *b) {
375 assert(b->input_fd < 0);
376 assert(b->output_fd < 0);
382 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
386 b->output_fd = b->input_fd;
388 return bus_kernel_take_fd(b);
391 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
396 assert(bus->state == BUS_RUNNING);
398 /* If we can't deliver, we want room for the error message */
399 r = bus_rqueue_make_room(bus);
403 r = bus_message_setup_kmsg(bus, m);
407 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
409 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
410 sd_bus_message *reply;
412 if (errno == EAGAIN || errno == EINTR)
414 else if (errno == ENXIO || errno == ESRCH) {
416 /* ENXIO: unique name not known
417 * ESRCH: well-known name not known */
419 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
420 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
422 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
426 } else if (errno == EADDRNOTAVAIL) {
428 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
430 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
431 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
433 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
439 r = bus_message_new_synthetic_error(
441 BUS_MESSAGE_SERIAL(m),
448 r = bus_seal_synthetic_message(bus, reply);
452 bus->rqueue[bus->rqueue_size++] = reply;
460 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
462 struct kdbus_item *d;
467 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
468 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
470 KDBUS_ITEM_FOREACH(d, k, items) {
472 if (d->type == KDBUS_ITEM_FDS)
473 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
474 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
475 close_nointr_nofail(d->memfd.fd);
479 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
480 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
485 r = sd_bus_message_new_signal(
487 "/org/freedesktop/DBus",
488 "org.freedesktop.DBus",
494 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
498 m->sender = "org.freedesktop.DBus";
500 r = bus_seal_synthetic_message(bus, m);
504 bus->rqueue[bus->rqueue_size++] = m;
510 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
511 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
517 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_STARTER)))
520 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
522 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_STARTER))) {
524 if (isempty(old_owner))
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_synthetic_message(bus, m);
573 bus->rqueue[bus->rqueue_size++] = m;
579 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
580 struct kdbus_item *d, *found = NULL;
582 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
583 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
584 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
585 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
587 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
588 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
590 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
591 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
596 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
598 KDBUS_ITEM_FOREACH(d, k, items) {
599 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
604 log_debug("Got unknown field from kernel %llu", d->type);
608 log_debug("Didn't find a kernel message to translate.");
612 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
615 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
616 sd_bus_message *m = NULL;
617 struct kdbus_item *d;
619 _cleanup_free_ int *fds = NULL;
620 struct bus_header *h = NULL;
621 size_t total, n_bytes = 0, idx = 0;
622 const char *destination = NULL, *seclabel = NULL;
627 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
629 KDBUS_ITEM_FOREACH(d, k, items) {
632 l = d->size - offsetof(struct kdbus_item, data);
636 case KDBUS_ITEM_PAYLOAD_OFF:
638 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
640 if (!bus_header_is_complete(h, d->vec.size))
644 n_bytes += d->vec.size;
647 case KDBUS_ITEM_PAYLOAD_MEMFD:
651 n_bytes += d->memfd.size;
654 case KDBUS_ITEM_FDS: {
659 f = realloc(fds, sizeof(int) * (n_fds + j));
664 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
669 case KDBUS_ITEM_SECLABEL:
678 r = bus_header_message_size(h, &total);
682 if (n_bytes != total)
685 /* on kdbus we only speak native endian gvariant, never dbus1
686 * marshalling or reverse endian */
687 if (h->version != 2 ||
688 h->endian != BUS_NATIVE_ENDIAN)
691 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
695 KDBUS_ITEM_FOREACH(d, k, items) {
698 l = d->size - offsetof(struct kdbus_item, data);
702 case KDBUS_ITEM_PAYLOAD_OFF: {
705 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
707 if (idx + d->vec.size > begin_body) {
708 struct bus_body_part *part;
710 /* Contains body material */
712 part = message_append_part(m);
718 /* A -1 offset is NUL padding. */
719 part->is_zero = d->vec.offset == ~0ULL;
721 if (idx >= begin_body) {
723 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
724 part->size = d->vec.size;
727 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
728 part->size = d->vec.size - (begin_body - idx);
738 case KDBUS_ITEM_PAYLOAD_MEMFD: {
739 struct bus_body_part *part;
741 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
746 part = message_append_part(m);
752 part->memfd = d->memfd.fd;
753 part->size = d->memfd.size;
756 idx += d->memfd.size;
760 case KDBUS_ITEM_CREDS:
761 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
762 m->creds.uid = d->creds.uid;
763 m->creds.gid = d->creds.gid;
764 m->creds.pid = d->creds.pid;
765 m->creds.tid = d->creds.tid;
766 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;
769 case KDBUS_ITEM_TIMESTAMP:
770 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
771 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
774 case KDBUS_ITEM_PID_COMM:
775 m->creds.comm = d->str;
776 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
779 case KDBUS_ITEM_TID_COMM:
780 m->creds.tid_comm = d->str;
781 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
785 m->creds.exe = d->str;
786 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
789 case KDBUS_ITEM_CMDLINE:
790 m->creds.cmdline = d->str;
791 m->creds.cmdline_size = l;
792 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
795 case KDBUS_ITEM_CGROUP:
796 m->creds.cgroup = d->str;
797 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;
800 case KDBUS_ITEM_AUDIT:
801 m->creds.audit_session_id = d->audit.sessionid;
802 m->creds.audit_login_uid = d->audit.loginuid;
803 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
806 case KDBUS_ITEM_CAPS:
807 m->creds.capability = d->data;
808 m->creds.capability_size = l;
809 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;
812 case KDBUS_ITEM_DST_NAME:
813 destination = d->str;
816 case KDBUS_ITEM_NAME:
817 r = strv_extend(&m->creds.well_known_names, d->name.name);
820 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
824 case KDBUS_ITEM_SECLABEL:
828 log_debug("Got unknown field from kernel %llu", d->type);
832 r = bus_message_parse_fields(m);
836 if (k->src_id == KDBUS_SRC_ID_KERNEL)
837 m->sender = "org.freedesktop.DBus";
839 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
840 m->sender = m->creds.unique_name = m->sender_buffer;
841 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
844 if (!m->destination) {
846 m->destination = destination;
847 else if (k->dst_id != KDBUS_DST_ID_NAME &&
848 k->dst_id != KDBUS_DST_ID_BROADCAST) {
849 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
850 m->destination = m->destination_buffer;
854 /* We take possession of the kmsg struct now */
856 m->release_kdbus = true;
860 bus->rqueue[bus->rqueue_size++] = m;
866 struct bus_body_part *part;
869 /* Make sure the memfds are not freed twice */
870 MESSAGE_FOREACH_PART(part, i, m)
871 if (part->memfd >= 0)
874 sd_bus_message_unref(m);
880 int bus_kernel_read_message(sd_bus *bus) {
887 r = bus_rqueue_make_room(bus);
891 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
898 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
900 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
901 r = bus_kernel_make_message(bus, k);
903 /* Anybody can send us invalid messages, let's just drop them. */
904 if (r == -EBADMSG || r == -EPROTOTYPE) {
905 log_debug("Ignoring invalid message: %s", strerror(-r));
909 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
910 r = bus_kernel_translate_message(bus, k);
915 close_kdbus_msg(bus, k);
917 return r < 0 ? r : 1;
920 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
921 struct memfd_cache *c;
927 if (!bus || !bus->is_kernel)
930 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
932 if (bus->n_memfd_cache <= 0) {
935 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
937 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
946 c = &bus->memfd_cache[--bus->n_memfd_cache];
949 assert(c->size == 0 || c->address);
951 *address = c->address;
955 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
960 static void close_and_munmap(int fd, void *address, size_t size) {
962 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
964 close_nointr_nofail(fd);
967 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
968 struct memfd_cache *c;
969 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
972 assert(size == 0 || address);
974 if (!bus || !bus->is_kernel) {
975 close_and_munmap(fd, address, size);
979 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
981 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
982 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
984 close_and_munmap(fd, address, size);
988 c = &bus->memfd_cache[bus->n_memfd_cache++];
990 c->address = address;
992 /* If overly long, let's return a bit to the OS */
994 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
995 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
1000 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1003 void bus_kernel_flush_memfd(sd_bus *b) {
1008 for (i = 0; i < b->n_memfd_cache; i++)
1009 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
1012 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1015 assert(kdbus_flags);
1017 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1018 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1020 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1021 f |= KDBUS_NAME_REPLACE_EXISTING;
1023 if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1024 f |= KDBUS_NAME_QUEUE;
1030 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1035 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1036 m |= KDBUS_ATTACH_CREDS;
1038 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1039 m |= KDBUS_ATTACH_COMM;
1041 if (mask & SD_BUS_CREDS_EXE)
1042 m |= KDBUS_ATTACH_EXE;
1044 if (mask & SD_BUS_CREDS_CMDLINE)
1045 m |= KDBUS_ATTACH_CMDLINE;
1047 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))
1048 m |= KDBUS_ATTACH_CGROUP;
1050 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1051 m |= KDBUS_ATTACH_CAPS;
1053 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1054 m |= KDBUS_ATTACH_SECLABEL;
1056 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1057 m |= KDBUS_ATTACH_AUDIT;
1059 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1060 m |= KDBUS_ATTACH_NAMES;
1066 int bus_kernel_create_bus(const char *name, char **s) {
1067 struct kdbus_cmd_bus_make *make;
1068 struct kdbus_item *n;
1074 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1078 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1079 offsetof(struct kdbus_item, str) +
1080 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1083 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1084 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1085 n->type = KDBUS_ITEM_MAKE_NAME;
1087 make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1088 make->flags = KDBUS_MAKE_POLICY_OPEN;
1089 make->bloom_size = BLOOM_SIZE;
1090 assert_cc(BLOOM_SIZE % 8 == 0);
1092 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1093 close_nointr_nofail(fd);
1097 /* The higher 32bit of the flags field are considered
1098 * 'incompatible flags'. Refuse them all for now. */
1099 if (make->flags > 0xFFFFFFFFULL) {
1100 close_nointr_nofail(fd);
1107 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1109 close_nointr_nofail(fd);
1119 int bus_kernel_create_starter(const char *bus, const char *name) {
1120 struct kdbus_cmd_hello *hello;
1121 struct kdbus_item *n;
1128 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1129 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1131 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1135 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1136 offsetof(struct kdbus_item, str) +
1140 strcpy(n->str, name);
1141 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1142 n->type = KDBUS_ITEM_STARTER_NAME;
1144 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1145 hello->conn_flags = KDBUS_HELLO_STARTER;
1146 hello->pool_size = KDBUS_POOL_SIZE;
1148 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1149 close_nointr_nofail(fd);
1153 /* The higher 32bit of both flags fields are considered
1154 * 'incompatible flags'. Refuse them all for now. */
1155 if (hello->bus_flags > 0xFFFFFFFFULL ||
1156 hello->conn_flags > 0xFFFFFFFFULL) {
1157 close_nointr_nofail(fd);
1161 if (hello->bloom_size != BLOOM_SIZE) {
1162 close_nointr_nofail(fd);
1169 int bus_kernel_create_namespace(const char *name, char **s) {
1170 struct kdbus_cmd_ns_make *make;
1171 struct kdbus_item *n;
1177 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1181 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) +
1182 offsetof(struct kdbus_item, str) +
1186 strcpy(n->str, name);
1187 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1188 n->type = KDBUS_ITEM_MAKE_NAME;
1190 make->size = ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) + n->size);
1191 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1193 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1194 close_nointr_nofail(fd);
1198 /* The higher 32bit of the flags field are considered
1199 * 'incompatible flags'. Refuse them all for now. */
1200 if (make->flags > 0xFFFFFFFFULL) {
1201 close_nointr_nofail(fd);
1208 p = strappend("/dev/kdbus/ns/", name);
1210 close_nointr_nofail(fd);
1220 int bus_kernel_monitor(sd_bus *bus) {
1221 struct kdbus_cmd_monitor cmd_monitor;
1227 cmd_monitor.flags = KDBUS_MONITOR_ENABLE;
1229 r = ioctl(bus->input_fd, KDBUS_CMD_MONITOR, &cmd_monitor);