chiark / gitweb /
bus: append unique and well known names to all messages unconditionally
[elogind.git] / src / libsystemd-bus / bus-kernel.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
24 #endif
25
26 #include <fcntl.h>
27 #include <malloc.h>
28 #include <sys/mman.h>
29
30 #include "util.h"
31
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-kernel.h"
35 #include "bus-bloom.h"
36 #include "bus-util.h"
37
38 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
39
40 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
41         int r;
42
43         assert(s);
44         assert(id);
45
46         if (!startswith(s, ":1."))
47                 return 0;
48
49         r = safe_atou64(s + 3, id);
50         if (r < 0)
51                 return r;
52
53         return 1;
54 }
55
56 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
57         assert(d);
58         assert(sz > 0);
59
60         *d = ALIGN8_PTR(*d);
61
62         /* Note that p can be NULL, which encodes a region full of
63          * zeroes, which is useful to optimize certain padding
64          * conditions */
65
66         (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
67         (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
68         (*d)->vec.address = PTR_TO_UINT64(p);
69         (*d)->vec.size = sz;
70
71         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
72 }
73
74 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
75         assert(d);
76         assert(memfd >= 0);
77         assert(sz > 0);
78
79         *d = ALIGN8_PTR(*d);
80         (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
81         (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
82         (*d)->memfd.fd = memfd;
83         (*d)->memfd.size = sz;
84
85         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
86 }
87
88 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
89         assert(d);
90         assert(s);
91
92         *d = ALIGN8_PTR(*d);
93
94         (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
95         (*d)->type = KDBUS_ITEM_DST_NAME;
96         memcpy((*d)->str, s, length + 1);
97
98         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
99 }
100
101 static void* append_bloom(struct kdbus_item **d, size_t length) {
102         void *r;
103
104         assert(d);
105
106         *d = ALIGN8_PTR(*d);
107
108         (*d)->size = offsetof(struct kdbus_item, data) + length;
109         (*d)->type = KDBUS_ITEM_BLOOM;
110         r = (*d)->data;
111
112         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
113
114         return r;
115 }
116
117 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
118         assert(d);
119         assert(fds);
120         assert(n_fds > 0);
121
122         *d = ALIGN8_PTR(*d);
123         (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
124         (*d)->type = KDBUS_ITEM_FDS;
125         memcpy((*d)->fds, fds, sizeof(int) * n_fds);
126
127         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
128 }
129
130 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
131         unsigned i;
132         int r;
133
134         assert(m);
135         assert(bloom);
136
137         memset(bloom, 0, BLOOM_SIZE);
138
139         bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
140
141         if (m->interface)
142                 bloom_add_pair(bloom, "interface", m->interface);
143         if (m->member)
144                 bloom_add_pair(bloom, "member", m->member);
145         if (m->path) {
146                 bloom_add_pair(bloom, "path", m->path);
147                 bloom_add_pair(bloom, "path-slash-prefix", m->path);
148                 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
149         }
150
151         r = sd_bus_message_rewind(m, true);
152         if (r < 0)
153                 return r;
154
155         for (i = 0; i < 64; i++) {
156                 char type;
157                 const char *t;
158                 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
159                 char *e;
160
161                 r = sd_bus_message_peek_type(m, &type, NULL);
162                 if (r < 0)
163                         return r;
164
165                 if (type != SD_BUS_TYPE_STRING &&
166                     type != SD_BUS_TYPE_OBJECT_PATH &&
167                     type != SD_BUS_TYPE_SIGNATURE)
168                         break;
169
170                 r = sd_bus_message_read_basic(m, type, &t);
171                 if (r < 0)
172                         return r;
173
174                 e = stpcpy(buf, "arg");
175                 if (i < 10)
176                         *(e++) = '0' + i;
177                 else {
178                         *(e++) = '0' + (i / 10);
179                         *(e++) = '0' + (i % 10);
180                 }
181
182                 *e = 0;
183                 bloom_add_pair(bloom, buf, t);
184
185                 strcpy(e, "-dot-prefix");
186                 bloom_add_prefixes(bloom, buf, t, '.');
187                 strcpy(e, "-slash-prefix");
188                 bloom_add_prefixes(bloom, buf, t, '/');
189         }
190
191         return 0;
192 }
193
194 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
195         struct bus_body_part *part;
196         struct kdbus_item *d;
197         bool well_known;
198         uint64_t unique;
199         size_t sz, dl;
200         unsigned i;
201         int r;
202
203         assert(b);
204         assert(m);
205         assert(m->sealed);
206
207         if (m->kdbus)
208                 return 0;
209
210         if (m->destination) {
211                 r = bus_kernel_parse_unique_name(m->destination, &unique);
212                 if (r < 0)
213                         return r;
214
215                 well_known = r == 0;
216         } else
217                 well_known = false;
218
219         sz = offsetof(struct kdbus_msg, items);
220
221         assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
222                   ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
223
224         /* Add in fixed header, fields header and payload */
225         sz += (1 + m->n_body_parts) *
226                 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
227
228         /* Add space for bloom filter */
229         sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
230
231         /* Add in well-known destination header */
232         if (well_known) {
233                 dl = strlen(m->destination);
234                 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
235         }
236
237         /* Add space for unix fds */
238         if (m->n_fds > 0)
239                 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
240
241         m->kdbus = memalign(8, sz);
242         if (!m->kdbus) {
243                 r = -ENOMEM;
244                 goto fail;
245         }
246
247         m->free_kdbus = true;
248         memset(m->kdbus, 0, sz);
249
250         m->kdbus->flags =
251                 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
252                 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
253         m->kdbus->dst_id =
254                 well_known ? 0 :
255                 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
256         m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
257         m->kdbus->cookie = m->header->serial;
258
259         m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
260
261         d = m->kdbus->items;
262
263         if (well_known)
264                 append_destination(&d, m->destination, dl);
265
266         append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
267
268         MESSAGE_FOREACH_PART(part, i, m) {
269                 if (part->is_zero) {
270                         /* If this is padding then simply send a
271                          * vector with a NULL data pointer which the
272                          * kernel will just pass through. This is the
273                          * most efficient way to encode zeroes */
274
275                         append_payload_vec(&d, NULL, part->size);
276                         continue;
277                 }
278
279                 if (part->memfd >= 0 && part->sealed && m->destination) {
280                         /* Try to send a memfd, if the part is
281                          * sealed and this is not a broadcast. Since we can only  */
282
283                         append_payload_memfd(&d, part->memfd, part->size);
284                         continue;
285                 }
286
287                 /* Otherwise let's send a vector to the actual data,
288                  * for that we need to map it first. */
289                 r = bus_body_part_map(part);
290                 if (r < 0)
291                         goto fail;
292
293                 append_payload_vec(&d, part->data, part->size);
294         }
295
296         if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
297                 void *p;
298
299                 p = append_bloom(&d, BLOOM_SIZE);
300                 r = bus_message_setup_bloom(m, p);
301                 if (r < 0)
302                         goto fail;
303         }
304
305         if (m->n_fds > 0)
306                 append_fds(&d, m->fds, m->n_fds);
307
308         m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
309         assert(m->kdbus->size <= sz);
310
311         return 0;
312
313 fail:
314         m->poisoned = true;
315         return r;
316 }
317
318 int bus_kernel_take_fd(sd_bus *b) {
319         struct kdbus_cmd_hello hello;
320         int r;
321
322         assert(b);
323
324         if (b->is_server)
325                 return -EINVAL;
326
327         b->use_memfd = 1;
328
329         zero(hello);
330         hello.size = sizeof(hello);
331         hello.conn_flags = b->hello_flags;
332         hello.attach_flags = b->attach_flags;
333         hello.pool_size = KDBUS_POOL_SIZE;
334
335         r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
336         if (r < 0)
337                 return -errno;
338
339         if (!b->kdbus_buffer) {
340                 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
341                 if (b->kdbus_buffer == MAP_FAILED) {
342                         b->kdbus_buffer = NULL;
343                         return -errno;
344                 }
345         }
346
347         /* The higher 32bit of both flags fields are considered
348          * 'incompatible flags'. Refuse them all for now. */
349         if (hello.bus_flags > 0xFFFFFFFFULL ||
350             hello.conn_flags > 0xFFFFFFFFULL)
351                 return -ENOTSUP;
352
353         if (hello.bloom_size != BLOOM_SIZE)
354                 return -ENOTSUP;
355
356         if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
357                 return -ENOMEM;
358
359         b->unique_id = hello.id;
360
361         b->is_kernel = true;
362         b->bus_client = true;
363         b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
364
365         /* the kernel told us the UUID of the underlying bus */
366         memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
367
368         return bus_start_running(b);
369 }
370
371 int bus_kernel_connect(sd_bus *b) {
372         assert(b);
373         assert(b->input_fd < 0);
374         assert(b->output_fd < 0);
375         assert(b->kernel);
376
377         if (b->is_server)
378                 return -EINVAL;
379
380         b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
381         if (b->input_fd < 0)
382                 return -errno;
383
384         b->output_fd = b->input_fd;
385
386         return bus_kernel_take_fd(b);
387 }
388
389 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
390         int r;
391
392         assert(bus);
393         assert(m);
394         assert(bus->state == BUS_RUNNING);
395
396         /* If we can't deliver, we want room for the error message */
397         r = bus_rqueue_make_room(bus);
398         if (r < 0)
399                 return r;
400
401         r = bus_message_setup_kmsg(bus, m);
402         if (r < 0)
403                 return r;
404
405         r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
406         if (r < 0) {
407                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
408                 sd_bus_message *reply;
409
410                 if (errno == EAGAIN || errno == EINTR)
411                         return 0;
412                 else if (errno == ENXIO || errno == ESRCH) {
413
414                         /* ENXIO: unique name not known
415                          * ESRCH: well-known name not known */
416
417                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
418                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
419                         else
420                                 return 0;
421
422                 } else if (errno == EADDRNOTAVAIL) {
423
424                         /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
425
426                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
427                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
428                         else
429                                 return 0;
430                 } else
431                         return -errno;
432
433                 r = bus_message_new_synthetic_error(
434                                 bus,
435                                 BUS_MESSAGE_SERIAL(m),
436                                 &error,
437                                 &reply);
438
439                 if (r < 0)
440                         return r;
441
442                 r = bus_seal_synthetic_message(bus, reply);
443                 if (r < 0)
444                         return r;
445
446                 bus->rqueue[bus->rqueue_size++] = reply;
447
448                 return 0;
449         }
450
451         return 1;
452 }
453
454 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
455         uint64_t off;
456         struct kdbus_item *d;
457
458         assert(bus);
459         assert(k);
460
461         off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
462         ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
463
464         KDBUS_PART_FOREACH(d, k, items) {
465
466                 if (d->type == KDBUS_ITEM_FDS)
467                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
468                 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
469                         close_nointr_nofail(d->memfd.fd);
470         }
471 }
472
473 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
474         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
475         int r;
476
477         assert(bus);
478
479         r = sd_bus_message_new_signal(
480                         bus,
481                         "/org/freedesktop/DBus",
482                         "org.freedesktop.DBus",
483                         "NameOwnerChanged",
484                         &m);
485         if (r < 0)
486                 return r;
487
488         r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
489         if (r < 0)
490                 return r;
491
492         m->sender = "org.freedesktop.DBus";
493
494         r = bus_seal_synthetic_message(bus, m);
495         if (r < 0)
496                 return r;
497
498         bus->rqueue[bus->rqueue_size++] = m;
499         m = NULL;
500
501         return 1;
502 }
503
504 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
505         char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
506
507         assert(bus);
508         assert(k);
509         assert(d);
510
511         if (d->name_change.flags != 0)
512                 return 0;
513
514         if (d->type == KDBUS_ITEM_NAME_ADD)
515                 old_owner[0] = 0;
516         else
517                 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
518
519         if (d->type == KDBUS_ITEM_NAME_REMOVE)
520                 new_owner[0] = 0;
521         else
522                 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
523
524         return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
525 }
526
527 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
528         char owner[UNIQUE_NAME_MAX];
529
530         assert(bus);
531         assert(k);
532         assert(d);
533
534         sprintf(owner, ":1.%llu", d->id_change.id);
535
536         return push_name_owner_changed(
537                         bus, owner,
538                         d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
539                         d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
540 }
541
542 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
543         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
544         int r;
545
546         assert(bus);
547         assert(k);
548         assert(d);
549
550         r = bus_message_new_synthetic_error(
551                         bus,
552                         k->cookie_reply,
553                         d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
554                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
555                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
556                         &m);
557         if (r < 0)
558                 return r;
559
560         m->sender = "org.freedesktop.DBus";
561
562         r = bus_seal_synthetic_message(bus, m);
563         if (r < 0)
564                 return r;
565
566         bus->rqueue[bus->rqueue_size++] = m;
567         m = NULL;
568
569         return 1;
570 }
571
572 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
573         struct kdbus_item *d, *found = NULL;
574
575         static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
576                 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
577                 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
578                 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
579
580                 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
581                 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
582
583                 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
584                 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
585         };
586
587         assert(bus);
588         assert(k);
589         assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
590
591         KDBUS_PART_FOREACH(d, k, items) {
592                 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
593                         if (found)
594                                 return -EBADMSG;
595                         found = d;
596                 } else
597                         log_debug("Got unknown field from kernel %llu", d->type);
598         }
599
600         if (!found) {
601                 log_debug("Didn't find a kernel message to translate.");
602                 return 0;
603         }
604
605         return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
606 }
607
608 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
609         sd_bus_message *m = NULL;
610         struct kdbus_item *d;
611         unsigned n_fds = 0;
612         _cleanup_free_ int *fds = NULL;
613         struct bus_header *h = NULL;
614         size_t total, n_bytes = 0, idx = 0;
615         const char *destination = NULL, *seclabel = NULL;
616         int r;
617
618         assert(bus);
619         assert(k);
620         assert(k->payload_type == KDBUS_PAYLOAD_DBUS1);
621
622         KDBUS_PART_FOREACH(d, k, items) {
623                 size_t l;
624
625                 l = d->size - offsetof(struct kdbus_item, data);
626
627                 switch (d->type) {
628
629                 case KDBUS_ITEM_PAYLOAD_OFF:
630                         if (!h) {
631                                 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
632
633                                 if (!bus_header_is_complete(h, d->vec.size))
634                                         return -EBADMSG;
635                         }
636
637                         n_bytes += d->vec.size;
638                         break;
639
640                 case KDBUS_ITEM_PAYLOAD_MEMFD:
641                         if (!h)
642                                 return -EBADMSG;
643
644                         n_bytes += d->memfd.size;
645                         break;
646
647                 case KDBUS_ITEM_FDS: {
648                         int *f;
649                         unsigned j;
650
651                         j = l / sizeof(int);
652                         f = realloc(fds, sizeof(int) * (n_fds + j));
653                         if (!f)
654                                 return -ENOMEM;
655
656                         fds = f;
657                         memcpy(fds + n_fds, d->fds, sizeof(int) * j);
658                         n_fds += j;
659                         break;
660                 }
661
662                 case KDBUS_ITEM_SECLABEL:
663                         seclabel = d->str;
664                         break;
665                 }
666         }
667
668         if (!h)
669                 return -EBADMSG;
670
671         r = bus_header_message_size(h, &total);
672         if (r < 0)
673                 return r;
674
675         if (n_bytes != total)
676                 return -EBADMSG;
677
678         r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
679         if (r < 0)
680                 return r;
681
682         KDBUS_PART_FOREACH(d, k, items) {
683                 size_t l;
684
685                 l = d->size - offsetof(struct kdbus_item, data);
686
687                 switch (d->type) {
688
689                 case KDBUS_ITEM_PAYLOAD_OFF: {
690                         size_t begin_body;
691
692                         begin_body = BUS_MESSAGE_BODY_BEGIN(m);
693
694                         if (idx + d->vec.size > begin_body) {
695                                 struct bus_body_part *part;
696
697                                 /* Contains body material */
698
699                                 part = message_append_part(m);
700                                 if (!part) {
701                                         r = -ENOMEM;
702                                         goto fail;
703                                 }
704
705                                 /* A -1 offset is NUL padding. */
706                                 part->is_zero = d->vec.offset == ~0ULL;
707
708                                 if (idx >= begin_body) {
709                                         if (!part->is_zero)
710                                                 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
711                                         part->size = d->vec.size;
712                                 } else {
713                                         if (!part->is_zero)
714                                                 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
715                                         part->size = d->vec.size - (begin_body - idx);
716                                 }
717
718                                 part->sealed = true;
719                         }
720
721                         idx += d->vec.size;
722                         break;
723                 }
724
725                 case KDBUS_ITEM_PAYLOAD_MEMFD: {
726                         struct bus_body_part *part;
727
728                         if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
729                                 r = -EBADMSG;
730                                 goto fail;
731                         }
732
733                         part = message_append_part(m);
734                         if (!part) {
735                                 r = -ENOMEM;
736                                 goto fail;
737                         }
738
739                         part->memfd = d->memfd.fd;
740                         part->size = d->memfd.size;
741                         part->sealed = true;
742
743                         idx += d->memfd.size;
744                         break;
745                 }
746
747                 case KDBUS_ITEM_CREDS:
748                         m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
749                         m->creds.uid = d->creds.uid;
750                         m->creds.gid = d->creds.gid;
751                         m->creds.pid = d->creds.pid;
752                         m->creds.tid = d->creds.tid;
753                         m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID) & bus->creds_mask;
754                         break;
755
756                 case KDBUS_ITEM_TIMESTAMP:
757                         m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
758                         m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
759                         break;
760
761                 case KDBUS_ITEM_PID_COMM:
762                         m->creds.comm = d->str;
763                         m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
764                         break;
765
766                 case KDBUS_ITEM_TID_COMM:
767                         m->creds.tid_comm = d->str;
768                         m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
769                         break;
770
771                 case KDBUS_ITEM_EXE:
772                         m->creds.exe = d->str;
773                         m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
774                         break;
775
776                 case KDBUS_ITEM_CMDLINE:
777                         m->creds.cmdline = d->str;
778                         m->creds.cmdline_size = l;
779                         m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
780                         break;
781
782                 case KDBUS_ITEM_CGROUP:
783                         m->creds.cgroup = d->str;
784                         m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask;
785                         break;
786
787                 case KDBUS_ITEM_AUDIT:
788                         m->creds.audit_session_id = d->audit.sessionid;
789                         m->creds.audit_login_uid = d->audit.loginuid;
790                         m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
791                         break;
792
793                 case KDBUS_ITEM_CAPS:
794                         m->creds.capability = d->data;
795                         m->creds.capability_size = l;
796                         m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask;
797                         break;
798
799                 case KDBUS_ITEM_DST_NAME:
800                         destination = d->str;
801                         break;
802
803                 case KDBUS_ITEM_NAMES:
804                         m->creds.well_known_names = d->str;
805                         m->creds.well_known_names_size = l;
806                         m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
807                         break;
808
809                 case KDBUS_ITEM_FDS:
810                 case KDBUS_ITEM_SECLABEL:
811                         break;
812
813                 default:
814                         log_debug("Got unknown field from kernel %llu", d->type);
815                 }
816         }
817
818         r = bus_message_parse_fields(m);
819         if (r < 0)
820                 goto fail;
821
822         if (k->src_id == KDBUS_SRC_ID_KERNEL)
823                 m->sender = "org.freedesktop.DBus";
824         else {
825                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
826                 m->sender = m->creds.unique_name = m->sender_buffer;
827                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
828         }
829
830         if (!m->destination) {
831                 if (destination)
832                         m->destination = destination;
833                 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
834                          k->dst_id != KDBUS_DST_ID_BROADCAST) {
835                         snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
836                         m->destination = m->destination_buffer;
837                 }
838         }
839
840         /* We take possession of the kmsg struct now */
841         m->kdbus = k;
842         m->release_kdbus = true;
843         m->free_fds = true;
844         fds = NULL;
845
846         bus->rqueue[bus->rqueue_size++] = m;
847
848         return 1;
849
850 fail:
851         if (m) {
852                 struct bus_body_part *part;
853                 unsigned i;
854
855                 /* Make sure the memfds are not freed twice */
856                 MESSAGE_FOREACH_PART(part, i, m)
857                         if (part->memfd >= 0)
858                                 part->memfd = -1;
859
860                 sd_bus_message_unref(m);
861         }
862
863         return r;
864 }
865
866 int bus_kernel_read_message(sd_bus *bus) {
867         struct kdbus_msg *k;
868         uint64_t off;
869         int r;
870
871         assert(bus);
872
873         r = bus_rqueue_make_room(bus);
874         if (r < 0)
875                 return r;
876
877         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
878         if (r < 0) {
879                 if (errno == EAGAIN)
880                         return 0;
881
882                 return -errno;
883         }
884         k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
885
886         if (k->payload_type == KDBUS_PAYLOAD_DBUS1)
887                 r = bus_kernel_make_message(bus, k);
888         else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
889                 r = bus_kernel_translate_message(bus, k);
890         else
891                 r = 0;
892
893         if (r <= 0)
894                 close_kdbus_msg(bus, k);
895
896         return r < 0 ? r : 1;
897 }
898
899 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
900         struct memfd_cache *c;
901         int fd;
902
903         assert(address);
904         assert(size);
905
906         if (!bus || !bus->is_kernel)
907                 return -ENOTSUP;
908
909         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
910
911         if (bus->n_memfd_cache <= 0) {
912                 int r;
913
914                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
915
916                 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
917                 if (r < 0)
918                         return -errno;
919
920                 *address = NULL;
921                 *size = 0;
922                 return fd;
923         }
924
925         c = &bus->memfd_cache[--bus->n_memfd_cache];
926
927         assert(c->fd >= 0);
928         assert(c->size == 0 || c->address);
929
930         *address = c->address;
931         *size = c->size;
932         fd = c->fd;
933
934         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
935
936         return fd;
937 }
938
939 static void close_and_munmap(int fd, void *address, size_t size) {
940         if (size > 0)
941                 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
942
943         close_nointr_nofail(fd);
944 }
945
946 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
947         struct memfd_cache *c;
948         uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
949
950         assert(fd >= 0);
951         assert(size == 0 || address);
952
953         if (!bus || !bus->is_kernel) {
954                 close_and_munmap(fd, address, size);
955                 return;
956         }
957
958         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
959
960         if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
961                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
962
963                 close_and_munmap(fd, address, size);
964                 return;
965         }
966
967         c = &bus->memfd_cache[bus->n_memfd_cache++];
968         c->fd = fd;
969         c->address = address;
970
971         /* If overly long, let's return a bit to the OS */
972         if (size > max_sz) {
973                 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
974                 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
975                 c->size = max_sz;
976         } else
977                 c->size = size;
978
979         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
980 }
981
982 void bus_kernel_flush_memfd(sd_bus *b) {
983         unsigned i;
984
985         assert(b);
986
987         for (i = 0; i < b->n_memfd_cache; i++)
988                 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
989 }
990
991 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
992         uint64_t f = 0;
993
994         assert(kdbus_flags);
995
996         if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
997                 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
998
999         if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1000                 f |= KDBUS_NAME_REPLACE_EXISTING;
1001
1002         if (!(flags & SD_BUS_NAME_DO_NOT_QUEUE))
1003                 f |= KDBUS_NAME_QUEUE;
1004
1005         *kdbus_flags = f;
1006         return 0;
1007 }
1008
1009 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1010         uint64_t m = 0;
1011
1012         assert(kdbus_mask);
1013
1014         if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1015                 m |= KDBUS_ATTACH_CREDS;
1016
1017         if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1018                 m |= KDBUS_ATTACH_COMM;
1019
1020         if (mask & SD_BUS_CREDS_EXE)
1021                 m |= KDBUS_ATTACH_EXE;
1022
1023         if (mask & SD_BUS_CREDS_CMDLINE)
1024                 m |= KDBUS_ATTACH_CMDLINE;
1025
1026         if (mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID))
1027                 m |= KDBUS_ATTACH_CGROUP;
1028
1029         if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1030                 m |= KDBUS_ATTACH_CAPS;
1031
1032         if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1033                 m |= KDBUS_ATTACH_SECLABEL;
1034
1035         if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1036                 m |= KDBUS_ATTACH_AUDIT;
1037
1038         if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1039                 m |= KDBUS_ATTACH_NAMES;
1040
1041         *kdbus_mask = m;
1042         return 0;
1043 }
1044
1045 int bus_kernel_create(const char *name, char **s) {
1046         struct kdbus_cmd_bus_make *make;
1047         struct kdbus_item *n;
1048         int fd;
1049
1050         assert(name);
1051         assert(s);
1052
1053         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1054         if (fd < 0)
1055                 return -errno;
1056
1057         make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) +
1058                               offsetof(struct kdbus_item, str) +
1059                               DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1060
1061         n = make->items;
1062         sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1063         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1064         n->type = KDBUS_MAKE_NAME;
1065
1066         make->size = ALIGN8(offsetof(struct kdbus_cmd_bus_make, items) + n->size);
1067         make->flags = KDBUS_MAKE_POLICY_OPEN;
1068         make->bus_flags = 0;
1069         make->bloom_size = BLOOM_SIZE;
1070         assert_cc(BLOOM_SIZE % 8 == 0);
1071
1072         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1073                 close_nointr_nofail(fd);
1074                 return -errno;
1075         }
1076
1077         if (s) {
1078                 char *p;
1079
1080                 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1081                 if (!p) {
1082                         close_nointr_nofail(fd);
1083                         return -ENOMEM;
1084                 }
1085
1086                 *s = p;
1087         }
1088
1089         return fd;
1090 }