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_prefixes(bloom, "path-slash-prefix", m->path, '/');
147 r = sd_bus_message_rewind(m, true);
151 for (i = 0; i < 64; i++) {
154 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
157 r = sd_bus_message_peek_type(m, &type, NULL);
161 if (type != SD_BUS_TYPE_STRING &&
162 type != SD_BUS_TYPE_OBJECT_PATH &&
163 type != SD_BUS_TYPE_SIGNATURE)
166 r = sd_bus_message_read_basic(m, type, &t);
170 e = stpcpy(buf, "arg");
174 *(e++) = '0' + (i / 10);
175 *(e++) = '0' + (i % 10);
179 bloom_add_pair(bloom, buf, t);
181 strcpy(e, "-dot-prefix");
182 bloom_add_prefixes(bloom, buf, t, '.');
183 strcpy(e, "-slash-prefix");
184 bloom_add_prefixes(bloom, buf, t, '/');
190 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
191 struct bus_body_part *part;
192 struct kdbus_item *d;
206 if (m->destination) {
207 r = bus_kernel_parse_unique_name(m->destination, &unique);
215 sz = offsetof(struct kdbus_msg, items);
217 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
218 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
220 /* Add in fixed header, fields header and payload */
221 sz += (1 + m->n_body_parts) *
222 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
224 /* Add space for bloom filter */
225 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
227 /* Add in well-known destination header */
229 dl = strlen(m->destination);
230 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
233 /* Add space for unix fds */
235 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
237 m->kdbus = memalign(8, sz);
243 m->free_kdbus = true;
244 memset(m->kdbus, 0, sz);
247 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
248 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
251 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
252 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
253 m->kdbus->cookie = m->header->serial;
255 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
260 append_destination(&d, m->destination, dl);
262 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
264 MESSAGE_FOREACH_PART(part, i, m) {
266 /* If this is padding then simply send a
267 * vector with a NULL data pointer which the
268 * kernel will just pass through. This is the
269 * most efficient way to encode zeroes */
271 append_payload_vec(&d, NULL, part->size);
275 if (part->memfd >= 0 && part->sealed && m->destination) {
276 /* Try to send a memfd, if the part is
277 * sealed and this is not a broadcast. Since we can only */
279 append_payload_memfd(&d, part->memfd, part->size);
283 /* Otherwise let's send a vector to the actual data,
284 * for that we need to map it first. */
285 r = bus_body_part_map(part);
289 append_payload_vec(&d, part->data, part->size);
292 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
295 p = append_bloom(&d, BLOOM_SIZE);
296 r = bus_message_setup_bloom(m, p);
302 append_fds(&d, m->fds, m->n_fds);
304 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
305 assert(m->kdbus->size <= sz);
314 int bus_kernel_take_fd(sd_bus *b) {
315 uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
316 ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
317 ALIGN8(sizeof(struct kdbus_vec))] = {};
319 struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
328 if (!b->kdbus_buffer) {
329 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
330 if (b->kdbus_buffer == MAP_FAILED) {
331 b->kdbus_buffer = NULL;
336 hello->size = sizeof(h);
337 hello->conn_flags = b->hello_flags;
339 hello->items[0].type = KDBUS_HELLO_POOL;
340 hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
341 hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
342 hello->items[0].vec.size = KDBUS_POOL_SIZE;
344 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
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)
361 b->bus_client = true;
362 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
364 r = 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 r = bus_message_setup_kmsg(bus, m);
400 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
402 return errno == EAGAIN ? 0 : -errno;
407 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
408 struct kdbus_item *d;
413 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
415 KDBUS_ITEM_FOREACH(d, k) {
417 if (d->type == KDBUS_MSG_FDS)
418 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
419 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
420 close_nointr_nofail(d->memfd.fd);
424 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
425 sd_bus_message *m = NULL;
426 struct kdbus_item *d;
428 _cleanup_free_ int *fds = NULL;
429 struct bus_header *h = NULL;
430 size_t total, n_bytes = 0, idx = 0;
431 const char *destination = NULL, *seclabel = NULL;
438 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
441 KDBUS_ITEM_FOREACH(d, k) {
444 l = d->size - offsetof(struct kdbus_item, data);
446 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
449 h = UINT64_TO_PTR(d->vec.address);
451 if (!bus_header_is_complete(h, d->vec.size))
455 n_bytes += d->vec.size;
457 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
462 n_bytes += d->memfd.size;
464 } else if (d->type == KDBUS_MSG_FDS) {
469 f = realloc(fds, sizeof(int) * (n_fds + j));
474 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
477 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
484 r = bus_header_message_size(h, &total);
488 if (n_bytes != total)
491 r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
495 KDBUS_ITEM_FOREACH(d, k) {
498 l = d->size - offsetof(struct kdbus_item, data);
500 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
503 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
505 if (idx + d->vec.size > begin_body) {
506 struct bus_body_part *part;
508 /* Contains body material */
510 part = message_append_part(m);
516 if (idx >= begin_body) {
517 part->data = UINT64_TO_PTR(d->vec.address);
518 part->size = d->vec.size;
520 part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
521 part->size = d->vec.size - (begin_body - idx);
524 part->is_zero = d->vec.address == 0;
529 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
530 struct bus_body_part *part;
532 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
537 part = message_append_part(m);
543 part->memfd = d->memfd.fd;
544 part->size = d->memfd.size;
547 idx += d->memfd.size;
549 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
550 m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
551 m->uid = d->creds.uid;
552 m->gid = d->creds.gid;
553 m->pid = d->creds.pid;
554 m->tid = d->creds.tid;
555 m->uid_valid = m->gid_valid = true;
556 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
557 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
558 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
559 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
561 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
562 m->tid_comm = d->str;
563 else if (d->type == KDBUS_MSG_SRC_EXE)
565 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
567 m->cmdline_length = l;
568 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
570 else if (d->type == KDBUS_MSG_SRC_AUDIT)
571 m->audit = &d->audit;
572 else if (d->type == KDBUS_MSG_SRC_CAPS) {
573 m->capability = d->data;
574 m->capability_size = l;
575 } else if (d->type == KDBUS_MSG_DST_NAME)
576 destination = d->str;
577 else if (d->type != KDBUS_MSG_FDS &&
578 d->type != KDBUS_MSG_SRC_SECLABEL)
579 log_debug("Got unknown field from kernel %llu", d->type);
582 r = bus_message_parse_fields(m);
586 if (k->src_id == KDBUS_SRC_ID_KERNEL)
587 m->sender = "org.freedesktop.DBus";
589 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
590 m->sender = m->sender_buffer;
593 if (!m->destination) {
595 m->destination = destination;
596 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
597 k->dst_id != KDBUS_DST_ID_BROADCAST) {
598 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
599 m->destination = m->destination_buffer;
603 /* We take possession of the kmsg struct now */
605 m->bus = sd_bus_ref(bus);
606 m->release_kdbus = true;
616 struct bus_body_part *part;
619 /* Make sure the memfds are not freed twice */
620 MESSAGE_FOREACH_PART(part, i, m)
621 if (part->memfd >= 0)
624 sd_bus_message_unref(m);
630 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
638 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr);
645 k = UINT64_TO_PTR(addr);
647 r = bus_kernel_make_message(bus, k, m);
649 close_kdbus_msg(bus, k);
651 return r < 0 ? r : 1;
654 int bus_kernel_create(const char *name, char **s) {
655 struct kdbus_cmd_bus_make *make;
656 struct kdbus_item *n, *cg;
664 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
669 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
670 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
671 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
674 cg->type = KDBUS_MAKE_CGROUP;
676 cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
678 n = KDBUS_ITEM_NEXT(cg);
679 n->type = KDBUS_MAKE_NAME;
680 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
681 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
683 make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
684 make->flags = KDBUS_MAKE_POLICY_OPEN;
686 make->bloom_size = BLOOM_SIZE;
687 assert_cc(BLOOM_SIZE % 8 == 0);
689 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
693 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
694 close_nointr_nofail(fd);
705 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
706 struct memfd_cache *c;
712 if (!bus || !bus->is_kernel)
715 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
717 if (bus->n_memfd_cache <= 0) {
720 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
722 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
731 c = &bus->memfd_cache[-- bus->n_memfd_cache];
734 assert(c->size == 0 || c->address);
736 *address = c->address;
740 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
745 static void close_and_munmap(int fd, void *address, size_t size) {
747 assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
749 close_nointr_nofail(fd);
752 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
753 struct memfd_cache *c;
756 assert(size == 0 || address);
758 if (!bus || !bus->is_kernel) {
759 close_and_munmap(fd, address, size);
763 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
765 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
766 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
768 close_and_munmap(fd, address, size);
772 c = &bus->memfd_cache[bus->n_memfd_cache++];
774 c->address = address;
776 /* If overly long, let's return a bit to the OS */
777 if (size > MEMFD_CACHE_ITEM_SIZE_MAX) {
778 uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX;
780 ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
782 c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
786 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
789 void bus_kernel_flush_memfd(sd_bus *b) {
794 for (i = 0; i < b->n_memfd_cache; i++) {
795 if (b->memfd_cache[i].size > 0)
796 assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
798 close_nointr_nofail(b->memfd_cache[i].fd);