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);
366 /* the kernel told us the UUID of the underlying bus */
367 memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
369 return bus_start_running(b);
372 int bus_kernel_connect(sd_bus *b) {
374 assert(b->input_fd < 0);
375 assert(b->output_fd < 0);
381 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
385 b->output_fd = b->input_fd;
387 return bus_kernel_take_fd(b);
390 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
395 assert(bus->state == BUS_RUNNING);
397 /* If we can't deliver, we want room for the error message */
398 r = bus_rqueue_make_room(bus);
402 r = bus_message_setup_kmsg(bus, m);
406 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
408 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
409 sd_bus_message *reply;
411 if (errno == EAGAIN || errno == EINTR)
413 else if (errno == ENXIO || errno == ESRCH) {
415 /* ENXIO: unique name not known
416 * ESRCH: well-known name not known */
418 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
419 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
423 } else if (errno == EADDRNOTAVAIL) {
425 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
427 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
428 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
434 r = bus_message_new_synthetic_error(
436 BUS_MESSAGE_SERIAL(m),
443 r = bus_seal_synthetic_message(bus, reply);
447 bus->rqueue[bus->rqueue_size++] = reply;
455 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
457 struct kdbus_item *d;
462 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
463 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
465 KDBUS_ITEM_FOREACH(d, k, items) {
467 if (d->type == KDBUS_ITEM_FDS)
468 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
469 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
470 close_nointr_nofail(d->memfd.fd);
474 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
475 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
480 r = sd_bus_message_new_signal(
482 "/org/freedesktop/DBus",
483 "org.freedesktop.DBus",
489 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
493 m->sender = "org.freedesktop.DBus";
495 r = bus_seal_synthetic_message(bus, m);
499 bus->rqueue[bus->rqueue_size++] = m;
505 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
506 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
512 if (d->name_change.flags != 0)
515 if (d->type == KDBUS_ITEM_NAME_ADD)
518 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
520 if (d->type == KDBUS_ITEM_NAME_REMOVE)
523 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
525 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
528 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
529 char owner[UNIQUE_NAME_MAX];
535 sprintf(owner, ":1.%llu", d->id_change.id);
537 return push_name_owner_changed(
539 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
540 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
543 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
544 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
551 r = bus_message_new_synthetic_error(
554 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
555 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
556 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
561 m->sender = "org.freedesktop.DBus";
563 r = bus_seal_synthetic_message(bus, m);
567 bus->rqueue[bus->rqueue_size++] = m;
573 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
574 struct kdbus_item *d, *found = NULL;
576 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
577 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
578 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
579 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
581 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
582 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
584 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
585 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
590 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
592 KDBUS_ITEM_FOREACH(d, k, items) {
593 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
598 log_debug("Got unknown field from kernel %llu", d->type);
602 log_debug("Didn't find a kernel message to translate.");
606 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
609 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
610 sd_bus_message *m = NULL;
611 struct kdbus_item *d;
613 _cleanup_free_ int *fds = NULL;
614 struct bus_header *h = NULL;
615 size_t total, n_bytes = 0, idx = 0;
616 const char *destination = NULL, *seclabel = NULL;
621 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
623 KDBUS_ITEM_FOREACH(d, k, items) {
626 l = d->size - offsetof(struct kdbus_item, data);
630 case KDBUS_ITEM_PAYLOAD_OFF:
632 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
634 if (!bus_header_is_complete(h, d->vec.size))
638 n_bytes += d->vec.size;
641 case KDBUS_ITEM_PAYLOAD_MEMFD:
645 n_bytes += d->memfd.size;
648 case KDBUS_ITEM_FDS: {
653 f = realloc(fds, sizeof(int) * (n_fds + j));
658 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
663 case KDBUS_ITEM_SECLABEL:
672 r = bus_header_message_size(h, &total);
676 if (n_bytes != total)
679 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
683 KDBUS_ITEM_FOREACH(d, k, items) {
686 l = d->size - offsetof(struct kdbus_item, data);
690 case KDBUS_ITEM_PAYLOAD_OFF: {
693 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
695 if (idx + d->vec.size > begin_body) {
696 struct bus_body_part *part;
698 /* Contains body material */
700 part = message_append_part(m);
706 /* A -1 offset is NUL padding. */
707 part->is_zero = d->vec.offset == ~0ULL;
709 if (idx >= begin_body) {
711 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
712 part->size = d->vec.size;
715 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
716 part->size = d->vec.size - (begin_body - idx);
726 case KDBUS_ITEM_PAYLOAD_MEMFD: {
727 struct bus_body_part *part;
729 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
734 part = message_append_part(m);
740 part->memfd = d->memfd.fd;
741 part->size = d->memfd.size;
744 idx += d->memfd.size;
748 case KDBUS_ITEM_CREDS:
749 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
750 m->creds.uid = d->creds.uid;
751 m->creds.gid = d->creds.gid;
752 m->creds.pid = d->creds.pid;
753 m->creds.tid = d->creds.tid;
754 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;
757 case KDBUS_ITEM_TIMESTAMP:
758 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
759 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
762 case KDBUS_ITEM_PID_COMM:
763 m->creds.comm = d->str;
764 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
767 case KDBUS_ITEM_TID_COMM:
768 m->creds.tid_comm = d->str;
769 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
773 m->creds.exe = d->str;
774 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
777 case KDBUS_ITEM_CMDLINE:
778 m->creds.cmdline = d->str;
779 m->creds.cmdline_size = l;
780 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
783 case KDBUS_ITEM_CGROUP:
784 m->creds.cgroup = d->str;
785 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;
788 case KDBUS_ITEM_AUDIT:
789 m->creds.audit_session_id = d->audit.sessionid;
790 m->creds.audit_login_uid = d->audit.loginuid;
791 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
794 case KDBUS_ITEM_CAPS:
795 m->creds.capability = d->data;
796 m->creds.capability_size = l;
797 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;
800 case KDBUS_ITEM_DST_NAME:
801 destination = d->str;
804 case KDBUS_ITEM_NAME:
805 r = strv_extend(&m->creds.well_known_names, d->name.name);
808 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
812 case KDBUS_ITEM_SECLABEL:
816 log_debug("Got unknown field from kernel %llu", d->type);
820 r = bus_message_parse_fields(m);
824 if (k->src_id == KDBUS_SRC_ID_KERNEL)
825 m->sender = "org.freedesktop.DBus";
827 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
828 m->sender = m->creds.unique_name = m->sender_buffer;
829 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
832 if (!m->destination) {
834 m->destination = destination;
835 else if (k->dst_id != KDBUS_DST_ID_NAME &&
836 k->dst_id != KDBUS_DST_ID_BROADCAST) {
837 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
838 m->destination = m->destination_buffer;
842 /* We take possession of the kmsg struct now */
844 m->release_kdbus = true;
848 bus->rqueue[bus->rqueue_size++] = m;
854 struct bus_body_part *part;
857 /* Make sure the memfds are not freed twice */
858 MESSAGE_FOREACH_PART(part, i, m)
859 if (part->memfd >= 0)
862 sd_bus_message_unref(m);
868 int bus_kernel_read_message(sd_bus *bus) {
875 r = bus_rqueue_make_room(bus);
879 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
886 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
888 if (k->payload_type == KDBUS_PAYLOAD_DBUS)
889 r = bus_kernel_make_message(bus, k);
890 else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
891 r = bus_kernel_translate_message(bus, k);
896 close_kdbus_msg(bus, k);
898 return r < 0 ? r : 1;
901 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
902 struct memfd_cache *c;
908 if (!bus || !bus->is_kernel)
911 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
913 if (bus->n_memfd_cache <= 0) {
916 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
918 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
927 c = &bus->memfd_cache[--bus->n_memfd_cache];
930 assert(c->size == 0 || c->address);
932 *address = c->address;
936 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
941 static void close_and_munmap(int fd, void *address, size_t size) {
943 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
945 close_nointr_nofail(fd);
948 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
949 struct memfd_cache *c;
950 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
953 assert(size == 0 || address);
955 if (!bus || !bus->is_kernel) {
956 close_and_munmap(fd, address, size);
960 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
962 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
963 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
965 close_and_munmap(fd, address, size);
969 c = &bus->memfd_cache[bus->n_memfd_cache++];
971 c->address = address;
973 /* If overly long, let's return a bit to the OS */
975 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
976 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
981 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
984 void bus_kernel_flush_memfd(sd_bus *b) {
989 for (i = 0; i < b->n_memfd_cache; i++)
990 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
993 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
998 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
999 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1001 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1002 f |= KDBUS_NAME_REPLACE_EXISTING;
1004 if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1005 f |= KDBUS_NAME_QUEUE;
1011 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1016 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1017 m |= KDBUS_ATTACH_CREDS;
1019 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1020 m |= KDBUS_ATTACH_COMM;
1022 if (mask & SD_BUS_CREDS_EXE)
1023 m |= KDBUS_ATTACH_EXE;
1025 if (mask & SD_BUS_CREDS_CMDLINE)
1026 m |= KDBUS_ATTACH_CMDLINE;
1028 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))
1029 m |= KDBUS_ATTACH_CGROUP;
1031 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1032 m |= KDBUS_ATTACH_CAPS;
1034 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1035 m |= KDBUS_ATTACH_SECLABEL;
1037 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1038 m |= KDBUS_ATTACH_AUDIT;
1040 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1041 m |= KDBUS_ATTACH_NAMES;
1047 int bus_kernel_create_bus(const char *name, char **s) {
1048 struct kdbus_cmd_bus_make *make;
1049 struct kdbus_item *n;
1055 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1059 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1060 offsetof(struct kdbus_item, str) +
1061 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1064 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1065 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1066 n->type = KDBUS_ITEM_MAKE_NAME;
1068 make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1069 make->flags = KDBUS_MAKE_POLICY_OPEN;
1070 make->bloom_size = BLOOM_SIZE;
1071 assert_cc(BLOOM_SIZE % 8 == 0);
1073 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1074 close_nointr_nofail(fd);
1078 /* The higher 32bit of the flags field are considered
1079 * 'incompatible flags'. Refuse them all for now. */
1080 if (make->flags > 0xFFFFFFFFULL) {
1081 close_nointr_nofail(fd);
1088 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1090 close_nointr_nofail(fd);
1100 int bus_kernel_create_starter(const char *bus, const char *name) {
1101 struct kdbus_cmd_hello *hello;
1102 struct kdbus_item *n;
1109 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1110 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1112 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1116 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1117 offsetof(struct kdbus_item, str) +
1121 strcpy(n->str, name);
1122 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1123 n->type = KDBUS_ITEM_STARTER_NAME;
1125 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1126 hello->conn_flags = KDBUS_HELLO_STARTER;
1127 hello->pool_size = KDBUS_POOL_SIZE;
1129 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1130 close_nointr_nofail(fd);
1134 /* The higher 32bit of both flags fields are considered
1135 * 'incompatible flags'. Refuse them all for now. */
1136 if (hello->bus_flags > 0xFFFFFFFFULL ||
1137 hello->conn_flags > 0xFFFFFFFFULL) {
1138 close_nointr_nofail(fd);
1142 if (hello->bloom_size != BLOOM_SIZE) {
1143 close_nointr_nofail(fd);
1150 int bus_kernel_create_namespace(const char *name, char **s) {
1151 struct kdbus_cmd_ns_make *make;
1152 struct kdbus_item *n;
1158 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1162 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) +
1163 offsetof(struct kdbus_item, str) +
1167 strcpy(n->str, name);
1168 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1169 n->type = KDBUS_ITEM_MAKE_NAME;
1171 make->size = ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) + n->size);
1172 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1174 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1175 close_nointr_nofail(fd);
1179 /* The higher 32bit of the flags field are considered
1180 * 'incompatible flags'. Refuse them all for now. */
1181 if (make->flags > 0xFFFFFFFFULL) {
1182 close_nointr_nofail(fd);
1189 p = strappend("/dev/kdbus/ns/", name);
1191 close_nointr_nofail(fd);