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) {
648 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k);
656 r = bus_kernel_make_message(bus, k, m);
658 close_kdbus_msg(bus, k);
660 return r < 0 ? r : 1;
663 int bus_kernel_create(const char *name, char **s) {
664 struct kdbus_cmd_bus_make *make;
665 struct kdbus_item *n, *cg;
673 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
678 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
679 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
680 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
683 cg->type = KDBUS_MAKE_CGROUP;
685 cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
687 n = KDBUS_ITEM_NEXT(cg);
688 n->type = KDBUS_MAKE_NAME;
689 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
690 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
692 make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
693 make->flags = KDBUS_MAKE_POLICY_OPEN;
695 make->bloom_size = BLOOM_SIZE;
696 assert_cc(BLOOM_SIZE % 8 == 0);
698 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
702 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
703 close_nointr_nofail(fd);
714 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
715 struct memfd_cache *c;
721 if (!bus || !bus->is_kernel)
724 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
726 if (bus->n_memfd_cache <= 0) {
729 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
731 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
740 c = &bus->memfd_cache[-- bus->n_memfd_cache];
743 assert(c->size == 0 || c->address);
745 *address = c->address;
749 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
754 static void close_and_munmap(int fd, void *address, size_t size) {
756 assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
758 close_nointr_nofail(fd);
761 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
762 struct memfd_cache *c;
765 assert(size == 0 || address);
767 if (!bus || !bus->is_kernel) {
768 close_and_munmap(fd, address, size);
772 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0);
774 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
775 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
777 close_and_munmap(fd, address, size);
781 c = &bus->memfd_cache[bus->n_memfd_cache++];
783 c->address = address;
785 /* If overly long, let's return a bit to the OS */
786 if (size > MEMFD_CACHE_ITEM_SIZE_MAX) {
787 uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX;
789 ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
791 c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
795 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0);
798 void bus_kernel_flush_memfd(sd_bus *b) {
803 for (i = 0; i < b->n_memfd_cache; i++) {
804 if (b->memfd_cache[i].size > 0)
805 assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
807 close_nointr_nofail(b->memfd_cache[i].fd);