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