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 return bus_start_running(b);
371 int bus_kernel_connect(sd_bus *b) {
373 assert(b->input_fd < 0);
374 assert(b->output_fd < 0);
380 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
384 b->output_fd = b->input_fd;
386 return bus_kernel_take_fd(b);
389 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
394 assert(bus->state == BUS_RUNNING);
396 /* If we can't deliver, we want room for the error message */
397 r = bus_rqueue_make_room(bus);
401 r = bus_message_setup_kmsg(bus, m);
405 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
407 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
408 sd_bus_message *reply;
410 if (errno == EAGAIN || errno == EINTR)
412 else if (errno == ENXIO || errno == ESRCH) {
414 /* ENXIO: unique name not known
415 * ESRCH: well-known name not known */
417 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
418 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
422 } else if (errno == EADDRNOTAVAIL) {
424 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
426 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
427 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
433 r = bus_message_new_synthetic_error(
435 BUS_MESSAGE_SERIAL(m),
442 r = bus_seal_synthetic_message(bus, reply);
446 bus->rqueue[bus->rqueue_size++] = reply;
454 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
456 struct kdbus_item *d;
461 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
462 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
464 KDBUS_PART_FOREACH(d, k, items) {
466 if (d->type == KDBUS_ITEM_FDS)
467 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
468 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
469 close_nointr_nofail(d->memfd.fd);
473 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
474 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
479 r = sd_bus_message_new_signal(
481 "/org/freedesktop/DBus",
482 "org.freedesktop.DBus",
488 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
492 m->sender = "org.freedesktop.DBus";
494 r = bus_seal_synthetic_message(bus, m);
498 bus->rqueue[bus->rqueue_size++] = m;
504 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
505 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
511 if (d->name_change.flags != 0)
514 if (d->type == KDBUS_ITEM_NAME_ADD)
517 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
519 if (d->type == KDBUS_ITEM_NAME_REMOVE)
522 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
524 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
527 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
528 char owner[UNIQUE_NAME_MAX];
534 sprintf(owner, ":1.%llu", d->id_change.id);
536 return push_name_owner_changed(
538 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
539 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
542 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
543 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
550 r = bus_message_new_synthetic_error(
553 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
554 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
555 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
560 m->sender = "org.freedesktop.DBus";
562 r = bus_seal_synthetic_message(bus, m);
566 bus->rqueue[bus->rqueue_size++] = m;
572 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
573 struct kdbus_item *d, *found = NULL;
575 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
576 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
577 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
578 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
580 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
581 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
583 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
584 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
589 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
591 KDBUS_PART_FOREACH(d, k, items) {
592 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
597 log_debug("Got unknown field from kernel %llu", d->type);
601 log_debug("Didn't find a kernel message to translate.");
605 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
608 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
609 sd_bus_message *m = NULL;
610 struct kdbus_item *d;
612 _cleanup_free_ int *fds = NULL;
613 struct bus_header *h = NULL;
614 size_t total, n_bytes = 0, idx = 0;
615 const char *destination = NULL, *seclabel = NULL;
620 assert(k->payload_type == KDBUS_PAYLOAD_DBUS1);
622 KDBUS_PART_FOREACH(d, k, items) {
625 l = d->size - offsetof(struct kdbus_item, data);
629 case KDBUS_ITEM_PAYLOAD_OFF:
631 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
633 if (!bus_header_is_complete(h, d->vec.size))
637 n_bytes += d->vec.size;
640 case KDBUS_ITEM_PAYLOAD_MEMFD:
644 n_bytes += d->memfd.size;
647 case KDBUS_ITEM_FDS: {
652 f = realloc(fds, sizeof(int) * (n_fds + j));
657 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
662 case KDBUS_ITEM_SECLABEL:
671 r = bus_header_message_size(h, &total);
675 if (n_bytes != total)
678 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
682 KDBUS_PART_FOREACH(d, k, items) {
685 l = d->size - offsetof(struct kdbus_item, data);
689 case KDBUS_ITEM_PAYLOAD_OFF: {
692 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
694 if (idx + d->vec.size > begin_body) {
695 struct bus_body_part *part;
697 /* Contains body material */
699 part = message_append_part(m);
705 /* A -1 offset is NUL padding. */
706 part->is_zero = d->vec.offset == ~0ULL;
708 if (idx >= begin_body) {
710 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
711 part->size = d->vec.size;
714 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
715 part->size = d->vec.size - (begin_body - idx);
725 case KDBUS_ITEM_PAYLOAD_MEMFD: {
726 struct bus_body_part *part;
728 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
733 part = message_append_part(m);
739 part->memfd = d->memfd.fd;
740 part->size = d->memfd.size;
743 idx += d->memfd.size;
747 case KDBUS_ITEM_CREDS:
748 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
749 m->creds.uid = d->creds.uid;
750 m->creds.gid = d->creds.gid;
751 m->creds.pid = d->creds.pid;
752 m->creds.tid = d->creds.tid;
753 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;
756 case KDBUS_ITEM_TIMESTAMP:
757 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
758 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
761 case KDBUS_ITEM_PID_COMM:
762 m->creds.comm = d->str;
763 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
766 case KDBUS_ITEM_TID_COMM:
767 m->creds.tid_comm = d->str;
768 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
772 m->creds.exe = d->str;
773 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
776 case KDBUS_ITEM_CMDLINE:
777 m->creds.cmdline = d->str;
778 m->creds.cmdline_size = l;
779 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
782 case KDBUS_ITEM_CGROUP:
783 m->creds.cgroup = d->str;
784 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;
787 case KDBUS_ITEM_AUDIT:
788 m->creds.audit_session_id = d->audit.sessionid;
789 m->creds.audit_login_uid = d->audit.loginuid;
790 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
793 case KDBUS_ITEM_CAPS:
794 m->creds.capability = d->data;
795 m->creds.capability_size = l;
796 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;
799 case KDBUS_ITEM_DST_NAME:
800 destination = d->str;
803 case KDBUS_ITEM_NAMES:
804 m->creds.well_known_names = d->str;
805 m->creds.well_known_names_size = l;
806 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
810 case KDBUS_ITEM_SECLABEL:
814 log_debug("Got unknown field from kernel %llu", d->type);
818 r = bus_message_parse_fields(m);
822 if (k->src_id == KDBUS_SRC_ID_KERNEL)
823 m->sender = "org.freedesktop.DBus";
825 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
826 m->sender = m->creds.unique_name = m->sender_buffer;
827 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
830 if (!m->destination) {
832 m->destination = destination;
833 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
834 k->dst_id != KDBUS_DST_ID_BROADCAST) {
835 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
836 m->destination = m->destination_buffer;
840 /* We take possession of the kmsg struct now */
842 m->release_kdbus = true;
846 bus->rqueue[bus->rqueue_size++] = m;
852 struct bus_body_part *part;
855 /* Make sure the memfds are not freed twice */
856 MESSAGE_FOREACH_PART(part, i, m)
857 if (part->memfd >= 0)
860 sd_bus_message_unref(m);
866 int bus_kernel_read_message(sd_bus *bus) {
873 r = bus_rqueue_make_room(bus);
877 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
884 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
886 if (k->payload_type == KDBUS_PAYLOAD_DBUS1)
887 r = bus_kernel_make_message(bus, k);
888 else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
889 r = bus_kernel_translate_message(bus, k);
894 close_kdbus_msg(bus, k);
896 return r < 0 ? r : 1;
899 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
900 struct memfd_cache *c;
906 if (!bus || !bus->is_kernel)
909 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
911 if (bus->n_memfd_cache <= 0) {
914 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
916 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
925 c = &bus->memfd_cache[--bus->n_memfd_cache];
928 assert(c->size == 0 || c->address);
930 *address = c->address;
934 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
939 static void close_and_munmap(int fd, void *address, size_t size) {
941 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
943 close_nointr_nofail(fd);
946 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
947 struct memfd_cache *c;
948 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
951 assert(size == 0 || address);
953 if (!bus || !bus->is_kernel) {
954 close_and_munmap(fd, address, size);
958 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
960 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
961 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
963 close_and_munmap(fd, address, size);
967 c = &bus->memfd_cache[bus->n_memfd_cache++];
969 c->address = address;
971 /* If overly long, let's return a bit to the OS */
973 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
974 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
979 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
982 void bus_kernel_flush_memfd(sd_bus *b) {
987 for (i = 0; i < b->n_memfd_cache; i++)
988 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
991 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
996 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
997 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
999 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1000 f |= KDBUS_NAME_REPLACE_EXISTING;
1002 if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1003 f |= KDBUS_NAME_QUEUE;
1009 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1014 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1015 m |= KDBUS_ATTACH_CREDS;
1017 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1018 m |= KDBUS_ATTACH_COMM;
1020 if (mask & SD_BUS_CREDS_EXE)
1021 m |= KDBUS_ATTACH_EXE;
1023 if (mask & SD_BUS_CREDS_CMDLINE)
1024 m |= KDBUS_ATTACH_CMDLINE;
1026 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))
1027 m |= KDBUS_ATTACH_CGROUP;
1029 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1030 m |= KDBUS_ATTACH_CAPS;
1032 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1033 m |= KDBUS_ATTACH_SECLABEL;
1035 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1036 m |= KDBUS_ATTACH_AUDIT;
1038 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1039 m |= KDBUS_ATTACH_NAMES;
1045 int bus_kernel_create_bus(const char *name, char **s) {
1046 struct kdbus_cmd_bus_make *make;
1047 struct kdbus_item *n;
1053 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1057 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1058 offsetof(struct kdbus_item, str) +
1059 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1062 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1063 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1064 n->type = KDBUS_MAKE_NAME;
1066 make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1067 make->flags = KDBUS_MAKE_POLICY_OPEN;
1068 make->bus_flags = 0;
1069 make->bloom_size = BLOOM_SIZE;
1070 assert_cc(BLOOM_SIZE % 8 == 0);
1072 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1073 close_nointr_nofail(fd);
1077 /* The higher 32bit of the flags field are considered
1078 * 'incompatible flags'. Refuse them all for now. */
1079 if (make->flags > 0xFFFFFFFFULL) {
1080 close_nointr_nofail(fd);
1087 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1089 close_nointr_nofail(fd);
1099 int bus_kernel_create_starter(const char *bus, const char *name) {
1100 struct kdbus_cmd_hello *hello;
1101 struct kdbus_item *n;
1108 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1109 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1111 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1115 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1116 offsetof(struct kdbus_item, str) +
1120 strcpy(n->str, name);
1121 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1122 n->type = KDBUS_ITEM_STARTER_NAME;
1124 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1125 hello->conn_flags = KDBUS_HELLO_STARTER;
1126 hello->pool_size = KDBUS_POOL_SIZE;
1128 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1129 close_nointr_nofail(fd);
1133 /* The higher 32bit of both flags fields are considered
1134 * 'incompatible flags'. Refuse them all for now. */
1135 if (hello->bus_flags > 0xFFFFFFFFULL ||
1136 hello->conn_flags > 0xFFFFFFFFULL) {
1137 close_nointr_nofail(fd);
1141 if (hello->bloom_size != BLOOM_SIZE) {
1142 close_nointr_nofail(fd);
1149 int bus_kernel_create_namespace(const char *name, char **s) {
1150 struct kdbus_cmd_ns_make *make;
1151 struct kdbus_item *n;
1157 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1161 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) +
1162 offsetof(struct kdbus_item, str) +
1166 strcpy(n->str, name);
1167 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1168 n->type = KDBUS_MAKE_NAME;
1170 make->size = ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) + n->size);
1171 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1173 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1174 close_nointr_nofail(fd);
1178 /* The higher 32bit of the flags field are considered
1179 * 'incompatible flags'. Refuse them all for now. */
1180 if (make->flags > 0xFFFFFFFFULL) {
1181 close_nointr_nofail(fd);
1188 p = strappend("/dev/kdbus/ns/", name);
1190 close_nointr_nofail(fd);