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);
424 } else if (errno == EADDRNOTAVAIL) {
426 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
428 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
429 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
435 r = bus_message_new_synthetic_error(
437 BUS_MESSAGE_SERIAL(m),
444 r = bus_seal_synthetic_message(bus, reply);
448 bus->rqueue[bus->rqueue_size++] = reply;
456 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
458 struct kdbus_item *d;
463 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
464 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
466 KDBUS_ITEM_FOREACH(d, k, items) {
468 if (d->type == KDBUS_ITEM_FDS)
469 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
470 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
471 close_nointr_nofail(d->memfd.fd);
475 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
476 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
481 r = sd_bus_message_new_signal(
483 "/org/freedesktop/DBus",
484 "org.freedesktop.DBus",
490 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
494 m->sender = "org.freedesktop.DBus";
496 r = bus_seal_synthetic_message(bus, m);
500 bus->rqueue[bus->rqueue_size++] = m;
506 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
507 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
513 if (d->name_change.flags != 0)
516 if (d->type == KDBUS_ITEM_NAME_ADD)
519 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
521 if (d->type == KDBUS_ITEM_NAME_REMOVE)
524 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
526 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
529 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
530 char owner[UNIQUE_NAME_MAX];
536 sprintf(owner, ":1.%llu", d->id_change.id);
538 return push_name_owner_changed(
540 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
541 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
544 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
545 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
552 r = bus_message_new_synthetic_error(
555 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
556 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
557 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
562 m->sender = "org.freedesktop.DBus";
564 r = bus_seal_synthetic_message(bus, m);
568 bus->rqueue[bus->rqueue_size++] = m;
574 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
575 struct kdbus_item *d, *found = NULL;
577 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
578 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
579 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
580 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
582 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
583 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
585 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
586 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
591 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
593 KDBUS_ITEM_FOREACH(d, k, items) {
594 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
599 log_debug("Got unknown field from kernel %llu", d->type);
603 log_debug("Didn't find a kernel message to translate.");
607 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
610 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
611 sd_bus_message *m = NULL;
612 struct kdbus_item *d;
614 _cleanup_free_ int *fds = NULL;
615 struct bus_header *h = NULL;
616 size_t total, n_bytes = 0, idx = 0;
617 const char *destination = NULL, *seclabel = NULL;
622 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
624 KDBUS_ITEM_FOREACH(d, k, items) {
627 l = d->size - offsetof(struct kdbus_item, data);
631 case KDBUS_ITEM_PAYLOAD_OFF:
633 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
635 if (!bus_header_is_complete(h, d->vec.size))
639 n_bytes += d->vec.size;
642 case KDBUS_ITEM_PAYLOAD_MEMFD:
646 n_bytes += d->memfd.size;
649 case KDBUS_ITEM_FDS: {
654 f = realloc(fds, sizeof(int) * (n_fds + j));
659 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
664 case KDBUS_ITEM_SECLABEL:
673 r = bus_header_message_size(h, &total);
677 if (n_bytes != total)
680 /* on kdbus we only speak native endian gvariant, never dbus1
681 * marshalling or reverse endian */
682 if (h->version != 2 ||
683 h->endian != BUS_NATIVE_ENDIAN)
686 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
690 KDBUS_ITEM_FOREACH(d, k, items) {
693 l = d->size - offsetof(struct kdbus_item, data);
697 case KDBUS_ITEM_PAYLOAD_OFF: {
700 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
702 if (idx + d->vec.size > begin_body) {
703 struct bus_body_part *part;
705 /* Contains body material */
707 part = message_append_part(m);
713 /* A -1 offset is NUL padding. */
714 part->is_zero = d->vec.offset == ~0ULL;
716 if (idx >= begin_body) {
718 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
719 part->size = d->vec.size;
722 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
723 part->size = d->vec.size - (begin_body - idx);
733 case KDBUS_ITEM_PAYLOAD_MEMFD: {
734 struct bus_body_part *part;
736 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
741 part = message_append_part(m);
747 part->memfd = d->memfd.fd;
748 part->size = d->memfd.size;
751 idx += d->memfd.size;
755 case KDBUS_ITEM_CREDS:
756 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
757 m->creds.uid = d->creds.uid;
758 m->creds.gid = d->creds.gid;
759 m->creds.pid = d->creds.pid;
760 m->creds.tid = d->creds.tid;
761 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;
764 case KDBUS_ITEM_TIMESTAMP:
765 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
766 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
769 case KDBUS_ITEM_PID_COMM:
770 m->creds.comm = d->str;
771 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
774 case KDBUS_ITEM_TID_COMM:
775 m->creds.tid_comm = d->str;
776 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
780 m->creds.exe = d->str;
781 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
784 case KDBUS_ITEM_CMDLINE:
785 m->creds.cmdline = d->str;
786 m->creds.cmdline_size = l;
787 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
790 case KDBUS_ITEM_CGROUP:
791 m->creds.cgroup = d->str;
792 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;
795 case KDBUS_ITEM_AUDIT:
796 m->creds.audit_session_id = d->audit.sessionid;
797 m->creds.audit_login_uid = d->audit.loginuid;
798 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
801 case KDBUS_ITEM_CAPS:
802 m->creds.capability = d->data;
803 m->creds.capability_size = l;
804 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;
807 case KDBUS_ITEM_DST_NAME:
808 destination = d->str;
811 case KDBUS_ITEM_NAME:
812 r = strv_extend(&m->creds.well_known_names, d->name.name);
815 m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
819 case KDBUS_ITEM_SECLABEL:
823 log_debug("Got unknown field from kernel %llu", d->type);
827 r = bus_message_parse_fields(m);
831 if (k->src_id == KDBUS_SRC_ID_KERNEL)
832 m->sender = "org.freedesktop.DBus";
834 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
835 m->sender = m->creds.unique_name = m->sender_buffer;
836 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
839 if (!m->destination) {
841 m->destination = destination;
842 else if (k->dst_id != KDBUS_DST_ID_NAME &&
843 k->dst_id != KDBUS_DST_ID_BROADCAST) {
844 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
845 m->destination = m->destination_buffer;
849 /* We take possession of the kmsg struct now */
851 m->release_kdbus = true;
855 bus->rqueue[bus->rqueue_size++] = m;
861 struct bus_body_part *part;
864 /* Make sure the memfds are not freed twice */
865 MESSAGE_FOREACH_PART(part, i, m)
866 if (part->memfd >= 0)
869 sd_bus_message_unref(m);
875 int bus_kernel_read_message(sd_bus *bus) {
882 r = bus_rqueue_make_room(bus);
886 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
893 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
895 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
896 r = bus_kernel_make_message(bus, k);
898 /* Anybody can send us invalid messages, let's just drop them. */
899 if (r == -EBADMSG || r == -EPROTOTYPE) {
900 log_error("Ignoring invalid message: %s", strerror(-r));
904 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
905 r = bus_kernel_translate_message(bus, k);
910 close_kdbus_msg(bus, k);
912 return r < 0 ? r : 1;
915 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
916 struct memfd_cache *c;
922 if (!bus || !bus->is_kernel)
925 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
927 if (bus->n_memfd_cache <= 0) {
930 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
932 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
941 c = &bus->memfd_cache[--bus->n_memfd_cache];
944 assert(c->size == 0 || c->address);
946 *address = c->address;
950 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
955 static void close_and_munmap(int fd, void *address, size_t size) {
957 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
959 close_nointr_nofail(fd);
962 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
963 struct memfd_cache *c;
964 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
967 assert(size == 0 || address);
969 if (!bus || !bus->is_kernel) {
970 close_and_munmap(fd, address, size);
974 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
976 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
977 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
979 close_and_munmap(fd, address, size);
983 c = &bus->memfd_cache[bus->n_memfd_cache++];
985 c->address = address;
987 /* If overly long, let's return a bit to the OS */
989 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
990 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
995 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
998 void bus_kernel_flush_memfd(sd_bus *b) {
1003 for (i = 0; i < b->n_memfd_cache; i++)
1004 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
1007 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1010 assert(kdbus_flags);
1012 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1013 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1015 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1016 f |= KDBUS_NAME_REPLACE_EXISTING;
1018 if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1019 f |= KDBUS_NAME_QUEUE;
1025 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1030 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1031 m |= KDBUS_ATTACH_CREDS;
1033 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1034 m |= KDBUS_ATTACH_COMM;
1036 if (mask & SD_BUS_CREDS_EXE)
1037 m |= KDBUS_ATTACH_EXE;
1039 if (mask & SD_BUS_CREDS_CMDLINE)
1040 m |= KDBUS_ATTACH_CMDLINE;
1042 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))
1043 m |= KDBUS_ATTACH_CGROUP;
1045 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1046 m |= KDBUS_ATTACH_CAPS;
1048 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1049 m |= KDBUS_ATTACH_SECLABEL;
1051 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1052 m |= KDBUS_ATTACH_AUDIT;
1054 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1055 m |= KDBUS_ATTACH_NAMES;
1061 int bus_kernel_create_bus(const char *name, char **s) {
1062 struct kdbus_cmd_bus_make *make;
1063 struct kdbus_item *n;
1069 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1073 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1074 offsetof(struct kdbus_item, str) +
1075 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1078 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1079 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1080 n->type = KDBUS_ITEM_MAKE_NAME;
1082 make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1083 make->flags = KDBUS_MAKE_POLICY_OPEN;
1084 make->bloom_size = BLOOM_SIZE;
1085 assert_cc(BLOOM_SIZE % 8 == 0);
1087 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1088 close_nointr_nofail(fd);
1092 /* The higher 32bit of the flags field are considered
1093 * 'incompatible flags'. Refuse them all for now. */
1094 if (make->flags > 0xFFFFFFFFULL) {
1095 close_nointr_nofail(fd);
1102 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1104 close_nointr_nofail(fd);
1114 int bus_kernel_create_starter(const char *bus, const char *name) {
1115 struct kdbus_cmd_hello *hello;
1116 struct kdbus_item *n;
1123 p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
1124 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1126 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1130 hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
1131 offsetof(struct kdbus_item, str) +
1135 strcpy(n->str, name);
1136 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1137 n->type = KDBUS_ITEM_STARTER_NAME;
1139 hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
1140 hello->conn_flags = KDBUS_HELLO_STARTER;
1141 hello->pool_size = KDBUS_POOL_SIZE;
1143 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1144 close_nointr_nofail(fd);
1148 /* The higher 32bit of both flags fields are considered
1149 * 'incompatible flags'. Refuse them all for now. */
1150 if (hello->bus_flags > 0xFFFFFFFFULL ||
1151 hello->conn_flags > 0xFFFFFFFFULL) {
1152 close_nointr_nofail(fd);
1156 if (hello->bloom_size != BLOOM_SIZE) {
1157 close_nointr_nofail(fd);
1164 int bus_kernel_create_namespace(const char *name, char **s) {
1165 struct kdbus_cmd_ns_make *make;
1166 struct kdbus_item *n;
1172 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1176 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) +
1177 offsetof(struct kdbus_item, str) +
1181 strcpy(n->str, name);
1182 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1183 n->type = KDBUS_ITEM_MAKE_NAME;
1185 make->size = ALIGN8(offsetof(struct kdbus_cmd_ns_make, items) + n->size);
1186 make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
1188 if (ioctl(fd, KDBUS_CMD_NS_MAKE, make) < 0) {
1189 close_nointr_nofail(fd);
1193 /* The higher 32bit of the flags field are considered
1194 * 'incompatible flags'. Refuse them all for now. */
1195 if (make->flags > 0xFFFFFFFFULL) {
1196 close_nointr_nofail(fd);
1203 p = strappend("/dev/kdbus/ns/", name);
1205 close_nointr_nofail(fd);