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 #define KDBUS_POOL_SIZE (4*1024*1024)
50 static int parse_unique_name(const char *s, uint64_t *id) {
56 if (!startswith(s, ":1."))
59 r = safe_atou64(s + 3, id);
66 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
72 /* Note that p can be NULL, which encodes a region full of
73 * zeroes, which is useful to optimize certain padding
76 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
77 (*d)->type = KDBUS_MSG_PAYLOAD_VEC;
78 (*d)->vec.address = PTR_TO_UINT64(p);
81 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
84 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
90 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
91 (*d)->type = KDBUS_MSG_PAYLOAD_MEMFD;
92 (*d)->memfd.fd = memfd;
93 (*d)->memfd.size = sz;
95 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
98 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
104 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
105 (*d)->type = KDBUS_MSG_DST_NAME;
106 memcpy((*d)->str, s, length + 1);
108 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
111 static void* append_bloom(struct kdbus_item **d, size_t length) {
118 (*d)->size = offsetof(struct kdbus_item, data) + length;
119 (*d)->type = KDBUS_MSG_BLOOM;
122 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
127 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
133 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
134 (*d)->type = KDBUS_MSG_FDS;
135 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
137 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
140 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
147 memset(bloom, 0, BLOOM_SIZE);
149 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
152 bloom_add_pair(bloom, "interface", m->interface);
154 bloom_add_pair(bloom, "member", m->member);
156 bloom_add_pair(bloom, "path", m->path);
157 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
160 r = sd_bus_message_rewind(m, true);
164 for (i = 0; i < 64; i++) {
167 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
170 r = sd_bus_message_peek_type(m, &type, NULL);
174 if (type != SD_BUS_TYPE_STRING &&
175 type != SD_BUS_TYPE_OBJECT_PATH &&
176 type != SD_BUS_TYPE_SIGNATURE)
179 r = sd_bus_message_read_basic(m, type, &t);
183 e = stpcpy(buf, "arg");
187 *(e++) = '0' + (i / 10);
188 *(e++) = '0' + (i % 10);
192 bloom_add_pair(bloom, buf, t);
194 strcpy(e, "-dot-prefix");
195 bloom_add_prefixes(bloom, buf, t, '.');
196 strcpy(e, "-slash-prefix");
197 bloom_add_prefixes(bloom, buf, t, '/');
203 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
204 struct bus_body_part *part;
205 struct kdbus_item *d;
219 if (m->destination) {
220 r = parse_unique_name(m->destination, &unique);
228 sz = offsetof(struct kdbus_msg, items);
230 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
231 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
233 /* Add in fixed header, fields header and payload */
234 sz += (1 + m->n_body_parts) *
235 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
237 /* Add space for bloom filter */
238 sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
240 /* Add in well-known destination header */
242 dl = strlen(m->destination);
243 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
246 /* Add space for unix fds */
248 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
250 m->kdbus = memalign(8, sz);
256 m->free_kdbus = true;
257 memset(m->kdbus, 0, sz);
260 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
261 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
264 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
265 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
266 m->kdbus->cookie = m->header->serial;
268 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
273 append_destination(&d, m->destination, dl);
275 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
277 MESSAGE_FOREACH_PART(part, i, m) {
279 /* If this is padding then simply send a
280 * vector with a NULL data pointer which the
281 * kernel will just pass through. This is the
282 * most efficient way to encode zeroes */
284 append_payload_vec(&d, NULL, part->size);
288 if (part->memfd >= 0 && part->sealed && m->destination) {
289 /* Try to send a memfd, if the part is
290 * sealed and this is not a broadcast. Since we can only */
292 append_payload_memfd(&d, part->memfd, part->size);
296 /* Otherwise let's send a vector to the actual data,
297 * for that we need to map it first. */
298 r = bus_body_part_map(part);
302 append_payload_vec(&d, part->data, part->size);
305 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
308 p = append_bloom(&d, BLOOM_SIZE);
309 r = bus_message_setup_bloom(m, p);
315 append_fds(&d, m->fds, m->n_fds);
317 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
318 assert(m->kdbus->size <= sz);
327 int bus_kernel_take_fd(sd_bus *b) {
328 uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
329 ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
330 ALIGN8(sizeof(struct kdbus_vec))] = {};
332 struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
341 if (!b->kdbus_buffer) {
342 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
343 if (b->kdbus_buffer == MAP_FAILED) {
344 b->kdbus_buffer = NULL;
349 hello->size = sizeof(h);
351 KDBUS_HELLO_ACCEPT_FD|
352 KDBUS_HELLO_ATTACH_COMM|
353 KDBUS_HELLO_ATTACH_EXE|
354 KDBUS_HELLO_ATTACH_CMDLINE|
355 KDBUS_HELLO_ATTACH_CGROUP|
356 KDBUS_HELLO_ATTACH_CAPS|
357 KDBUS_HELLO_ATTACH_SECLABEL|
358 KDBUS_HELLO_ATTACH_AUDIT;
360 hello->items[0].type = KDBUS_HELLO_POOL;
361 hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
362 hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
363 hello->items[0].vec.size = KDBUS_POOL_SIZE;
365 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
369 /* The higher 32bit of both flags fields are considered
370 * 'incompatible flags'. Refuse them all for now. */
371 if (hello->bus_flags > 0xFFFFFFFFULL ||
372 hello->conn_flags > 0xFFFFFFFFULL)
375 if (hello->bloom_size != BLOOM_SIZE)
378 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
382 b->bus_client = true;
385 r = bus_start_running(b);
392 int bus_kernel_connect(sd_bus *b) {
394 assert(b->input_fd < 0);
395 assert(b->output_fd < 0);
401 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
405 b->output_fd = b->input_fd;
407 return bus_kernel_take_fd(b);
410 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
415 assert(bus->state == BUS_RUNNING);
417 r = bus_message_setup_kmsg(bus, m);
421 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
423 return errno == EAGAIN ? 0 : -errno;
428 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
429 struct kdbus_item *d;
434 ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
436 KDBUS_ITEM_FOREACH(d, k) {
438 if (d->type == KDBUS_MSG_FDS)
439 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
440 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
441 close_nointr_nofail(d->memfd.fd);
445 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
446 sd_bus_message *m = NULL;
447 struct kdbus_item *d;
449 _cleanup_free_ int *fds = NULL;
450 struct bus_header *h = NULL;
451 size_t total, n_bytes = 0, idx = 0;
452 const char *destination = NULL, *seclabel = NULL;
459 if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
462 KDBUS_ITEM_FOREACH(d, k) {
465 l = d->size - offsetof(struct kdbus_item, data);
467 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
470 h = UINT64_TO_PTR(d->vec.address);
472 if (!bus_header_is_complete(h, d->vec.size))
476 n_bytes += d->vec.size;
478 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
483 n_bytes += d->memfd.size;
485 } else if (d->type == KDBUS_MSG_FDS) {
490 f = realloc(fds, sizeof(int) * (n_fds + j));
495 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
498 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
505 r = bus_header_message_size(h, &total);
509 if (n_bytes != total)
512 r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
516 KDBUS_ITEM_FOREACH(d, k) {
519 l = d->size - offsetof(struct kdbus_item, data);
521 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
524 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
526 if (idx + d->vec.size > begin_body) {
527 struct bus_body_part *part;
529 /* Contains body material */
531 part = message_append_part(m);
537 if (idx >= begin_body) {
538 part->data = UINT64_TO_PTR(d->vec.address);
539 part->size = d->vec.size;
541 part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
542 part->size = d->vec.size - (begin_body - idx);
545 part->is_zero = d->vec.address == 0;
550 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
551 struct bus_body_part *part;
553 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
558 part = message_append_part(m);
564 part->memfd = d->memfd.fd;
565 part->size = d->memfd.size;
568 idx += d->memfd.size;
570 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
571 m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
572 m->uid = d->creds.uid;
573 m->gid = d->creds.gid;
574 m->pid = d->creds.pid;
575 m->tid = d->creds.tid;
576 m->uid_valid = m->gid_valid = true;
577 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
578 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
579 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
580 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
582 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
583 m->tid_comm = d->str;
584 else if (d->type == KDBUS_MSG_SRC_EXE)
586 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
588 m->cmdline_length = l;
589 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
591 else if (d->type == KDBUS_MSG_SRC_AUDIT)
592 m->audit = &d->audit;
593 else if (d->type == KDBUS_MSG_SRC_CAPS) {
594 m->capability = d->data;
595 m->capability_size = l;
596 } else if (d->type == KDBUS_MSG_DST_NAME)
597 destination = d->str;
598 else if (d->type != KDBUS_MSG_FDS &&
599 d->type != KDBUS_MSG_SRC_SECLABEL)
600 log_debug("Got unknown field from kernel %llu", d->type);
603 r = bus_message_parse_fields(m);
607 if (k->src_id == KDBUS_SRC_ID_KERNEL)
608 m->sender = "org.freedesktop.DBus";
610 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
611 m->sender = m->sender_buffer;
614 if (!m->destination) {
616 m->destination = destination;
617 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
618 k->dst_id != KDBUS_DST_ID_BROADCAST) {
619 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
620 m->destination = m->destination_buffer;
624 /* We take possession of the kmsg struct now */
626 m->bus = sd_bus_ref(bus);
627 m->release_kdbus = true;
637 struct bus_body_part *part;
640 /* Make sure the memfds are not freed twice */
641 MESSAGE_FOREACH_PART(part, i, m)
642 if (part->memfd >= 0)
645 sd_bus_message_unref(m);
651 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
658 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k);
666 r = bus_kernel_make_message(bus, k, m);
668 close_kdbus_msg(bus, k);
670 return r < 0 ? r : 1;
673 int bus_kernel_create(const char *name, char **s) {
674 struct kdbus_cmd_bus_make *make;
675 struct kdbus_item *n, *cg;
683 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
688 make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
689 KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
690 KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
693 cg->type = KDBUS_MAKE_CGROUP;
695 cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
697 n = KDBUS_ITEM_NEXT(cg);
698 n->type = KDBUS_MAKE_NAME;
699 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
700 n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
702 make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
703 make->flags = KDBUS_MAKE_POLICY_OPEN;
705 make->bloom_size = BLOOM_SIZE;
706 assert_cc(BLOOM_SIZE % 8 == 0);
708 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
712 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
713 close_nointr_nofail(fd);
724 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
725 struct memfd_cache *c;
730 if (!bus || !bus->is_kernel)
733 if (bus->n_memfd_cache <= 0) {
736 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
745 c = &bus->memfd_cache[-- bus->n_memfd_cache];
748 assert(c->size == 0 || c->address);
750 *address = c->address;
756 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
757 struct memfd_cache *c;
760 assert(size == 0 || address);
762 if (!bus || !bus->is_kernel ||
763 bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
766 assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
768 close_nointr_nofail(fd);
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;
787 void bus_kernel_flush_memfd(sd_bus *b) {
792 for (i = 0; i < b->n_memfd_cache; i++) {
793 if (b->memfd_cache[i].size > 0)
794 assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
796 close_nointr_nofail(b->memfd_cache[i].fd);