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.pool_size = KDBUS_POOL_SIZE;
331 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
335 if (!b->kdbus_buffer) {
336 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
337 if (b->kdbus_buffer == MAP_FAILED) {
338 b->kdbus_buffer = NULL;
343 /* The higher 32bit of both flags fields are considered
344 * 'incompatible flags'. Refuse them all for now. */
345 if (hello.bus_flags > 0xFFFFFFFFULL ||
346 hello.conn_flags > 0xFFFFFFFFULL)
349 if (hello.bloom_size != BLOOM_SIZE)
352 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
356 b->bus_client = true;
357 b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
359 r = bus_start_running(b);
366 int bus_kernel_connect(sd_bus *b) {
368 assert(b->input_fd < 0);
369 assert(b->output_fd < 0);
375 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
379 b->output_fd = b->input_fd;
381 return bus_kernel_take_fd(b);
384 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
389 assert(bus->state == BUS_RUNNING);
391 r = bus_message_setup_kmsg(bus, m);
395 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
397 return errno == EAGAIN ? 0 : -errno;
402 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
404 struct kdbus_item *d;
409 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
410 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
412 KDBUS_ITEM_FOREACH(d, k) {
414 if (d->type == KDBUS_MSG_FDS)
415 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
416 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
417 close_nointr_nofail(d->memfd.fd);
421 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
422 sd_bus_message *m = NULL;
423 struct kdbus_item *d;
425 _cleanup_free_ int *fds = NULL;
426 struct bus_header *h = NULL;
427 size_t total, n_bytes = 0, idx = 0;
428 const char *destination = NULL, *seclabel = NULL;
435 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
438 KDBUS_ITEM_FOREACH(d, k) {
441 l = d->size - offsetof(struct kdbus_item, data);
443 if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
446 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
448 if (!bus_header_is_complete(h, d->vec.size))
452 n_bytes += d->vec.size;
454 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
459 n_bytes += d->memfd.size;
461 } else if (d->type == KDBUS_MSG_FDS) {
466 f = realloc(fds, sizeof(int) * (n_fds + j));
471 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
474 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
481 r = bus_header_message_size(h, &total);
485 if (n_bytes != total)
488 r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
492 KDBUS_ITEM_FOREACH(d, k) {
495 l = d->size - offsetof(struct kdbus_item, data);
497 if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
500 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
502 if (idx + d->vec.size > begin_body) {
503 struct bus_body_part *part;
505 /* Contains body material */
507 part = message_append_part(m);
513 /* A -1 offset is NUL padding. */
514 part->is_zero = d->vec.offset == ~0ULL;
516 if (idx >= begin_body) {
518 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
519 part->size = d->vec.size;
522 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
523 part->size = d->vec.size - (begin_body - idx);
530 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
531 struct bus_body_part *part;
533 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
538 part = message_append_part(m);
544 part->memfd = d->memfd.fd;
545 part->size = d->memfd.size;
548 idx += d->memfd.size;
550 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
551 m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
552 m->uid = d->creds.uid;
553 m->gid = d->creds.gid;
554 m->pid = d->creds.pid;
555 m->tid = d->creds.tid;
556 m->uid_valid = m->gid_valid = true;
557 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
558 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
559 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
560 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
562 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
563 m->tid_comm = d->str;
564 else if (d->type == KDBUS_MSG_SRC_EXE)
566 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
568 m->cmdline_length = l;
569 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
571 else if (d->type == KDBUS_MSG_SRC_AUDIT)
572 m->audit = &d->audit;
573 else if (d->type == KDBUS_MSG_SRC_CAPS) {
574 m->capability = d->data;
575 m->capability_size = l;
576 } else if (d->type == KDBUS_MSG_DST_NAME)
577 destination = d->str;
578 else if (d->type != KDBUS_MSG_FDS &&
579 d->type != KDBUS_MSG_SRC_SECLABEL)
580 log_debug("Got unknown field from kernel %llu", d->type);
583 r = bus_message_parse_fields(m);
587 if (k->src_id == KDBUS_SRC_ID_KERNEL)
588 m->sender = "org.freedesktop.DBus";
590 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
591 m->sender = m->sender_buffer;
594 if (!m->destination) {
596 m->destination = destination;
597 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
598 k->dst_id != KDBUS_DST_ID_BROADCAST) {
599 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
600 m->destination = m->destination_buffer;
604 /* We take possession of the kmsg struct now */
606 m->bus = sd_bus_ref(bus);
607 m->release_kdbus = true;
617 struct bus_body_part *part;
620 /* Make sure the memfds are not freed twice */
621 MESSAGE_FOREACH_PART(part, i, m)
622 if (part->memfd >= 0)
625 sd_bus_message_unref(m);
631 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
639 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
646 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
648 r = bus_kernel_make_message(bus, k, m);
650 close_kdbus_msg(bus, k);
652 return r < 0 ? r : 1;
655 int bus_kernel_create(const char *name, char **s) {
656 struct kdbus_cmd_bus_make *make;
657 struct kdbus_item *n;
665 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
670 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
671 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
672 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
675 n->type = KDBUS_MAKE_NAME;
676 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
677 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
679 make->size = offsetof(struct kdbus_cmd_bus_make, items) + n->size;
680 make->flags = KDBUS_MAKE_POLICY_OPEN;
682 make->bloom_size = BLOOM_SIZE;
683 assert_cc(BLOOM_SIZE % 8 == 0);
685 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
689 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
690 close_nointr_nofail(fd);
701 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
702 struct memfd_cache *c;
708 if (!bus || !bus->is_kernel)
711 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
713 if (bus->n_memfd_cache <= 0) {
716 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
718 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
727 c = &bus->memfd_cache[--bus->n_memfd_cache];
730 assert(c->size == 0 || c->address);
732 *address = c->address;
736 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
741 static void close_and_munmap(int fd, void *address, size_t size) {
743 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
745 close_nointr_nofail(fd);
748 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
749 struct memfd_cache *c;
750 uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
753 assert(size == 0 || address);
755 if (!bus || !bus->is_kernel) {
756 close_and_munmap(fd, address, size);
760 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
762 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
763 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
765 close_and_munmap(fd, address, size);
769 c = &bus->memfd_cache[bus->n_memfd_cache++];
771 c->address = address;
773 /* If overly long, let's return a bit to the OS */
775 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
776 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
781 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
784 void bus_kernel_flush_memfd(sd_bus *b) {
789 for (i = 0; i < b->n_memfd_cache; i++)
790 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);