chiark / gitweb /
sd-bus: add sd_bus_message.verify_destination_id and .destination_ptr
[elogind.git] / src / libsystemd / sd-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 <libgen.h>
29 #include <sys/mman.h>
30 #include <sys/prctl.h>
31
32 #include "util.h"
33 #include "strv.h"
34 #include "memfd-util.h"
35
36 #include "bus-internal.h"
37 #include "bus-message.h"
38 #include "bus-kernel.h"
39 #include "bus-bloom.h"
40 #include "bus-util.h"
41 #include "bus-label.h"
42 #include "cgroup-util.h"
43
44 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
45
46 int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
47         int r;
48
49         assert(s);
50         assert(id);
51
52         if (!startswith(s, ":1."))
53                 return 0;
54
55         r = safe_atou64(s + 3, id);
56         if (r < 0)
57                 return r;
58
59         return 1;
60 }
61
62 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
63         assert(d);
64         assert(sz > 0);
65
66         *d = ALIGN8_PTR(*d);
67
68         /* Note that p can be NULL, which encodes a region full of
69          * zeroes, which is useful to optimize certain padding
70          * conditions */
71
72         (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
73         (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
74         (*d)->vec.address = PTR_TO_UINT64(p);
75         (*d)->vec.size = sz;
76
77         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
78 }
79
80 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
81         assert(d);
82         assert(memfd >= 0);
83         assert(sz > 0);
84
85         *d = ALIGN8_PTR(*d);
86         (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
87         (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
88         (*d)->memfd.fd = memfd;
89         (*d)->memfd.size = sz;
90
91         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
92 }
93
94 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
95         assert(d);
96         assert(s);
97
98         *d = ALIGN8_PTR(*d);
99
100         (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
101         (*d)->type = KDBUS_ITEM_DST_NAME;
102         memcpy((*d)->str, s, length + 1);
103
104         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
105 }
106
107 static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
108         struct kdbus_item *i;
109
110         assert(d);
111
112         i = ALIGN8_PTR(*d);
113
114         i->size = offsetof(struct kdbus_item, bloom_filter) +
115                   offsetof(struct kdbus_bloom_filter, data) +
116                   length;
117         i->type = KDBUS_ITEM_BLOOM_FILTER;
118
119         *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
120
121         return &i->bloom_filter;
122 }
123
124 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
125         assert(d);
126         assert(fds);
127         assert(n_fds > 0);
128
129         *d = ALIGN8_PTR(*d);
130         (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
131         (*d)->type = KDBUS_ITEM_FDS;
132         memcpy((*d)->fds, fds, sizeof(int) * n_fds);
133
134         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
135 }
136
137 static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
138         void *data;
139         unsigned i;
140         int r;
141
142         assert(m);
143         assert(bloom);
144
145         data = bloom->data;
146         memzero(data, m->bus->bloom_size);
147         bloom->generation = 0;
148
149         bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
150
151         if (m->interface)
152                 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
153         if (m->member)
154                 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
155         if (m->path) {
156                 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
157                 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
158                 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
159         }
160
161         r = sd_bus_message_rewind(m, true);
162         if (r < 0)
163                 return r;
164
165         for (i = 0; i < 64; i++) {
166                 char type;
167                 const char *t;
168                 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
169                 char *e;
170
171                 r = sd_bus_message_peek_type(m, &type, NULL);
172                 if (r < 0)
173                         return r;
174
175                 if (type != SD_BUS_TYPE_STRING &&
176                     type != SD_BUS_TYPE_OBJECT_PATH &&
177                     type != SD_BUS_TYPE_SIGNATURE)
178                         break;
179
180                 r = sd_bus_message_read_basic(m, type, &t);
181                 if (r < 0)
182                         return r;
183
184                 e = stpcpy(buf, "arg");
185                 if (i < 10)
186                         *(e++) = '0' + (char) i;
187                 else {
188                         *(e++) = '0' + (char) (i / 10);
189                         *(e++) = '0' + (char) (i % 10);
190                 }
191
192                 *e = 0;
193                 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
194
195                 strcpy(e, "-dot-prefix");
196                 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
197                 strcpy(e, "-slash-prefix");
198                 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
199         }
200
201         return 0;
202 }
203
204 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
205         struct bus_body_part *part;
206         struct kdbus_item *d;
207         const char *destination;
208         bool well_known;
209         uint64_t unique;
210         size_t sz, dl;
211         unsigned i;
212         int r;
213
214         assert(b);
215         assert(m);
216         assert(m->sealed);
217
218         /* We put this together only once, if this message is reused
219          * we reuse the earlier-built version */
220         if (m->kdbus)
221                 return 0;
222
223         destination = m->destination ?: m->destination_ptr;
224
225         if (destination) {
226                 r = bus_kernel_parse_unique_name(destination, &unique);
227                 if (r < 0)
228                         return r;
229
230                 well_known = r == 0;
231         } else
232                 well_known = false;
233
234         sz = offsetof(struct kdbus_msg, items);
235
236         assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
237                   ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
238
239         /* Add in fixed header, fields header and payload */
240         sz += (1 + m->n_body_parts) *
241                 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
242
243         /* Add space for bloom filter */
244         sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
245                      offsetof(struct kdbus_bloom_filter, data) +
246                      m->bus->bloom_size);
247
248         /* Add in well-known destination header */
249         if (well_known) {
250                 dl = strlen(destination);
251                 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
252         }
253
254         /* Add space for unix fds */
255         if (m->n_fds > 0)
256                 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
257
258         m->kdbus = memalign(8, sz);
259         if (!m->kdbus) {
260                 r = -ENOMEM;
261                 goto fail;
262         }
263
264         m->free_kdbus = true;
265         memzero(m->kdbus, sz);
266
267         m->kdbus->flags =
268                 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
269                 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
270
271         if (well_known) {
272                 /* verify_destination_id will usually be 0, which makes the kernel driver only look
273                  * at the provided well-known name. Otherwise, the kernel will make sure the provided
274                  * destination id matches the owner of the provided weel-known-name, and fail if they
275                  * differ. Currently, this is only needed for bus-proxyd. */
276                 m->kdbus->dst_id = m->verify_destination_id;
277         } else {
278                 m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
279         }
280
281         m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
282         m->kdbus->cookie = (uint64_t) m->header->serial;
283         m->kdbus->priority = m->priority;
284
285         if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) {
286                 m->kdbus->cookie_reply = m->reply_cookie;
287         } else {
288                 struct timespec now;
289
290                 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
291                 m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
292                                        m->timeout * NSEC_PER_USEC;
293         }
294
295         d = m->kdbus->items;
296
297         if (well_known)
298                 append_destination(&d, destination, dl);
299
300         append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
301
302         MESSAGE_FOREACH_PART(part, i, m) {
303                 if (part->is_zero) {
304                         /* If this is padding then simply send a
305                          * vector with a NULL data pointer which the
306                          * kernel will just pass through. This is the
307                          * most efficient way to encode zeroes */
308
309                         append_payload_vec(&d, NULL, part->size);
310                         continue;
311                 }
312
313                 if (part->memfd >= 0 && part->sealed && destination) {
314                         /* Try to send a memfd, if the part is
315                          * sealed and this is not a broadcast. Since we can only  */
316
317                         append_payload_memfd(&d, part->memfd, part->size);
318                         continue;
319                 }
320
321                 /* Otherwise, let's send a vector to the actual data.
322                  * For that, we need to map it first. */
323                 r = bus_body_part_map(part);
324                 if (r < 0)
325                         goto fail;
326
327                 append_payload_vec(&d, part->data, part->size);
328         }
329
330         if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
331                 struct kdbus_bloom_filter *bloom;
332
333                 bloom = append_bloom(&d, m->bus->bloom_size);
334                 r = bus_message_setup_bloom(m, bloom);
335                 if (r < 0)
336                         goto fail;
337         }
338
339         if (m->n_fds > 0)
340                 append_fds(&d, m->fds, m->n_fds);
341
342         m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
343         assert(m->kdbus->size <= sz);
344
345         return 0;
346
347 fail:
348         m->poisoned = true;
349         return r;
350 }
351
352 static void unset_memfds(struct sd_bus_message *m) {
353         struct bus_body_part *part;
354         unsigned i;
355
356         assert(m);
357
358         /* Make sure the memfds are not freed twice */
359         MESSAGE_FOREACH_PART(part, i, m)
360                 if (part->memfd >= 0)
361                         part->memfd = -1;
362 }
363
364 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
365         sd_bus_message *m = NULL;
366         struct kdbus_item *d;
367         unsigned n_fds = 0;
368         _cleanup_free_ int *fds = NULL;
369         struct bus_header *h = NULL;
370         size_t total, n_bytes = 0, idx = 0;
371         const char *destination = NULL, *seclabel = NULL;
372         int r;
373
374         assert(bus);
375         assert(k);
376         assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
377
378         KDBUS_ITEM_FOREACH(d, k, items) {
379                 size_t l;
380
381                 l = d->size - offsetof(struct kdbus_item, data);
382
383                 switch (d->type) {
384
385                 case KDBUS_ITEM_PAYLOAD_OFF:
386                         if (!h) {
387                                 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
388
389                                 if (!bus_header_is_complete(h, d->vec.size))
390                                         return -EBADMSG;
391                         }
392
393                         n_bytes += d->vec.size;
394                         break;
395
396                 case KDBUS_ITEM_PAYLOAD_MEMFD:
397                         if (!h)
398                                 return -EBADMSG;
399
400                         n_bytes += d->memfd.size;
401                         break;
402
403                 case KDBUS_ITEM_FDS: {
404                         int *f;
405                         unsigned j;
406
407                         j = l / sizeof(int);
408                         f = realloc(fds, sizeof(int) * (n_fds + j));
409                         if (!f)
410                                 return -ENOMEM;
411
412                         fds = f;
413                         memcpy(fds + n_fds, d->fds, sizeof(int) * j);
414                         n_fds += j;
415                         break;
416                 }
417
418                 case KDBUS_ITEM_SECLABEL:
419                         seclabel = d->str;
420                         break;
421                 }
422         }
423
424         if (!h)
425                 return -EBADMSG;
426
427         r = bus_header_message_size(h, &total);
428         if (r < 0)
429                 return r;
430
431         if (n_bytes != total)
432                 return -EBADMSG;
433
434         /* on kdbus we only speak native endian gvariant, never dbus1
435          * marshalling or reverse endian */
436         if (h->version != 2 ||
437             h->endian != BUS_NATIVE_ENDIAN)
438                 return -EPROTOTYPE;
439
440         r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
441         if (r < 0)
442                 return r;
443
444         /* The well-known names list is different from the other
445         credentials. If we asked for it, but nothing is there, this
446         means that the list of well-known names is simply empty, not
447         that we lack any data */
448
449         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
450
451         KDBUS_ITEM_FOREACH(d, k, items) {
452                 size_t l;
453
454                 l = d->size - offsetof(struct kdbus_item, data);
455
456                 switch (d->type) {
457
458                 case KDBUS_ITEM_PAYLOAD_OFF: {
459                         size_t begin_body;
460
461                         begin_body = BUS_MESSAGE_BODY_BEGIN(m);
462
463                         if (idx + d->vec.size > begin_body) {
464                                 struct bus_body_part *part;
465
466                                 /* Contains body material */
467
468                                 part = message_append_part(m);
469                                 if (!part) {
470                                         r = -ENOMEM;
471                                         goto fail;
472                                 }
473
474                                 /* A -1 offset is NUL padding. */
475                                 part->is_zero = d->vec.offset == ~0ULL;
476
477                                 if (idx >= begin_body) {
478                                         if (!part->is_zero)
479                                                 part->data = (uint8_t *)k + d->vec.offset;
480                                         part->size = d->vec.size;
481                                 } else {
482                                         if (!part->is_zero)
483                                                 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
484                                         part->size = d->vec.size - (begin_body - idx);
485                                 }
486
487                                 part->sealed = true;
488                         }
489
490                         idx += d->vec.size;
491                         break;
492                 }
493
494                 case KDBUS_ITEM_PAYLOAD_MEMFD: {
495                         struct bus_body_part *part;
496
497                         if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
498                                 r = -EBADMSG;
499                                 goto fail;
500                         }
501
502                         part = message_append_part(m);
503                         if (!part) {
504                                 r = -ENOMEM;
505                                 goto fail;
506                         }
507
508                         part->memfd = d->memfd.fd;
509                         part->size = d->memfd.size;
510                         part->sealed = true;
511
512                         idx += d->memfd.size;
513                         break;
514                 }
515
516                 case KDBUS_ITEM_CREDS:
517                         /* UID/GID/PID are always valid */
518                         m->creds.uid = (uid_t) d->creds.uid;
519                         m->creds.gid = (gid_t) d->creds.gid;
520                         m->creds.pid = (pid_t) d->creds.pid;
521                         m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
522
523                         /* The PID starttime/TID might be missing
524                          * however, when the data is faked by some
525                          * data bus proxy and it lacks that
526                          * information about the real client since
527                          * SO_PEERCRED is used for that */
528
529                         if (d->creds.starttime > 0) {
530                                 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
531                                 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
532                         }
533
534                         if (d->creds.tid > 0) {
535                                 m->creds.tid = (pid_t) d->creds.tid;
536                                 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
537                         }
538                         break;
539
540                 case KDBUS_ITEM_TIMESTAMP:
541
542                         if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
543                                 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
544                                 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
545                                 m->seqnum = d->timestamp.seqnum;
546                         }
547
548                         break;
549
550                 case KDBUS_ITEM_PID_COMM:
551                         m->creds.comm = d->str;
552                         m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
553                         break;
554
555                 case KDBUS_ITEM_TID_COMM:
556                         m->creds.tid_comm = d->str;
557                         m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
558                         break;
559
560                 case KDBUS_ITEM_EXE:
561                         m->creds.exe = d->str;
562                         m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
563                         break;
564
565                 case KDBUS_ITEM_CMDLINE:
566                         m->creds.cmdline = d->str;
567                         m->creds.cmdline_size = l;
568                         m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
569                         break;
570
571                 case KDBUS_ITEM_CGROUP:
572                         m->creds.cgroup = d->str;
573                         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;
574
575                         r = bus_get_root_path(bus);
576                         if (r < 0)
577                                 goto fail;
578
579                         m->creds.cgroup_root = bus->cgroup_root;
580
581                         break;
582
583                 case KDBUS_ITEM_AUDIT:
584                         m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
585                         m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
586                         m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
587                         break;
588
589                 case KDBUS_ITEM_CAPS:
590                         m->creds.capability = (uint8_t *) d->caps.caps;
591                         m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps);
592                         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;
593                         break;
594
595                 case KDBUS_ITEM_DST_NAME:
596                         if (!service_name_is_valid(d->str))
597                                 return -EBADMSG;
598
599                         destination = d->str;
600                         break;
601
602                 case KDBUS_ITEM_OWNED_NAME:
603                         if (!service_name_is_valid(d->name.name))
604                                 return -EBADMSG;
605
606                         r = strv_extend(&m->creds.well_known_names, d->name.name);
607                         if (r < 0)
608                                 goto fail;
609                         break;
610
611                 case KDBUS_ITEM_CONN_DESCRIPTION:
612                         m->creds.description = d->str;
613                         m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
614                         break;
615
616                 case KDBUS_ITEM_FDS:
617                 case KDBUS_ITEM_SECLABEL:
618                         break;
619
620                 default:
621                         log_debug("Got unknown field from kernel %llu", d->type);
622                 }
623         }
624
625         r = bus_message_parse_fields(m);
626         if (r < 0)
627                 goto fail;
628
629         /* Override information from the user header with data from the kernel */
630         if (k->src_id == KDBUS_SRC_ID_KERNEL)
631                 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
632         else {
633                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
634                 m->sender = m->creds.unique_name = m->sender_buffer;
635         }
636
637         if (destination)
638                 m->destination = destination;
639         else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
640                 m->destination = NULL;
641         else if (k->dst_id == KDBUS_DST_ID_NAME)
642                 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
643         else {
644                 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
645                 m->destination = m->destination_buffer;
646         }
647
648         /* We take possession of the kmsg struct now */
649         m->kdbus = k;
650         m->release_kdbus = true;
651         m->free_fds = true;
652         fds = NULL;
653
654         bus->rqueue[bus->rqueue_size++] = m;
655
656         return 1;
657
658 fail:
659         unset_memfds(m);
660         sd_bus_message_unref(m);
661
662         return r;
663 }
664
665 int bus_kernel_take_fd(sd_bus *b) {
666         struct kdbus_cmd_hello *hello;
667         struct kdbus_item *item;
668         _cleanup_free_ char *g = NULL;
669         const char *name;
670         size_t l = 0, m = 0, sz;
671         int r;
672
673         assert(b);
674
675         if (b->is_server)
676                 return -EINVAL;
677
678         b->use_memfd = 1;
679
680         if (b->description) {
681                 g = bus_label_escape(b->description);
682                 if (!g)
683                         return -ENOMEM;
684
685                 name = g;
686         } else {
687                 char pr[17] = {};
688
689                 /* If no name is explicitly set, we'll include a hint
690                  * indicating the library implementation, a hint which
691                  * kind of bus this is and the thread name */
692
693                 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
694
695                 if (isempty(pr)) {
696                         name = b->is_system ? "sd-system" :
697                                 b->is_user ? "sd-user" : "sd";
698                 } else {
699                         _cleanup_free_ char *e = NULL;
700
701                         e = bus_label_escape(pr);
702                         if (!e)
703                                 return -ENOMEM;
704
705                         g = strappend(b->is_system ? "sd-system-" :
706                                       b->is_user ? "sd-user-" : "sd-",
707                                       e);
708                         if (!g)
709                                 return -ENOMEM;
710
711                         name = g;
712                 }
713
714                 b->description = bus_label_unescape(name);
715                 if (!b->description)
716                         return -ENOMEM;
717         }
718
719         m = strlen(name);
720
721         sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
722                 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
723
724         if (b->fake_creds_valid)
725                 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
726
727         if (b->fake_label) {
728                 l = strlen(b->fake_label);
729                 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
730         }
731
732         hello = alloca0_align(sz, 8);
733         hello->size = sz;
734         hello->flags = b->hello_flags;
735         hello->attach_flags_send = _KDBUS_ATTACH_ANY;
736         hello->attach_flags_recv = b->attach_flags;
737         hello->pool_size = KDBUS_POOL_SIZE;
738
739         item = hello->items;
740
741         item->size = offsetof(struct kdbus_item, str) + m + 1;
742         item->type = KDBUS_ITEM_CONN_DESCRIPTION;
743         memcpy(item->str, name, m + 1);
744         item = KDBUS_ITEM_NEXT(item);
745
746         if (b->fake_creds_valid) {
747                 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
748                 item->type = KDBUS_ITEM_CREDS;
749                 item->creds = b->fake_creds;
750
751                 item = KDBUS_ITEM_NEXT(item);
752         }
753
754         if (b->fake_label) {
755                 item->size = offsetof(struct kdbus_item, str) + l + 1;
756                 item->type = KDBUS_ITEM_SECLABEL;
757                 memcpy(item->str, b->fake_label, l+1);
758         }
759
760         r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
761         if (r < 0)
762                 return -errno;
763
764         if (!b->kdbus_buffer) {
765                 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
766                 if (b->kdbus_buffer == MAP_FAILED) {
767                         b->kdbus_buffer = NULL;
768                         return -errno;
769                 }
770         }
771
772         /* The higher 32bit of the bus_flags fields are considered
773          * 'incompatible flags'. Refuse them all for now. */
774         if (hello->bus_flags > 0xFFFFFFFFULL)
775                 return -ENOTSUP;
776
777         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
778                 return -ENOTSUP;
779
780         b->bloom_size = (size_t) hello->bloom.size;
781         b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
782
783         if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
784                 return -ENOMEM;
785
786         b->unique_id = hello->id;
787
788         b->is_kernel = true;
789         b->bus_client = true;
790         b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
791         b->message_version = 2;
792         b->message_endian = BUS_NATIVE_ENDIAN;
793
794         /* the kernel told us the UUID of the underlying bus */
795         memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
796
797         return bus_start_running(b);
798 }
799
800 int bus_kernel_connect(sd_bus *b) {
801         assert(b);
802         assert(b->input_fd < 0);
803         assert(b->output_fd < 0);
804         assert(b->kernel);
805
806         if (b->is_server)
807                 return -EINVAL;
808
809         b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
810         if (b->input_fd < 0)
811                 return -errno;
812
813         b->output_fd = b->input_fd;
814
815         return bus_kernel_take_fd(b);
816 }
817
818 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
819         struct kdbus_cmd_free cmd;
820         struct kdbus_item *d;
821
822         assert(bus);
823         assert(k);
824
825         cmd.flags = 0;
826         cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
827
828         KDBUS_ITEM_FOREACH(d, k, items) {
829
830                 if (d->type == KDBUS_ITEM_FDS)
831                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
832                 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
833                         safe_close(d->memfd.fd);
834         }
835
836         (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
837 }
838
839 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
840         int r;
841
842         assert(bus);
843         assert(m);
844         assert(bus->state == BUS_RUNNING);
845
846         /* If we can't deliver, we want room for the error message */
847         r = bus_rqueue_make_room(bus);
848         if (r < 0)
849                 return r;
850
851         r = bus_message_setup_kmsg(bus, m);
852         if (r < 0)
853                 return r;
854
855         /* If this is a synchronous method call, then let's tell the
856          * kernel, so that it can pass CPU time/scheduling to the
857          * destination for the time, if it wants to. If we
858          * synchronously wait for the result anyway, we won't need CPU
859          * anyway. */
860         if (hint_sync_call)
861                 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
862
863         r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
864         if (r < 0) {
865                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
866                 sd_bus_message *reply;
867
868                 if (errno == EAGAIN || errno == EINTR)
869                         return 0;
870                 else if (errno == ENXIO || errno == ESRCH) {
871
872                         /* ENXIO: unique name not known
873                          * ESRCH: well-known name not known */
874
875                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
876                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
877                         else {
878                                 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
879                                 return 0;
880                         }
881
882                 } else if (errno == EADDRNOTAVAIL) {
883
884                         /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
885
886                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
887                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
888                         else {
889                                 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
890                                 return 0;
891                         }
892                 } else
893                         return -errno;
894
895                 r = bus_message_new_synthetic_error(
896                                 bus,
897                                 BUS_MESSAGE_COOKIE(m),
898                                 &error,
899                                 &reply);
900
901                 if (r < 0)
902                         return r;
903
904                 r = bus_seal_synthetic_message(bus, reply);
905                 if (r < 0)
906                         return r;
907
908                 bus->rqueue[bus->rqueue_size++] = reply;
909
910         } else if (hint_sync_call) {
911                 struct kdbus_msg *k;
912
913                 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
914                 assert(k);
915
916                 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
917
918                         r = bus_kernel_make_message(bus, k);
919                         if (r < 0) {
920                                 close_kdbus_msg(bus, k);
921
922                                 /* Anybody can send us invalid messages, let's just drop them. */
923                                 if (r == -EBADMSG || r == -EPROTOTYPE)
924                                         log_debug("Ignoring invalid message: %s", strerror(-r));
925                                 else
926                                         return r;
927                         }
928                 } else {
929                         log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
930                         close_kdbus_msg(bus, k);
931                 }
932         }
933
934         return 1;
935 }
936
937 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
938         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
939         int r;
940
941         assert(bus);
942
943         r = sd_bus_message_new_signal(
944                         bus,
945                         &m,
946                         "/org/freedesktop/DBus",
947                         "org.freedesktop.DBus",
948                         "NameOwnerChanged");
949         if (r < 0)
950                 return r;
951
952         r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
953         if (r < 0)
954                 return r;
955
956         m->sender = "org.freedesktop.DBus";
957
958         r = bus_seal_synthetic_message(bus, m);
959         if (r < 0)
960                 return r;
961
962         bus->rqueue[bus->rqueue_size++] = m;
963         m = NULL;
964
965         return 1;
966 }
967
968 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
969         char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
970
971         assert(bus);
972         assert(k);
973         assert(d);
974
975         if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
976                 old_owner[0] = 0;
977         else
978                 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
979
980         if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
981
982                 if (isempty(old_owner))
983                         return 0;
984
985                 new_owner[0] = 0;
986         } else
987                 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
988
989         return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
990 }
991
992 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
993         char owner[UNIQUE_NAME_MAX];
994
995         assert(bus);
996         assert(k);
997         assert(d);
998
999         sprintf(owner, ":1.%llu", d->id_change.id);
1000
1001         return push_name_owner_changed(
1002                         bus, owner,
1003                         d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1004                         d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
1005 }
1006
1007 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1008         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1009         int r;
1010
1011         assert(bus);
1012         assert(k);
1013         assert(d);
1014
1015         r = bus_message_new_synthetic_error(
1016                         bus,
1017                         k->cookie_reply,
1018                         d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1019                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1020                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1021                         &m);
1022         if (r < 0)
1023                 return r;
1024
1025         m->sender = "org.freedesktop.DBus";
1026
1027         r = bus_seal_synthetic_message(bus, m);
1028         if (r < 0)
1029                 return r;
1030
1031         bus->rqueue[bus->rqueue_size++] = m;
1032         m = NULL;
1033
1034         return 1;
1035 }
1036
1037 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1038         struct kdbus_item *d, *found = NULL;
1039
1040         static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1041                 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1042                 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1043                 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1044
1045                 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1046                 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1047
1048                 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1049                 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1050         };
1051
1052         assert(bus);
1053         assert(k);
1054         assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1055
1056         KDBUS_ITEM_FOREACH(d, k, items) {
1057                 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1058                         if (found)
1059                                 return -EBADMSG;
1060                         found = d;
1061                 } else
1062                         log_debug("Got unknown field from kernel %llu", d->type);
1063         }
1064
1065         if (!found) {
1066                 log_debug("Didn't find a kernel message to translate.");
1067                 return 0;
1068         }
1069
1070         return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
1071 }
1072
1073 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1074         struct kdbus_cmd_recv recv = {};
1075         struct kdbus_msg *k;
1076         int r;
1077
1078         assert(bus);
1079
1080         r = bus_rqueue_make_room(bus);
1081         if (r < 0)
1082                 return r;
1083
1084         if (hint_priority) {
1085                 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1086                 recv.priority = priority;
1087         }
1088
1089         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1090         if (r < 0) {
1091                 if (errno == EAGAIN)
1092                         return 0;
1093
1094                 return -errno;
1095         }
1096
1097         k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1098         if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1099                 r = bus_kernel_make_message(bus, k);
1100
1101                 /* Anybody can send us invalid messages, let's just drop them. */
1102                 if (r == -EBADMSG || r == -EPROTOTYPE) {
1103                         log_debug("Ignoring invalid message: %s", strerror(-r));
1104                         r = 0;
1105                 }
1106
1107         } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1108                 r = bus_kernel_translate_message(bus, k);
1109         else {
1110                 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1111                 r = 0;
1112         }
1113
1114         if (r <= 0)
1115                 close_kdbus_msg(bus, k);
1116
1117         return r < 0 ? r : 1;
1118 }
1119
1120 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1121         struct memfd_cache *c;
1122         int fd;
1123
1124         assert(address);
1125         assert(mapped);
1126         assert(allocated);
1127
1128         if (!bus || !bus->is_kernel)
1129                 return -ENOTSUP;
1130
1131         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1132
1133         if (bus->n_memfd_cache <= 0) {
1134                 int r;
1135
1136                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1137
1138                 r = memfd_new(bus->description);
1139                 if (r < 0)
1140                         return r;
1141
1142                 *address = NULL;
1143                 *mapped = 0;
1144                 *allocated = 0;
1145                 return r;
1146         }
1147
1148         c = &bus->memfd_cache[--bus->n_memfd_cache];
1149
1150         assert(c->fd >= 0);
1151         assert(c->mapped == 0 || c->address);
1152
1153         *address = c->address;
1154         *mapped = c->mapped;
1155         *allocated = c->allocated;
1156         fd = c->fd;
1157
1158         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1159
1160         return fd;
1161 }
1162
1163 static void close_and_munmap(int fd, void *address, size_t size) {
1164         if (size > 0)
1165                 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1166
1167         safe_close(fd);
1168 }
1169
1170 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1171         struct memfd_cache *c;
1172         uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1173
1174         assert(fd >= 0);
1175         assert(mapped == 0 || address);
1176
1177         if (!bus || !bus->is_kernel) {
1178                 close_and_munmap(fd, address, mapped);
1179                 return;
1180         }
1181
1182         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1183
1184         if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1185                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1186
1187                 close_and_munmap(fd, address, mapped);
1188                 return;
1189         }
1190
1191         c = &bus->memfd_cache[bus->n_memfd_cache++];
1192         c->fd = fd;
1193         c->address = address;
1194
1195         /* If overly long, let's return a bit to the OS */
1196         if (mapped > max_mapped) {
1197                 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1198                 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1199                 c->mapped = c->allocated = max_mapped;
1200         } else {
1201                 c->mapped = mapped;
1202                 c->allocated = allocated;
1203         }
1204
1205         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1206 }
1207
1208 void bus_kernel_flush_memfd(sd_bus *b) {
1209         unsigned i;
1210
1211         assert(b);
1212
1213         for (i = 0; i < b->n_memfd_cache; i++)
1214                 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1215 }
1216
1217 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1218         uint64_t f = 0;
1219
1220         assert(kdbus_flags);
1221
1222         if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1223                 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1224
1225         if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1226                 f |= KDBUS_NAME_REPLACE_EXISTING;
1227
1228         if (flags & SD_BUS_NAME_QUEUE)
1229                 f |= KDBUS_NAME_QUEUE;
1230
1231         *kdbus_flags = f;
1232         return 0;
1233 }
1234
1235 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1236         uint64_t m = 0;
1237
1238         assert(kdbus_mask);
1239
1240         if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1241                 m |= KDBUS_ATTACH_CREDS;
1242
1243         if (mask & SD_BUS_CREDS_COMM)
1244                 m |= KDBUS_ATTACH_PID_COMM;
1245
1246         if (mask & SD_BUS_CREDS_TID_COMM)
1247                 m |= KDBUS_ATTACH_TID_COMM;
1248
1249         if (mask & SD_BUS_CREDS_EXE)
1250                 m |= KDBUS_ATTACH_EXE;
1251
1252         if (mask & SD_BUS_CREDS_CMDLINE)
1253                 m |= KDBUS_ATTACH_CMDLINE;
1254
1255         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))
1256                 m |= KDBUS_ATTACH_CGROUP;
1257
1258         if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1259                 m |= KDBUS_ATTACH_CAPS;
1260
1261         if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1262                 m |= KDBUS_ATTACH_SECLABEL;
1263
1264         if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1265                 m |= KDBUS_ATTACH_AUDIT;
1266
1267         if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1268                 m |= KDBUS_ATTACH_NAMES;
1269
1270         if (mask & SD_BUS_CREDS_DESCRIPTION)
1271                 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1272
1273         *kdbus_mask = m;
1274         return 0;
1275 }
1276
1277 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1278         struct kdbus_cmd_make *make;
1279         struct kdbus_item *n;
1280         int fd;
1281
1282         assert(name);
1283         assert(s);
1284
1285         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1286         if (fd < 0)
1287                 return -errno;
1288
1289         make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1290                                     offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1291                                     offsetof(struct kdbus_item, str) +
1292                                     DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
1293                              8);
1294
1295         make->size = offsetof(struct kdbus_cmd_make, items);
1296
1297         n = make->items;
1298         n->size = offsetof(struct kdbus_item, bloom_parameter) +
1299                   sizeof(struct kdbus_bloom_parameter);
1300         n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1301
1302         n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1303         n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1304
1305         assert_cc(DEFAULT_BLOOM_SIZE > 0);
1306         assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1307
1308         make->size += ALIGN8(n->size);
1309
1310         n = KDBUS_ITEM_NEXT(n);
1311         sprintf(n->str, UID_FMT "-%s", getuid(), name);
1312         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1313         n->type = KDBUS_ITEM_MAKE_NAME;
1314         make->size += ALIGN8(n->size);
1315
1316         make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1317
1318         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1319                 safe_close(fd);
1320                 return -errno;
1321         }
1322
1323         if (s) {
1324                 char *p;
1325
1326                 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1327                 if (!p) {
1328                         safe_close(fd);
1329                         return -ENOMEM;
1330                 }
1331
1332                 *s = p;
1333         }
1334
1335         return fd;
1336 }
1337
1338 static int bus_kernel_translate_access(BusPolicyAccess access) {
1339         assert(access >= 0);
1340         assert(access < _BUS_POLICY_ACCESS_MAX);
1341
1342         switch (access) {
1343
1344         case BUS_POLICY_ACCESS_SEE:
1345                 return KDBUS_POLICY_SEE;
1346
1347         case BUS_POLICY_ACCESS_TALK:
1348                 return KDBUS_POLICY_TALK;
1349
1350         case BUS_POLICY_ACCESS_OWN:
1351                 return KDBUS_POLICY_OWN;
1352
1353         default:
1354                 assert_not_reached("Unknown policy access");
1355         }
1356 }
1357
1358 static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
1359         int r;
1360
1361         assert(policy);
1362         assert(item);
1363
1364         switch (policy->type) {
1365
1366         case BUSNAME_POLICY_TYPE_USER: {
1367                 const char *user = policy->name;
1368                 uid_t uid;
1369
1370                 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
1371                 if (r < 0)
1372                         return r;
1373
1374                 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1375                 item->policy_access.id = uid;
1376                 break;
1377         }
1378
1379         case BUSNAME_POLICY_TYPE_GROUP: {
1380                 const char *group = policy->name;
1381                 gid_t gid;
1382
1383                 r = get_group_creds(&group, &gid);
1384                 if (r < 0)
1385                         return r;
1386
1387                 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1388                 item->policy_access.id = gid;
1389                 break;
1390         }
1391
1392         default:
1393                 assert_not_reached("Unknown policy type");
1394         }
1395
1396         item->policy_access.access = bus_kernel_translate_access(policy->access);
1397
1398         return 0;
1399 }
1400
1401 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1402         char *p;
1403         int fd;
1404         size_t len;
1405
1406         len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1407
1408         if (path) {
1409                 p = malloc(len);
1410                 if (!p)
1411                         return -ENOMEM;
1412                 *path = p;
1413         } else
1414                 p = alloca(len);
1415         sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1416
1417         fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1418         if (fd < 0)
1419                 return -errno;
1420
1421         return fd;
1422 }
1423
1424 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1425         _cleanup_free_ char *path = NULL;
1426         struct kdbus_cmd_make *make;
1427         struct kdbus_item *n;
1428         size_t size;
1429         int fd;
1430
1431         fd = bus_kernel_open_bus_fd(bus_name, &path);
1432         if (fd < 0)
1433                 return fd;
1434
1435         size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1436         size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
1437
1438         make = alloca0_align(size, 8);
1439         make->size = size;
1440         make->flags = KDBUS_MAKE_ACCESS_WORLD;
1441
1442         n = make->items;
1443
1444         n->type = KDBUS_ITEM_MAKE_NAME;
1445         n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1;
1446         strcpy(n->str, ep_name);
1447
1448         if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1449                 safe_close(fd);
1450                 return -errno;
1451         }
1452
1453         if (ep_path) {
1454                 char *p;
1455
1456                 p = strjoin(dirname(path), "/", ep_name, NULL);
1457                 if (!p) {
1458                         safe_close(fd);
1459                         return -ENOMEM;
1460                 }
1461
1462                 *ep_path = p;
1463         }
1464
1465         return fd;
1466 }
1467
1468 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
1469
1470         struct kdbus_cmd_update *update;
1471         struct kdbus_item *n;
1472         BusEndpointPolicy *po;
1473         Iterator i;
1474         size_t size;
1475         int r;
1476
1477         size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
1478
1479         HASHMAP_FOREACH(po, ep->policy_hash, i) {
1480                 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
1481                 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1482         }
1483
1484         update = alloca0_align(size, 8);
1485         update->size = size;
1486
1487         n = update->items;
1488
1489         HASHMAP_FOREACH(po, ep->policy_hash, i) {
1490                 n->type = KDBUS_ITEM_NAME;
1491                 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
1492                 strcpy(n->str, po->name);
1493                 n = KDBUS_ITEM_NEXT(n);
1494
1495                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1496                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1497
1498                 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1499                 n->policy_access.access = bus_kernel_translate_access(po->access);
1500                 n->policy_access.id = uid;
1501
1502                 n = KDBUS_ITEM_NEXT(n);
1503         }
1504
1505         r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
1506         if (r < 0)
1507                 return -errno;
1508
1509         return 0;
1510 }
1511
1512 int bus_kernel_make_starter(
1513                 int fd,
1514                 const char *name,
1515                 bool activating,
1516                 bool accept_fd,
1517                 BusNamePolicy *policy,
1518                 BusPolicyAccess world_policy) {
1519
1520         struct kdbus_cmd_hello *hello;
1521         struct kdbus_item *n;
1522         size_t policy_cnt = 0;
1523         BusNamePolicy *po;
1524         size_t size;
1525         int r;
1526
1527         assert(fd >= 0);
1528         assert(name);
1529
1530         LIST_FOREACH(policy, po, policy)
1531                 policy_cnt++;
1532
1533         if (world_policy >= 0)
1534                 policy_cnt++;
1535
1536         size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1537                ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1538                policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1539
1540         hello = alloca0_align(size, 8);
1541
1542         n = hello->items;
1543         strcpy(n->str, name);
1544         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1545         n->type = KDBUS_ITEM_NAME;
1546         n = KDBUS_ITEM_NEXT(n);
1547
1548         LIST_FOREACH(policy, po, policy) {
1549                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1550                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1551
1552                 r = bus_kernel_translate_policy(po, n);
1553                 if (r < 0)
1554                         return r;
1555
1556                 n = KDBUS_ITEM_NEXT(n);
1557         }
1558
1559         if (world_policy >= 0) {
1560                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1561                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1562                 n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1563                 n->policy_access.access = bus_kernel_translate_access(world_policy);
1564         }
1565
1566         hello->size = size;
1567         hello->flags =
1568                 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1569                 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
1570         hello->pool_size = KDBUS_POOL_SIZE;
1571         hello->attach_flags_send = _KDBUS_ATTACH_ANY;
1572         hello->attach_flags_recv = _KDBUS_ATTACH_ALL;
1573
1574         if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
1575                 return -errno;
1576
1577         /* The higher 32bit of the bus_flags fields are considered
1578          * 'incompatible flags'. Refuse them all for now. */
1579         if (hello->bus_flags > 0xFFFFFFFFULL)
1580                 return -ENOTSUP;
1581
1582         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
1583                 return -ENOTSUP;
1584
1585         return fd;
1586 }
1587
1588 int bus_kernel_create_domain(const char *name, char **s) {
1589         struct kdbus_cmd_make *make;
1590         struct kdbus_item *n;
1591         int fd;
1592
1593         assert(name);
1594         assert(s);
1595
1596         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1597         if (fd < 0)
1598                 return -errno;
1599
1600         make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1601                                     offsetof(struct kdbus_item, str) +
1602                                     strlen(name) + 1),
1603                              8);
1604
1605         n = make->items;
1606         strcpy(n->str, name);
1607         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1608         n->type = KDBUS_ITEM_MAKE_NAME;
1609
1610         make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1611         make->flags = KDBUS_MAKE_ACCESS_WORLD;
1612
1613         if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
1614                 safe_close(fd);
1615                 return -errno;
1616         }
1617
1618         /* The higher 32bit of the flags field are considered
1619          * 'incompatible flags'. Refuse them all for now. */
1620         if (make->flags > 0xFFFFFFFFULL) {
1621                 safe_close(fd);
1622                 return -ENOTSUP;
1623         }
1624
1625         if (s) {
1626                 char *p;
1627
1628                 p = strappend("/dev/kdbus/domain/", name);
1629                 if (!p) {
1630                         safe_close(fd);
1631                         return -ENOMEM;
1632                 }
1633
1634                 *s = p;
1635         }
1636
1637         return fd;
1638 }
1639
1640 int bus_kernel_try_close(sd_bus *bus) {
1641         assert(bus);
1642         assert(bus->is_kernel);
1643
1644         if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1645                 return -errno;
1646
1647         return 0;
1648 }
1649
1650 int bus_kernel_drop_one(int fd) {
1651         struct kdbus_cmd_recv recv = {
1652                 .flags = KDBUS_RECV_DROP
1653         };
1654
1655         assert(fd >= 0);
1656
1657         if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1658                 return -errno;
1659
1660         return 0;
1661 }