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 #define KDBUS_ITEM_NEXT(item) \
38 (typeof(item))(((uint8_t *)item) + ALIGN8((item)->size))
40 #define KDBUS_ITEM_FOREACH(item, head) \
41 for (item = (head)->items; \
42 (uint8_t *)(item) < (uint8_t *)(head) + (head)->size; \
43 item = KDBUS_ITEM_NEXT(item))
45 #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
46 #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
48 static int parse_unique_name(const char *s, uint64_t *id) {
54 if (!startswith(s, ":1."))
57 r = safe_atou64(s + 3, id);
64 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
70 /* Note that p can be NULL, which encodes a region full of
71 * zeroes, which is useful to optimize certain padding
74 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
75 (*d)->type = KDBUS_MSG_PAYLOAD_VEC;
76 (*d)->vec.address = PTR_TO_UINT64(p);
79 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
82 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
88 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
89 (*d)->type = KDBUS_MSG_PAYLOAD_MEMFD;
90 (*d)->memfd.fd = memfd;
91 (*d)->memfd.size = sz;
93 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
96 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
102 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
103 (*d)->type = KDBUS_MSG_DST_NAME;
104 memcpy((*d)->str, s, length + 1);
106 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
109 static void* append_bloom(struct kdbus_item **d, size_t length) {
116 (*d)->size = offsetof(struct kdbus_item, data) + length;
117 (*d)->type = KDBUS_MSG_BLOOM;
120 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
125 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
131 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
132 (*d)->type = KDBUS_MSG_FDS;
133 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
135 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
138 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
145 memset(bloom, 0, BLOOM_SIZE);
147 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
150 bloom_add_pair(bloom, "interface", m->interface);
152 bloom_add_pair(bloom, "member", m->member);
154 bloom_add_pair(bloom, "path", m->path);
155 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
158 r = sd_bus_message_rewind(m, true);
162 for (i = 0; i < 64; i++) {
165 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
168 r = sd_bus_message_peek_type(m, &type, NULL);
172 if (type != SD_BUS_TYPE_STRING &&
173 type != SD_BUS_TYPE_OBJECT_PATH &&
174 type != SD_BUS_TYPE_SIGNATURE)
177 r = sd_bus_message_read_basic(m, type, &t);
181 e = stpcpy(buf, "arg");
185 *(e++) = '0' + (i / 10);
186 *(e++) = '0' + (i % 10);
190 bloom_add_pair(bloom, buf, t);
192 strcpy(e, "-dot-prefix");
193 bloom_add_prefixes(bloom, buf, t, '.');
194 strcpy(e, "-slash-prefix");
195 bloom_add_prefixes(bloom, buf, t, '/');
201 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
202 struct bus_body_part *part;
203 struct kdbus_item *d;
217 if (m->destination) {
218 r = parse_unique_name(m->destination, &unique);
226 sz = offsetof(struct kdbus_msg, items);
228 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
229 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
231 /* Add in fixed header, fields header and payload */
232 sz += (1 + m->n_body_parts) *
233 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
235 /* Add space for bloom filter */
236 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
238 /* Add in well-known destination header */
240 dl = strlen(m->destination);
241 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
244 /* Add space for unix fds */
246 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
248 m->kdbus = memalign(8, sz);
254 m->free_kdbus = true;
255 memset(m->kdbus, 0, sz);
258 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
259 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
262 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
263 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
264 m->kdbus->cookie = m->header->serial;
266 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
271 append_destination(&d, m->destination, dl);
273 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
275 MESSAGE_FOREACH_PART(part, i, m) {
277 /* If this is padding then simply send a
278 * vector with a NULL data pointer which the
279 * kernel will just pass through. This is the
280 * most efficient way to encode zeroes */
282 append_payload_vec(&d, NULL, part->size);
286 if (part->memfd >= 0 && part->sealed && m->destination) {
287 /* Try to send a memfd, if the part is
288 * sealed and this is not a broadcast. Since we can only */
290 append_payload_memfd(&d, part->memfd, part->size);
294 /* Otherwise let's send a vector to the actual data,
295 * for that we need to map it first. */
296 r = bus_body_part_map(part);
300 append_payload_vec(&d, part->data, part->size);
303 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
306 p = append_bloom(&d, BLOOM_SIZE);
307 r = bus_message_setup_bloom(m, p);
313 append_fds(&d, m->fds, m->n_fds);
315 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
316 assert(m->kdbus->size <= sz);
325 int bus_kernel_take_fd(sd_bus *b) {
326 uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
327 ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
328 ALIGN8(sizeof(struct kdbus_vec))] = {};
330 struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
339 if (!b->kdbus_buffer) {
340 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
341 if (b->kdbus_buffer == MAP_FAILED) {
342 b->kdbus_buffer = NULL;
347 hello->size = sizeof(h);
348 hello->conn_flags = b->hello_flags;
350 hello->items[0].type = KDBUS_HELLO_POOL;
351 hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
352 hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
353 hello->items[0].vec.size = KDBUS_POOL_SIZE;
355 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
359 /* The higher 32bit of both flags fields are considered
360 * 'incompatible flags'. Refuse them all for now. */
361 if (hello->bus_flags > 0xFFFFFFFFULL ||
362 hello->conn_flags > 0xFFFFFFFFULL)
365 if (hello->bloom_size != BLOOM_SIZE)
368 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
372 b->bus_client = true;
373 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
375 r = bus_start_running(b);
382 int bus_kernel_connect(sd_bus *b) {
384 assert(b->input_fd < 0);
385 assert(b->output_fd < 0);
391 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
395 b->output_fd = b->input_fd;
397 return bus_kernel_take_fd(b);
400 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
405 assert(bus->state == BUS_RUNNING);
407 r = bus_message_setup_kmsg(bus, m);
411 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
413 return errno == EAGAIN ? 0 : -errno;
418 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
419 struct kdbus_item *d;
424 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
426 KDBUS_ITEM_FOREACH(d, k) {
428 if (d->type == KDBUS_MSG_FDS)
429 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
430 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
431 close_nointr_nofail(d->memfd.fd);
435 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
436 sd_bus_message *m = NULL;
437 struct kdbus_item *d;
439 _cleanup_free_ int *fds = NULL;
440 struct bus_header *h = NULL;
441 size_t total, n_bytes = 0, idx = 0;
442 const char *destination = NULL, *seclabel = NULL;
449 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
452 KDBUS_ITEM_FOREACH(d, k) {
455 l = d->size - offsetof(struct kdbus_item, data);
457 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
460 h = UINT64_TO_PTR(d->vec.address);
462 if (!bus_header_is_complete(h, d->vec.size))
466 n_bytes += d->vec.size;
468 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
473 n_bytes += d->memfd.size;
475 } else if (d->type == KDBUS_MSG_FDS) {
480 f = realloc(fds, sizeof(int) * (n_fds + j));
485 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
488 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
495 r = bus_header_message_size(h, &total);
499 if (n_bytes != total)
502 r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
506 KDBUS_ITEM_FOREACH(d, k) {
509 l = d->size - offsetof(struct kdbus_item, data);
511 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
514 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
516 if (idx + d->vec.size > begin_body) {
517 struct bus_body_part *part;
519 /* Contains body material */
521 part = message_append_part(m);
527 if (idx >= begin_body) {
528 part->data = UINT64_TO_PTR(d->vec.address);
529 part->size = d->vec.size;
531 part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
532 part->size = d->vec.size - (begin_body - idx);
535 part->is_zero = d->vec.address == 0;
540 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
541 struct bus_body_part *part;
543 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
548 part = message_append_part(m);
554 part->memfd = d->memfd.fd;
555 part->size = d->memfd.size;
558 idx += d->memfd.size;
560 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
561 m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
562 m->uid = d->creds.uid;
563 m->gid = d->creds.gid;
564 m->pid = d->creds.pid;
565 m->tid = d->creds.tid;
566 m->uid_valid = m->gid_valid = true;
567 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
568 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
569 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
570 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
572 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
573 m->tid_comm = d->str;
574 else if (d->type == KDBUS_MSG_SRC_EXE)
576 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
578 m->cmdline_length = l;
579 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
581 else if (d->type == KDBUS_MSG_SRC_AUDIT)
582 m->audit = &d->audit;
583 else if (d->type == KDBUS_MSG_SRC_CAPS) {
584 m->capability = d->data;
585 m->capability_size = l;
586 } else if (d->type == KDBUS_MSG_DST_NAME)
587 destination = d->str;
588 else if (d->type != KDBUS_MSG_FDS &&
589 d->type != KDBUS_MSG_SRC_SECLABEL)
590 log_debug("Got unknown field from kernel %llu", d->type);
593 r = bus_message_parse_fields(m);
597 if (k->src_id == KDBUS_SRC_ID_KERNEL)
598 m->sender = "org.freedesktop.DBus";
600 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
601 m->sender = m->sender_buffer;
604 if (!m->destination) {
606 m->destination = destination;
607 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
608 k->dst_id != KDBUS_DST_ID_BROADCAST) {
609 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
610 m->destination = m->destination_buffer;
614 /* We take possession of the kmsg struct now */
616 m->bus = sd_bus_ref(bus);
617 m->release_kdbus = true;
627 struct bus_body_part *part;
630 /* Make sure the memfds are not freed twice */
631 MESSAGE_FOREACH_PART(part, i, m)
632 if (part->memfd >= 0)
635 sd_bus_message_unref(m);
641 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
649 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr);
656 k = UINT64_TO_PTR(addr);
658 r = bus_kernel_make_message(bus, k, m);
660 close_kdbus_msg(bus, k);
662 return r < 0 ? r : 1;
665 int bus_kernel_create(const char *name, char **s) {
666 struct kdbus_cmd_bus_make *make;
667 struct kdbus_item *n, *cg;
675 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
680 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
681 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
682 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
685 cg->type = KDBUS_MAKE_CGROUP;
687 cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
689 n = KDBUS_ITEM_NEXT(cg);
690 n->type = KDBUS_MAKE_NAME;
691 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
692 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
694 make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
695 make->flags = KDBUS_MAKE_POLICY_OPEN;
697 make->bloom_size = BLOOM_SIZE;
698 assert_cc(BLOOM_SIZE % 8 == 0);
700 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
704 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
705 close_nointr_nofail(fd);
716 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
717 struct memfd_cache *c;
723 if (!bus || !bus->is_kernel)
726 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
728 if (bus->n_memfd_cache <= 0) {
731 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
733 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
742 c = &bus->memfd_cache[-- bus->n_memfd_cache];
745 assert(c->size == 0 || c->address);
747 *address = c->address;
751 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
756 static void close_and_munmap(int fd, void *address, size_t size) {
758 assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
760 close_nointr_nofail(fd);
763 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
764 struct memfd_cache *c;
767 assert(size == 0 || address);
769 if (!bus || !bus->is_kernel) {
770 close_and_munmap(fd, address, size);
774 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
776 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
777 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
779 close_and_munmap(fd, address, size);
783 c = &bus->memfd_cache[bus->n_memfd_cache++];
785 c->address = address;
787 /* If overly long, let's return a bit to the OS */
788 if (size > MEMFD_CACHE_ITEM_SIZE_MAX) {
789 uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX;
791 ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
793 c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
797 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
800 void bus_kernel_flush_memfd(sd_bus *b) {
805 for (i = 0; i < b->n_memfd_cache; i++) {
806 if (b->memfd_cache[i].size > 0)
807 assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
809 close_nointr_nofail(b->memfd_cache[i].fd);