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 uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
317 ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
318 ALIGN8(sizeof(struct kdbus_vec))] = {};
320 struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
331 if (!b->kdbus_buffer) {
332 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
333 if (b->kdbus_buffer == MAP_FAILED) {
334 b->kdbus_buffer = NULL;
339 hello->size = sizeof(h);
340 hello->conn_flags = b->hello_flags;
342 hello->items[0].type = KDBUS_HELLO_POOL;
343 hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
344 hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
345 hello->items[0].vec.size = KDBUS_POOL_SIZE;
347 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
351 /* The higher 32bit of both flags fields are considered
352 * 'incompatible flags'. Refuse them all for now. */
353 if (hello->bus_flags > 0xFFFFFFFFULL ||
354 hello->conn_flags > 0xFFFFFFFFULL)
357 if (hello->bloom_size != BLOOM_SIZE)
360 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
364 b->bus_client = true;
365 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
367 r = bus_start_running(b);
374 int bus_kernel_connect(sd_bus *b) {
376 assert(b->input_fd < 0);
377 assert(b->output_fd < 0);
383 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
387 b->output_fd = b->input_fd;
389 return bus_kernel_take_fd(b);
392 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
397 assert(bus->state == BUS_RUNNING);
399 r = bus_message_setup_kmsg(bus, m);
403 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
405 return errno == EAGAIN ? 0 : -errno;
410 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
411 struct kdbus_item *d;
416 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
418 KDBUS_ITEM_FOREACH(d, k) {
420 if (d->type == KDBUS_MSG_FDS)
421 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
422 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
423 close_nointr_nofail(d->memfd.fd);
427 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
428 sd_bus_message *m = NULL;
429 struct kdbus_item *d;
431 _cleanup_free_ int *fds = NULL;
432 struct bus_header *h = NULL;
433 size_t total, n_bytes = 0, idx = 0;
434 const char *destination = NULL, *seclabel = NULL;
441 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
444 KDBUS_ITEM_FOREACH(d, k) {
447 l = d->size - offsetof(struct kdbus_item, data);
449 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
452 h = UINT64_TO_PTR(d->vec.address);
454 if (!bus_header_is_complete(h, d->vec.size))
458 n_bytes += d->vec.size;
460 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
465 n_bytes += d->memfd.size;
467 } else if (d->type == KDBUS_MSG_FDS) {
472 f = realloc(fds, sizeof(int) * (n_fds + j));
477 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
480 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
487 r = bus_header_message_size(h, &total);
491 if (n_bytes != total)
494 r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
498 KDBUS_ITEM_FOREACH(d, k) {
501 l = d->size - offsetof(struct kdbus_item, data);
503 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
506 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
508 if (idx + d->vec.size > begin_body) {
509 struct bus_body_part *part;
511 /* Contains body material */
513 part = message_append_part(m);
519 if (idx >= begin_body) {
520 part->data = UINT64_TO_PTR(d->vec.address);
521 part->size = d->vec.size;
523 part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
524 part->size = d->vec.size - (begin_body - idx);
527 part->is_zero = d->vec.address == 0;
532 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
533 struct bus_body_part *part;
535 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
540 part = message_append_part(m);
546 part->memfd = d->memfd.fd;
547 part->size = d->memfd.size;
550 idx += d->memfd.size;
552 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
553 m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
554 m->uid = d->creds.uid;
555 m->gid = d->creds.gid;
556 m->pid = d->creds.pid;
557 m->tid = d->creds.tid;
558 m->uid_valid = m->gid_valid = true;
559 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
560 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
561 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
562 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
564 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
565 m->tid_comm = d->str;
566 else if (d->type == KDBUS_MSG_SRC_EXE)
568 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
570 m->cmdline_length = l;
571 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
573 else if (d->type == KDBUS_MSG_SRC_AUDIT)
574 m->audit = &d->audit;
575 else if (d->type == KDBUS_MSG_SRC_CAPS) {
576 m->capability = d->data;
577 m->capability_size = l;
578 } else if (d->type == KDBUS_MSG_DST_NAME)
579 destination = d->str;
580 else if (d->type != KDBUS_MSG_FDS &&
581 d->type != KDBUS_MSG_SRC_SECLABEL)
582 log_debug("Got unknown field from kernel %llu", d->type);
585 r = bus_message_parse_fields(m);
589 if (k->src_id == KDBUS_SRC_ID_KERNEL)
590 m->sender = "org.freedesktop.DBus";
592 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
593 m->sender = m->sender_buffer;
596 if (!m->destination) {
598 m->destination = destination;
599 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
600 k->dst_id != KDBUS_DST_ID_BROADCAST) {
601 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
602 m->destination = m->destination_buffer;
606 /* We take possession of the kmsg struct now */
608 m->bus = sd_bus_ref(bus);
609 m->release_kdbus = true;
619 struct bus_body_part *part;
622 /* Make sure the memfds are not freed twice */
623 MESSAGE_FOREACH_PART(part, i, m)
624 if (part->memfd >= 0)
627 sd_bus_message_unref(m);
633 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
641 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr);
648 k = UINT64_TO_PTR(addr);
650 r = bus_kernel_make_message(bus, k, m);
652 close_kdbus_msg(bus, k);
654 return r < 0 ? r : 1;
657 int bus_kernel_create(const char *name, char **s) {
658 struct kdbus_cmd_bus_make *make;
659 struct kdbus_item *n, *cg;
667 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
672 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
673 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
674 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
677 cg->type = KDBUS_MAKE_CGROUP;
679 cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
681 n = KDBUS_ITEM_NEXT(cg);
682 n->type = KDBUS_MAKE_NAME;
683 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
684 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
686 make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
687 make->flags = KDBUS_MAKE_POLICY_OPEN;
689 make->bloom_size = BLOOM_SIZE;
690 assert_cc(BLOOM_SIZE % 8 == 0);
692 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
696 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
697 close_nointr_nofail(fd);
708 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
709 struct memfd_cache *c;
715 if (!bus || !bus->is_kernel)
718 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
720 if (bus->n_memfd_cache <= 0) {
723 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
725 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
734 c = &bus->memfd_cache[-- bus->n_memfd_cache];
737 assert(c->size == 0 || c->address);
739 *address = c->address;
743 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
748 static void close_and_munmap(int fd, void *address, size_t size) {
750 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
752 close_nointr_nofail(fd);
755 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
756 struct memfd_cache *c;
757 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
760 assert(size == 0 || address);
762 if (!bus || !bus->is_kernel) {
763 close_and_munmap(fd, address, size);
767 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
769 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
770 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
772 close_and_munmap(fd, address, size);
776 c = &bus->memfd_cache[bus->n_memfd_cache++];
778 c->address = address;
780 /* If overly long, let's return a bit to the OS */
782 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
783 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
788 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
791 void bus_kernel_flush_memfd(sd_bus *b) {
796 for (i = 0; i < b->n_memfd_cache; i++)
797 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);