chiark / gitweb /
1b586d81d05f7a2ad5c9f5852bdba75f03fe169e
[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->is_kernel = true;
360         b->bus_client = true;
361         b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
362
363         /* the kernel told us the UUID of the underlying bus */
364         memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
365
366         r = bus_start_running(b);
367         if (r < 0)
368                 return r;
369
370         return 1;
371 }
372
373 int bus_kernel_connect(sd_bus *b) {
374         assert(b);
375         assert(b->input_fd < 0);
376         assert(b->output_fd < 0);
377         assert(b->kernel);
378
379         if (b->is_server)
380                 return -EINVAL;
381
382         b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
383         if (b->input_fd < 0)
384                 return -errno;
385
386         b->output_fd = b->input_fd;
387
388         return bus_kernel_take_fd(b);
389 }
390
391 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
392         int r;
393
394         assert(bus);
395         assert(m);
396         assert(bus->state == BUS_RUNNING);
397
398         r = bus_message_setup_kmsg(bus, m);
399         if (r < 0)
400                 return r;
401
402         r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
403         if (r < 0)
404                 return errno == EAGAIN ? 0 : -errno;
405
406         return 1;
407 }
408
409 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
410         uint64_t off;
411         struct kdbus_item *d;
412
413         assert(bus);
414         assert(k);
415
416         off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
417         ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
418
419         KDBUS_PART_FOREACH(d, k, items) {
420
421                 if (d->type == KDBUS_ITEM_FDS)
422                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
423                 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
424                         close_nointr_nofail(d->memfd.fd);
425         }
426 }
427
428 static int return_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner, sd_bus_message **ret) {
429         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
430         int r;
431
432         assert(bus);
433         assert(ret);
434
435         r = sd_bus_message_new_signal(
436                         bus,
437                         "/org/freedesktop/DBus",
438                         "org.freedesktop.DBus",
439                         "NameOwnerChanged",
440                         &m);
441         if (r < 0)
442                 return r;
443
444         r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
445         if (r < 0)
446                 return r;
447
448         m->sender = "org.freedesktop.DBus";
449
450         r = bus_seal_message(bus, m);
451         if (r < 0)
452                 return r;
453
454         *ret = m;
455         m = NULL;
456
457         return 1;
458 }
459
460 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d, sd_bus_message **ret) {
461         char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
462
463         assert(bus);
464         assert(k);
465         assert(d);
466         assert(ret);
467
468         if (d->name_change.flags != 0)
469                 return 0;
470
471         if (d->type == KDBUS_ITEM_NAME_ADD)
472                 old_owner[0] = 0;
473         else
474                 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id);
475
476         if (d->type == KDBUS_ITEM_NAME_REMOVE)
477                 new_owner[0] = 0;
478         else
479                 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id);
480
481         return return_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ret);
482 }
483
484 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d, sd_bus_message **ret) {
485         char owner[UNIQUE_NAME_MAX];
486
487         assert(bus);
488         assert(k);
489         assert(d);
490         assert(ret);
491
492         sprintf(owner, ":1.%llu", d->id_change.id);
493
494         return return_name_owner_changed(
495                         bus, owner,
496                         d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
497                         d->type == KDBUS_ITEM_ID_ADD ? owner : NULL,
498                         ret);
499 }
500
501 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d, sd_bus_message **ret) {
502         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
503         int r;
504
505         assert(bus);
506         assert(k);
507         assert(d);
508         assert(ret);
509
510         r = bus_message_new_synthetic_error(
511                         bus,
512                         k->cookie_reply,
513                         d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
514                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
515                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
516                         &m);
517         if (r < 0)
518                 return r;
519
520         m->sender = "org.freedesktop.DBus";
521
522         r = bus_seal_message(bus, m);
523         if (r < 0)
524                 return r;
525
526         *ret = m;
527         m = NULL;
528
529         return 1;
530 }
531
532 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
533         struct kdbus_item *d, *found = NULL;
534
535         static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d, sd_bus_message **ret) = {
536                 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
537                 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
538                 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
539
540                 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
541                 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
542
543                 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
544                 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
545         };
546
547         assert(bus);
548         assert(k);
549         assert(ret);
550         assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
551
552         KDBUS_PART_FOREACH(d, k, items) {
553                 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
554                         if (found)
555                                 return -EBADMSG;
556                         found = d;
557                 } else
558                         log_debug("Got unknown field from kernel %llu", d->type);
559         }
560
561         if (!found) {
562                 log_debug("Didn't find a kernel message to translate.");
563                 return 0;
564         }
565
566         return translate[found->type](bus, k, d, ret);
567 }
568
569 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
570         sd_bus_message *m = NULL;
571         struct kdbus_item *d;
572         unsigned n_fds = 0;
573         _cleanup_free_ int *fds = NULL;
574         struct bus_header *h = NULL;
575         size_t total, n_bytes = 0, idx = 0;
576         const char *destination = NULL, *seclabel = NULL;
577         int r;
578
579         assert(bus);
580         assert(k);
581         assert(ret);
582         assert(k->payload_type == KDBUS_PAYLOAD_DBUS1);
583
584         KDBUS_PART_FOREACH(d, k, items) {
585                 size_t l;
586
587                 l = d->size - offsetof(struct kdbus_item, data);
588
589                 switch (d->type) {
590
591                 case KDBUS_ITEM_PAYLOAD_OFF:
592                         if (!h) {
593                                 h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
594
595                                 if (!bus_header_is_complete(h, d->vec.size))
596                                         return -EBADMSG;
597                         }
598
599                         n_bytes += d->vec.size;
600                         break;
601
602                 case KDBUS_ITEM_PAYLOAD_MEMFD:
603                         if (!h)
604                                 return -EBADMSG;
605
606                         n_bytes += d->memfd.size;
607                         break;
608
609                 case KDBUS_ITEM_FDS: {
610                         int *f;
611                         unsigned j;
612
613                         j = l / sizeof(int);
614                         f = realloc(fds, sizeof(int) * (n_fds + j));
615                         if (!f)
616                                 return -ENOMEM;
617
618                         fds = f;
619                         memcpy(fds + n_fds, d->fds, sizeof(int) * j);
620                         n_fds += j;
621                         break;
622                 }
623
624                 case KDBUS_ITEM_SECLABEL:
625                         seclabel = d->str;
626                         break;
627                 }
628         }
629
630         if (!h)
631                 return -EBADMSG;
632
633         r = bus_header_message_size(h, &total);
634         if (r < 0)
635                 return r;
636
637         if (n_bytes != total)
638                 return -EBADMSG;
639
640         r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
641         if (r < 0)
642                 return r;
643
644         KDBUS_PART_FOREACH(d, k, items) {
645                 size_t l;
646
647                 l = d->size - offsetof(struct kdbus_item, data);
648
649                 switch (d->type) {
650
651                 case KDBUS_ITEM_PAYLOAD_OFF: {
652                         size_t begin_body;
653
654                         begin_body = BUS_MESSAGE_BODY_BEGIN(m);
655
656                         if (idx + d->vec.size > begin_body) {
657                                 struct bus_body_part *part;
658
659                                 /* Contains body material */
660
661                                 part = message_append_part(m);
662                                 if (!part) {
663                                         r = -ENOMEM;
664                                         goto fail;
665                                 }
666
667                                 /* A -1 offset is NUL padding. */
668                                 part->is_zero = d->vec.offset == ~0ULL;
669
670                                 if (idx >= begin_body) {
671                                         if (!part->is_zero)
672                                                 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
673                                         part->size = d->vec.size;
674                                 } else {
675                                         if (!part->is_zero)
676                                                 part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
677                                         part->size = d->vec.size - (begin_body - idx);
678                                 }
679
680                                 part->sealed = true;
681                         }
682
683                         idx += d->vec.size;
684                         break;
685                 }
686
687                 case KDBUS_ITEM_PAYLOAD_MEMFD: {
688                         struct bus_body_part *part;
689
690                         if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
691                                 r = -EBADMSG;
692                                 goto fail;
693                         }
694
695                         part = message_append_part(m);
696                         if (!part) {
697                                 r = -ENOMEM;
698                                 goto fail;
699                         }
700
701                         part->memfd = d->memfd.fd;
702                         part->size = d->memfd.size;
703                         part->sealed = true;
704
705                         idx += d->memfd.size;
706                         break;
707                 }
708
709                 case KDBUS_ITEM_CREDS:
710                         m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
711                         m->creds.uid = d->creds.uid;
712                         m->creds.gid = d->creds.gid;
713                         m->creds.pid = d->creds.pid;
714                         m->creds.tid = d->creds.tid;
715                         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;
716                         break;
717
718                 case KDBUS_ITEM_TIMESTAMP:
719                         m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
720                         m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
721                         break;
722
723                 case KDBUS_ITEM_PID_COMM:
724                         m->creds.comm = d->str;
725                         m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
726                         break;
727
728                 case KDBUS_ITEM_TID_COMM:
729                         m->creds.tid_comm = d->str;
730                         m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
731                         break;
732
733                 case KDBUS_ITEM_EXE:
734                         m->creds.exe = d->str;
735                         m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
736                         break;
737
738                 case KDBUS_ITEM_CMDLINE:
739                         m->creds.cmdline = d->str;
740                         m->creds.cmdline_length = l;
741                         m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
742                         break;
743
744                 case KDBUS_ITEM_CGROUP:
745                         m->creds.cgroup = d->str;
746                         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;
747                         break;
748
749                 case KDBUS_ITEM_AUDIT:
750                         m->creds.audit_session_id = d->audit.sessionid;
751                         m->creds.audit_login_uid = d->audit.loginuid;
752                         m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
753                         break;
754
755                 case KDBUS_ITEM_CAPS:
756                         m->creds.capability = d->data;
757                         m->creds.capability_size = l;
758                         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;
759                         break;
760
761                 case KDBUS_ITEM_DST_NAME:
762                         destination = d->str;
763                         break;
764
765                 case KDBUS_ITEM_FDS:
766                 case KDBUS_ITEM_SECLABEL:
767                 case KDBUS_ITEM_NAMES:
768                         break;
769
770                 default:
771                         log_debug("Got unknown field from kernel %llu", d->type);
772                 }
773         }
774
775         r = bus_message_parse_fields(m);
776         if (r < 0)
777                 goto fail;
778
779         if (k->src_id == KDBUS_SRC_ID_KERNEL)
780                 m->sender = "org.freedesktop.DBus";
781         else {
782                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
783                 m->sender = m->sender_buffer;
784         }
785
786         if (!m->destination) {
787                 if (destination)
788                         m->destination = destination;
789                 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
790                          k->dst_id != KDBUS_DST_ID_BROADCAST) {
791                         snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
792                         m->destination = m->destination_buffer;
793                 }
794         }
795
796         /* We take possession of the kmsg struct now */
797         m->kdbus = k;
798         m->release_kdbus = true;
799         m->free_fds = true;
800
801         fds = NULL;
802
803         *ret = m;
804         return 1;
805
806 fail:
807         if (m) {
808                 struct bus_body_part *part;
809                 unsigned i;
810
811                 /* Make sure the memfds are not freed twice */
812                 MESSAGE_FOREACH_PART(part, i, m)
813                         if (part->memfd >= 0)
814                                 part->memfd = -1;
815
816                 sd_bus_message_unref(m);
817         }
818
819         return r;
820 }
821
822 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
823         uint64_t off;
824         struct kdbus_msg *k;
825         int r;
826
827         assert(bus);
828         assert(m);
829
830         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
831         if (r < 0) {
832                 if (errno == EAGAIN)
833                         return 0;
834
835                 return -errno;
836         }
837         k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
838
839         if (k->payload_type == KDBUS_PAYLOAD_DBUS1)
840                 r = bus_kernel_make_message(bus, k, m);
841         else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
842                 r = bus_kernel_translate_message(bus, k, m);
843         else
844                 r = 0;
845
846         if (r <= 0)
847                 close_kdbus_msg(bus, k);
848
849         return r < 0 ? r : 1;
850 }
851
852 int bus_kernel_create(const char *name, char **s) {
853         struct kdbus_cmd_bus_make *make;
854         struct kdbus_item *n;
855         size_t l;
856         int fd;
857         char *p;
858
859         assert(name);
860         assert(s);
861
862         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
863         if (fd < 0)
864                 return -errno;
865
866         l = strlen(name);
867         make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
868                        KDBUS_PART_HEADER_SIZE + sizeof(uint64_t) +
869                        KDBUS_PART_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
870
871         n = make->items;
872         n->type = KDBUS_MAKE_NAME;
873         sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
874         n->size = KDBUS_PART_HEADER_SIZE + strlen(n->str) + 1;
875
876         make->size = offsetof(struct kdbus_cmd_bus_make, items) + n->size;
877         make->flags = KDBUS_MAKE_POLICY_OPEN;
878         make->bus_flags = 0;
879         make->bloom_size = BLOOM_SIZE;
880         assert_cc(BLOOM_SIZE % 8 == 0);
881
882         p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
883         if (!p)
884                 return -ENOMEM;
885
886         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
887                 close_nointr_nofail(fd);
888                 free(p);
889                 return -errno;
890         }
891
892         if (s)
893                 *s = p;
894
895         return fd;
896 }
897
898 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
899         struct memfd_cache *c;
900         int fd;
901
902         assert(address);
903         assert(size);
904
905         if (!bus || !bus->is_kernel)
906                 return -ENOTSUP;
907
908         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
909
910         if (bus->n_memfd_cache <= 0) {
911                 int r;
912
913                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
914
915                 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
916                 if (r < 0)
917                         return -errno;
918
919                 *address = NULL;
920                 *size = 0;
921                 return fd;
922         }
923
924         c = &bus->memfd_cache[--bus->n_memfd_cache];
925
926         assert(c->fd >= 0);
927         assert(c->size == 0 || c->address);
928
929         *address = c->address;
930         *size = c->size;
931         fd = c->fd;
932
933         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
934
935         return fd;
936 }
937
938 static void close_and_munmap(int fd, void *address, size_t size) {
939         if (size > 0)
940                 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
941
942         close_nointr_nofail(fd);
943 }
944
945 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
946         struct memfd_cache *c;
947         uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
948
949         assert(fd >= 0);
950         assert(size == 0 || address);
951
952         if (!bus || !bus->is_kernel) {
953                 close_and_munmap(fd, address, size);
954                 return;
955         }
956
957         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
958
959         if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
960                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
961
962                 close_and_munmap(fd, address, size);
963                 return;
964         }
965
966         c = &bus->memfd_cache[bus->n_memfd_cache++];
967         c->fd = fd;
968         c->address = address;
969
970         /* If overly long, let's return a bit to the OS */
971         if (size > max_sz) {
972                 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
973                 assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
974                 c->size = max_sz;
975         } else
976                 c->size = size;
977
978         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
979 }
980
981 void bus_kernel_flush_memfd(sd_bus *b) {
982         unsigned i;
983
984         assert(b);
985
986         for (i = 0; i < b->n_memfd_cache; i++)
987                 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
988 }
989
990 int sd_bus_kernel_translate_request_name_flags(uint64_t sd_bus_flags, uint64_t *kdbus_flags) {
991
992         assert_return(kdbus_flags != NULL, -EINVAL);
993
994         *kdbus_flags = 0;
995
996         if (sd_bus_flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
997                 *kdbus_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
998
999         if (sd_bus_flags & SD_BUS_NAME_REPLACE_EXISTING)
1000                 *kdbus_flags |= KDBUS_NAME_REPLACE_EXISTING;
1001
1002         if (!(sd_bus_flags & SD_BUS_NAME_DO_NOT_QUEUE))
1003                 *kdbus_flags |= KDBUS_NAME_QUEUE;
1004
1005         return 0;
1006 }