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