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"
37 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
43 if (!startswith(s, ":1."))
46 r = safe_atou64(s + 3, id);
53 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
59 /* Note that p can be NULL, which encodes a region full of
60 * zeroes, which is useful to optimize certain padding
63 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
64 (*d)->type = KDBUS_MSG_PAYLOAD_VEC;
65 (*d)->vec.address = PTR_TO_UINT64(p);
68 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
71 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
77 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
78 (*d)->type = KDBUS_MSG_PAYLOAD_MEMFD;
79 (*d)->memfd.fd = memfd;
80 (*d)->memfd.size = sz;
82 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
85 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
91 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
92 (*d)->type = KDBUS_MSG_DST_NAME;
93 memcpy((*d)->str, s, length + 1);
95 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
98 static void* append_bloom(struct kdbus_item **d, size_t length) {
105 (*d)->size = offsetof(struct kdbus_item, data) + length;
106 (*d)->type = KDBUS_MSG_BLOOM;
109 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
114 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
120 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
121 (*d)->type = KDBUS_MSG_FDS;
122 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
124 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
127 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
134 memset(bloom, 0, BLOOM_SIZE);
136 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
139 bloom_add_pair(bloom, "interface", m->interface);
141 bloom_add_pair(bloom, "member", m->member);
143 bloom_add_pair(bloom, "path", m->path);
144 bloom_add_pair(bloom, "path-slash-prefix", m->path);
145 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
148 r = sd_bus_message_rewind(m, true);
152 for (i = 0; i < 64; i++) {
155 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
158 r = sd_bus_message_peek_type(m, &type, NULL);
162 if (type != SD_BUS_TYPE_STRING &&
163 type != SD_BUS_TYPE_OBJECT_PATH &&
164 type != SD_BUS_TYPE_SIGNATURE)
167 r = sd_bus_message_read_basic(m, type, &t);
171 e = stpcpy(buf, "arg");
175 *(e++) = '0' + (i / 10);
176 *(e++) = '0' + (i % 10);
180 bloom_add_pair(bloom, buf, t);
182 strcpy(e, "-dot-prefix");
183 bloom_add_prefixes(bloom, buf, t, '.');
184 strcpy(e, "-slash-prefix");
185 bloom_add_prefixes(bloom, buf, t, '/');
191 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
192 struct bus_body_part *part;
193 struct kdbus_item *d;
207 if (m->destination) {
208 r = bus_kernel_parse_unique_name(m->destination, &unique);
216 sz = offsetof(struct kdbus_msg, items);
218 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
219 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
221 /* Add in fixed header, fields header and payload */
222 sz += (1 + m->n_body_parts) *
223 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
225 /* Add space for bloom filter */
226 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
228 /* Add in well-known destination header */
230 dl = strlen(m->destination);
231 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
234 /* Add space for unix fds */
236 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
238 m->kdbus = memalign(8, sz);
244 m->free_kdbus = true;
245 memset(m->kdbus, 0, sz);
248 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
249 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
252 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
253 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
254 m->kdbus->cookie = m->header->serial;
256 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
261 append_destination(&d, m->destination, dl);
263 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
265 MESSAGE_FOREACH_PART(part, i, m) {
267 /* If this is padding then simply send a
268 * vector with a NULL data pointer which the
269 * kernel will just pass through. This is the
270 * most efficient way to encode zeroes */
272 append_payload_vec(&d, NULL, part->size);
276 if (part->memfd >= 0 && part->sealed && m->destination) {
277 /* Try to send a memfd, if the part is
278 * sealed and this is not a broadcast. Since we can only */
280 append_payload_memfd(&d, part->memfd, part->size);
284 /* Otherwise let's send a vector to the actual data,
285 * for that we need to map it first. */
286 r = bus_body_part_map(part);
290 append_payload_vec(&d, part->data, part->size);
293 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
296 p = append_bloom(&d, BLOOM_SIZE);
297 r = bus_message_setup_bloom(m, p);
303 append_fds(&d, m->fds, m->n_fds);
305 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
306 assert(m->kdbus->size <= sz);
315 int bus_kernel_take_fd(sd_bus *b) {
316 struct kdbus_cmd_hello hello;
327 hello.size = sizeof(hello);
328 hello.conn_flags = b->hello_flags;
329 hello.attach_flags = b->attach_flags;
330 hello.pool_size = KDBUS_POOL_SIZE;
332 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
336 if (!b->kdbus_buffer) {
337 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
338 if (b->kdbus_buffer == MAP_FAILED) {
339 b->kdbus_buffer = NULL;
344 /* The higher 32bit of both flags fields are considered
345 * 'incompatible flags'. Refuse them all for now. */
346 if (hello.bus_flags > 0xFFFFFFFFULL ||
347 hello.conn_flags > 0xFFFFFFFFULL)
350 if (hello.bloom_size != BLOOM_SIZE)
353 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
357 b->bus_client = true;
358 b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
360 /* the kernel told us the UUID of the underlying bus */
361 memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
363 r = bus_start_running(b);
370 int bus_kernel_connect(sd_bus *b) {
372 assert(b->input_fd < 0);
373 assert(b->output_fd < 0);
379 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
383 b->output_fd = b->input_fd;
385 return bus_kernel_take_fd(b);
388 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
393 assert(bus->state == BUS_RUNNING);
395 r = bus_message_setup_kmsg(bus, m);
399 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
401 return errno == EAGAIN ? 0 : -errno;
406 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
408 struct kdbus_item *d;
413 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
414 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
416 KDBUS_PART_FOREACH(d, k, items) {
418 if (d->type == KDBUS_MSG_FDS)
419 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
420 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
421 close_nointr_nofail(d->memfd.fd);
425 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
426 sd_bus_message *m = NULL;
427 struct kdbus_item *d;
429 _cleanup_free_ int *fds = NULL;
430 struct bus_header *h = NULL;
431 size_t total, n_bytes = 0, idx = 0;
432 const char *destination = NULL, *seclabel = NULL;
439 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
442 KDBUS_PART_FOREACH(d, k, items) {
445 l = d->size - offsetof(struct kdbus_item, data);
447 if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
450 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
452 if (!bus_header_is_complete(h, d->vec.size))
456 n_bytes += d->vec.size;
458 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
463 n_bytes += d->memfd.size;
465 } else if (d->type == KDBUS_MSG_FDS) {
470 f = realloc(fds, sizeof(int) * (n_fds + j));
475 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
478 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
485 r = bus_header_message_size(h, &total);
489 if (n_bytes != total)
492 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
496 KDBUS_PART_FOREACH(d, k, items) {
499 l = d->size - offsetof(struct kdbus_item, data);
501 if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
504 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
506 if (idx + d->vec.size > begin_body) {
507 struct bus_body_part *part;
509 /* Contains body material */
511 part = message_append_part(m);
517 /* A -1 offset is NUL padding. */
518 part->is_zero = d->vec.offset == ~0ULL;
520 if (idx >= begin_body) {
522 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
523 part->size = d->vec.size;
526 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
527 part->size = d->vec.size - (begin_body - idx);
534 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
535 struct bus_body_part *part;
537 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
542 part = message_append_part(m);
548 part->memfd = d->memfd.fd;
549 part->size = d->memfd.size;
552 idx += d->memfd.size;
554 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
555 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
556 m->creds.uid = d->creds.uid;
557 m->creds.gid = d->creds.gid;
558 m->creds.pid = d->creds.pid;
559 m->creds.tid = d->creds.tid;
560 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;
562 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
563 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
564 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
566 } else if (d->type == KDBUS_MSG_SRC_PID_COMM) {
567 m->creds.comm = d->str;
568 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
570 } else if (d->type == KDBUS_MSG_SRC_TID_COMM) {
571 m->creds.tid_comm = d->str;
572 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
574 } else if (d->type == KDBUS_MSG_SRC_EXE) {
575 m->creds.exe = d->str;
576 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
578 } else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
579 m->creds.cmdline = d->str;
580 m->creds.cmdline_length = l;
581 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
583 } else if (d->type == KDBUS_MSG_SRC_CGROUP) {
584 m->creds.cgroup = d->str;
585 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;
587 } else if (d->type == KDBUS_MSG_SRC_AUDIT) {
588 m->creds.audit_session_id = d->audit.sessionid;
589 m->creds.audit_login_uid = d->audit.loginuid;
590 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
592 } else if (d->type == KDBUS_MSG_SRC_CAPS) {
593 m->creds.capability = d->data;
594 m->creds.capability_size = l;
595 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;
597 } else if (d->type == KDBUS_MSG_DST_NAME)
598 destination = d->str;
599 else if (d->type != KDBUS_MSG_FDS &&
600 d->type != KDBUS_MSG_SRC_SECLABEL &&
601 d->type != KDBUS_MSG_SRC_NAMES)
602 log_debug("Got unknown field from kernel %llu", d->type);
605 r = bus_message_parse_fields(m);
609 if (k->src_id == KDBUS_SRC_ID_KERNEL)
610 m->sender = "org.freedesktop.DBus";
612 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
613 m->sender = m->sender_buffer;
616 if (!m->destination) {
618 m->destination = destination;
619 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
620 k->dst_id != KDBUS_DST_ID_BROADCAST) {
621 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
622 m->destination = m->destination_buffer;
626 /* We take possession of the kmsg struct now */
628 m->release_kdbus = true;
638 struct bus_body_part *part;
641 /* Make sure the memfds are not freed twice */
642 MESSAGE_FOREACH_PART(part, i, m)
643 if (part->memfd >= 0)
646 sd_bus_message_unref(m);
652 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
660 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
667 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
669 r = bus_kernel_make_message(bus, k, m);
671 close_kdbus_msg(bus, k);
673 return r < 0 ? r : 1;
676 int bus_kernel_create(const char *name, char **s) {
677 struct kdbus_cmd_bus_make *make;
678 struct kdbus_item *n;
686 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
691 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
692 KDBUS_PART_HEADER_SIZE + sizeof(uint64_t) +
693 KDBUS_PART_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
696 n->type = KDBUS_MAKE_NAME;
697 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
698 n->size = KDBUS_PART_HEADER_SIZE + strlen(n->str) + 1;
700 make->size = offsetof(struct kdbus_cmd_bus_make, items) + n->size;
701 make->flags = KDBUS_MAKE_POLICY_OPEN;
703 make->bloom_size = BLOOM_SIZE;
704 assert_cc(BLOOM_SIZE % 8 == 0);
706 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
710 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
711 close_nointr_nofail(fd);
722 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
723 struct memfd_cache *c;
729 if (!bus || !bus->is_kernel)
732 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
734 if (bus->n_memfd_cache <= 0) {
737 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
739 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
748 c = &bus->memfd_cache[--bus->n_memfd_cache];
751 assert(c->size == 0 || c->address);
753 *address = c->address;
757 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
762 static void close_and_munmap(int fd, void *address, size_t size) {
764 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
766 close_nointr_nofail(fd);
769 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
770 struct memfd_cache *c;
771 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
774 assert(size == 0 || address);
776 if (!bus || !bus->is_kernel) {
777 close_and_munmap(fd, address, size);
781 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
783 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
784 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
786 close_and_munmap(fd, address, size);
790 c = &bus->memfd_cache[bus->n_memfd_cache++];
792 c->address = address;
794 /* If overly long, let's return a bit to the OS */
796 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
797 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
802 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
805 void bus_kernel_flush_memfd(sd_bus *b) {
810 for (i = 0; i < b->n_memfd_cache; i++)
811 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
814 int sd_bus_kernel_translate_request_name_flags(uint64_t sd_bus_flags, uint64_t *kdbus_flags) {
816 assert_return(kdbus_flags != NULL, -EINVAL);
820 if (sd_bus_flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
821 *kdbus_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
823 if (sd_bus_flags & SD_BUS_NAME_REPLACE_EXISTING)
824 *kdbus_flags |= KDBUS_NAME_REPLACE_EXISTING;
826 if (!(sd_bus_flags & SD_BUS_NAME_DO_NOT_QUEUE))
827 *kdbus_flags |= KDBUS_NAME_QUEUE;