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