chiark / gitweb /
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PI...
[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_PIDS:
517
518                         /* The PID starttime/TID might be missing,
519                          * when the data is faked by some data bus
520                          * proxy and it lacks that information about
521                          * the real client since SO_PEERCRED is used
522                          * for that. */
523
524                         if (d->pids.pid > 0) {
525                                 m->creds.pid = (pid_t) d->pids.pid;
526                                 m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
527                         }
528
529                         if (d->pids.starttime > 0) {
530                                 m->creds.pid_starttime = d->pids.starttime / NSEC_PER_USEC;
531                                 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
532                         }
533
534                         if (d->pids.tid > 0) {
535                                 m->creds.tid = (pid_t) d->pids.tid;
536                                 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
537                         }
538
539                         break;
540
541                 case KDBUS_ITEM_CREDS:
542
543                         /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
544
545                         if ((uid_t) d->creds.uid != (uid_t) -1) {
546                                 m->creds.uid = (uid_t) d->creds.uid;
547                                 m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
548                         }
549
550                         if ((uid_t) d->creds.euid != (uid_t) -1) {
551                                 m->creds.euid = (uid_t) d->creds.euid;
552                                 m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
553                         }
554
555                         if ((uid_t) d->creds.suid != (uid_t) -1) {
556                                 m->creds.suid = (uid_t) d->creds.suid;
557                                 m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
558                         }
559
560                         if ((uid_t) d->creds.fsuid != (uid_t) -1) {
561                                 m->creds.fsuid = (uid_t) d->creds.fsuid;
562                                 m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
563                         }
564
565                         if ((gid_t) d->creds.gid != (gid_t) -1) {
566                                 m->creds.gid = (gid_t) d->creds.gid;
567                                 m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
568                         }
569
570                         if ((gid_t) d->creds.egid != (gid_t) -1) {
571                                 m->creds.egid = (gid_t) d->creds.egid;
572                                 m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
573                         }
574
575                         if ((gid_t) d->creds.sgid != (gid_t) -1) {
576                                 m->creds.sgid = (gid_t) d->creds.sgid;
577                                 m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
578                         }
579
580                         if ((gid_t) d->creds.fsgid != (gid_t) -1) {
581                                 m->creds.fsgid = (gid_t) d->creds.fsgid;
582                                 m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
583                         }
584
585                         break;
586
587                 case KDBUS_ITEM_TIMESTAMP:
588
589                         if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
590                                 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
591                                 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
592                                 m->seqnum = d->timestamp.seqnum;
593                         }
594
595                         break;
596
597                 case KDBUS_ITEM_PID_COMM:
598                         m->creds.comm = d->str;
599                         m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
600                         break;
601
602                 case KDBUS_ITEM_TID_COMM:
603                         m->creds.tid_comm = d->str;
604                         m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
605                         break;
606
607                 case KDBUS_ITEM_EXE:
608                         m->creds.exe = d->str;
609                         m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
610                         break;
611
612                 case KDBUS_ITEM_CMDLINE:
613                         m->creds.cmdline = d->str;
614                         m->creds.cmdline_size = l;
615                         m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
616                         break;
617
618                 case KDBUS_ITEM_CGROUP:
619                         m->creds.cgroup = d->str;
620                         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;
621
622                         r = bus_get_root_path(bus);
623                         if (r < 0)
624                                 goto fail;
625
626                         m->creds.cgroup_root = bus->cgroup_root;
627
628                         break;
629
630                 case KDBUS_ITEM_AUDIT:
631                         m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
632                         m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
633                         m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
634                         break;
635
636                 case KDBUS_ITEM_CAPS:
637                         m->creds.capability = (uint8_t *) d->caps.caps;
638                         m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps);
639                         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;
640                         break;
641
642                 case KDBUS_ITEM_DST_NAME:
643                         if (!service_name_is_valid(d->str))
644                                 return -EBADMSG;
645
646                         destination = d->str;
647                         break;
648
649                 case KDBUS_ITEM_OWNED_NAME:
650                         if (!service_name_is_valid(d->name.name))
651                                 return -EBADMSG;
652
653                         r = strv_extend(&m->creds.well_known_names, d->name.name);
654                         if (r < 0)
655                                 goto fail;
656                         break;
657
658                 case KDBUS_ITEM_CONN_DESCRIPTION:
659                         m->creds.description = d->str;
660                         m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
661                         break;
662
663                 case KDBUS_ITEM_FDS:
664                 case KDBUS_ITEM_SECLABEL:
665                         break;
666
667                 default:
668                         log_debug("Got unknown field from kernel %llu", d->type);
669                 }
670         }
671
672         r = bus_message_parse_fields(m);
673         if (r < 0)
674                 goto fail;
675
676         /* Override information from the user header with data from the kernel */
677         if (k->src_id == KDBUS_SRC_ID_KERNEL)
678                 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
679         else {
680                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
681                 m->sender = m->creds.unique_name = m->sender_buffer;
682         }
683
684         if (destination)
685                 m->destination = destination;
686         else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
687                 m->destination = NULL;
688         else if (k->dst_id == KDBUS_DST_ID_NAME)
689                 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
690         else {
691                 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
692                 m->destination = m->destination_buffer;
693         }
694
695         /* We take possession of the kmsg struct now */
696         m->kdbus = k;
697         m->release_kdbus = true;
698         m->free_fds = true;
699         fds = NULL;
700
701         bus->rqueue[bus->rqueue_size++] = m;
702
703         return 1;
704
705 fail:
706         unset_memfds(m);
707         sd_bus_message_unref(m);
708
709         return r;
710 }
711
712 int bus_kernel_take_fd(sd_bus *b) {
713         struct kdbus_cmd_hello *hello;
714         struct kdbus_item *item;
715         _cleanup_free_ char *g = NULL;
716         const char *name;
717         size_t l = 0, m = 0, sz;
718         int r;
719
720         assert(b);
721
722         if (b->is_server)
723                 return -EINVAL;
724
725         b->use_memfd = 1;
726
727         if (b->description) {
728                 g = bus_label_escape(b->description);
729                 if (!g)
730                         return -ENOMEM;
731
732                 name = g;
733         } else {
734                 char pr[17] = {};
735
736                 /* If no name is explicitly set, we'll include a hint
737                  * indicating the library implementation, a hint which
738                  * kind of bus this is and the thread name */
739
740                 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
741
742                 if (isempty(pr)) {
743                         name = b->is_system ? "sd-system" :
744                                 b->is_user ? "sd-user" : "sd";
745                 } else {
746                         _cleanup_free_ char *e = NULL;
747
748                         e = bus_label_escape(pr);
749                         if (!e)
750                                 return -ENOMEM;
751
752                         g = strappend(b->is_system ? "sd-system-" :
753                                       b->is_user ? "sd-user-" : "sd-",
754                                       e);
755                         if (!g)
756                                 return -ENOMEM;
757
758                         name = g;
759                 }
760
761                 b->description = bus_label_unescape(name);
762                 if (!b->description)
763                         return -ENOMEM;
764         }
765
766         m = strlen(name);
767
768         sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
769                 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
770
771         if (b->fake_creds_valid)
772                 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
773
774         if (b->fake_pids_valid)
775                 sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
776
777         if (b->fake_label) {
778                 l = strlen(b->fake_label);
779                 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
780         }
781
782         hello = alloca0_align(sz, 8);
783         hello->size = sz;
784         hello->flags = b->hello_flags;
785         hello->attach_flags_send = _KDBUS_ATTACH_ANY;
786         hello->attach_flags_recv = b->attach_flags;
787         hello->pool_size = KDBUS_POOL_SIZE;
788
789         item = hello->items;
790
791         item->size = offsetof(struct kdbus_item, str) + m + 1;
792         item->type = KDBUS_ITEM_CONN_DESCRIPTION;
793         memcpy(item->str, name, m + 1);
794         item = KDBUS_ITEM_NEXT(item);
795
796         if (b->fake_creds_valid) {
797                 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
798                 item->type = KDBUS_ITEM_CREDS;
799                 item->creds = b->fake_creds;
800
801                 item = KDBUS_ITEM_NEXT(item);
802         }
803
804         if (b->fake_pids_valid) {
805                 item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
806                 item->type = KDBUS_ITEM_PIDS;
807                 item->pids = b->fake_pids;
808
809                 item = KDBUS_ITEM_NEXT(item);
810         }
811
812         if (b->fake_label) {
813                 item->size = offsetof(struct kdbus_item, str) + l + 1;
814                 item->type = KDBUS_ITEM_SECLABEL;
815                 memcpy(item->str, b->fake_label, l+1);
816         }
817
818         r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
819         if (r < 0)
820                 return -errno;
821
822         if (!b->kdbus_buffer) {
823                 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
824                 if (b->kdbus_buffer == MAP_FAILED) {
825                         b->kdbus_buffer = NULL;
826                         return -errno;
827                 }
828         }
829
830         /* The higher 32bit of the bus_flags fields are considered
831          * 'incompatible flags'. Refuse them all for now. */
832         if (hello->bus_flags > 0xFFFFFFFFULL)
833                 return -ENOTSUP;
834
835         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
836                 return -ENOTSUP;
837
838         b->bloom_size = (size_t) hello->bloom.size;
839         b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
840
841         if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
842                 return -ENOMEM;
843
844         b->unique_id = hello->id;
845
846         b->is_kernel = true;
847         b->bus_client = true;
848         b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
849         b->message_version = 2;
850         b->message_endian = BUS_NATIVE_ENDIAN;
851
852         /* the kernel told us the UUID of the underlying bus */
853         memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
854
855         return bus_start_running(b);
856 }
857
858 int bus_kernel_connect(sd_bus *b) {
859         assert(b);
860         assert(b->input_fd < 0);
861         assert(b->output_fd < 0);
862         assert(b->kernel);
863
864         if (b->is_server)
865                 return -EINVAL;
866
867         b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
868         if (b->input_fd < 0)
869                 return -errno;
870
871         b->output_fd = b->input_fd;
872
873         return bus_kernel_take_fd(b);
874 }
875
876 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
877         struct kdbus_cmd_free cmd;
878         struct kdbus_item *d;
879
880         assert(bus);
881         assert(k);
882
883         cmd.flags = 0;
884         cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
885
886         KDBUS_ITEM_FOREACH(d, k, items) {
887
888                 if (d->type == KDBUS_ITEM_FDS)
889                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
890                 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
891                         safe_close(d->memfd.fd);
892         }
893
894         (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
895 }
896
897 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
898         int r;
899
900         assert(bus);
901         assert(m);
902         assert(bus->state == BUS_RUNNING);
903
904         /* If we can't deliver, we want room for the error message */
905         r = bus_rqueue_make_room(bus);
906         if (r < 0)
907                 return r;
908
909         r = bus_message_setup_kmsg(bus, m);
910         if (r < 0)
911                 return r;
912
913         /* If this is a synchronous method call, then let's tell the
914          * kernel, so that it can pass CPU time/scheduling to the
915          * destination for the time, if it wants to. If we
916          * synchronously wait for the result anyway, we won't need CPU
917          * anyway. */
918         if (hint_sync_call)
919                 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
920
921         r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
922         if (r < 0) {
923                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
924                 sd_bus_message *reply;
925
926                 if (errno == EAGAIN || errno == EINTR)
927                         return 0;
928                 else if (errno == ENXIO || errno == ESRCH) {
929
930                         /* ENXIO: unique name not known
931                          * ESRCH: well-known name not known */
932
933                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
934                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
935                         else {
936                                 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
937                                 return 0;
938                         }
939
940                 } else if (errno == EADDRNOTAVAIL) {
941
942                         /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
943
944                         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
945                                 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
946                         else {
947                                 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
948                                 return 0;
949                         }
950                 } else
951                         return -errno;
952
953                 r = bus_message_new_synthetic_error(
954                                 bus,
955                                 BUS_MESSAGE_COOKIE(m),
956                                 &error,
957                                 &reply);
958
959                 if (r < 0)
960                         return r;
961
962                 r = bus_seal_synthetic_message(bus, reply);
963                 if (r < 0)
964                         return r;
965
966                 bus->rqueue[bus->rqueue_size++] = reply;
967
968         } else if (hint_sync_call) {
969                 struct kdbus_msg *k;
970
971                 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
972                 assert(k);
973
974                 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
975
976                         r = bus_kernel_make_message(bus, k);
977                         if (r < 0) {
978                                 close_kdbus_msg(bus, k);
979
980                                 /* Anybody can send us invalid messages, let's just drop them. */
981                                 if (r == -EBADMSG || r == -EPROTOTYPE)
982                                         log_debug("Ignoring invalid message: %s", strerror(-r));
983                                 else
984                                         return r;
985                         }
986                 } else {
987                         log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
988                         close_kdbus_msg(bus, k);
989                 }
990         }
991
992         return 1;
993 }
994
995 static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
996         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
997         int r;
998
999         assert(bus);
1000
1001         r = sd_bus_message_new_signal(
1002                         bus,
1003                         &m,
1004                         "/org/freedesktop/DBus",
1005                         "org.freedesktop.DBus",
1006                         "NameOwnerChanged");
1007         if (r < 0)
1008                 return r;
1009
1010         r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
1011         if (r < 0)
1012                 return r;
1013
1014         m->sender = "org.freedesktop.DBus";
1015
1016         r = bus_seal_synthetic_message(bus, m);
1017         if (r < 0)
1018                 return r;
1019
1020         bus->rqueue[bus->rqueue_size++] = m;
1021         m = NULL;
1022
1023         return 1;
1024 }
1025
1026 static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1027         char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
1028
1029         assert(bus);
1030         assert(k);
1031         assert(d);
1032
1033         if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
1034                 old_owner[0] = 0;
1035         else
1036                 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
1037
1038         if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
1039
1040                 if (isempty(old_owner))
1041                         return 0;
1042
1043                 new_owner[0] = 0;
1044         } else
1045                 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
1046
1047         return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
1048 }
1049
1050 static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1051         char owner[UNIQUE_NAME_MAX];
1052
1053         assert(bus);
1054         assert(k);
1055         assert(d);
1056
1057         sprintf(owner, ":1.%llu", d->id_change.id);
1058
1059         return push_name_owner_changed(
1060                         bus, owner,
1061                         d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
1062                         d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
1063 }
1064
1065 static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
1066         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1067         int r;
1068
1069         assert(bus);
1070         assert(k);
1071         assert(d);
1072
1073         r = bus_message_new_synthetic_error(
1074                         bus,
1075                         k->cookie_reply,
1076                         d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
1077                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
1078                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1079                         &m);
1080         if (r < 0)
1081                 return r;
1082
1083         m->sender = "org.freedesktop.DBus";
1084
1085         r = bus_seal_synthetic_message(bus, m);
1086         if (r < 0)
1087                 return r;
1088
1089         bus->rqueue[bus->rqueue_size++] = m;
1090         m = NULL;
1091
1092         return 1;
1093 }
1094
1095 static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1096         struct kdbus_item *d, *found = NULL;
1097
1098         static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1099                 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1100                 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1101                 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1102
1103                 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1104                 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1105
1106                 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1107                 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1108         };
1109
1110         assert(bus);
1111         assert(k);
1112         assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1113
1114         KDBUS_ITEM_FOREACH(d, k, items) {
1115                 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1116                         if (found)
1117                                 return -EBADMSG;
1118                         found = d;
1119                 } else
1120                         log_debug("Got unknown field from kernel %llu", d->type);
1121         }
1122
1123         if (!found) {
1124                 log_debug("Didn't find a kernel message to translate.");
1125                 return 0;
1126         }
1127
1128         return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
1129 }
1130
1131 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1132         struct kdbus_cmd_recv recv = {};
1133         struct kdbus_msg *k;
1134         int r;
1135
1136         assert(bus);
1137
1138         r = bus_rqueue_make_room(bus);
1139         if (r < 0)
1140                 return r;
1141
1142         if (hint_priority) {
1143                 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1144                 recv.priority = priority;
1145         }
1146
1147         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
1148         if (r < 0) {
1149                 if (errno == EAGAIN)
1150                         return 0;
1151
1152                 return -errno;
1153         }
1154
1155         k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
1156         if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1157                 r = bus_kernel_make_message(bus, k);
1158
1159                 /* Anybody can send us invalid messages, let's just drop them. */
1160                 if (r == -EBADMSG || r == -EPROTOTYPE) {
1161                         log_debug("Ignoring invalid message: %s", strerror(-r));
1162                         r = 0;
1163                 }
1164
1165         } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
1166                 r = bus_kernel_translate_message(bus, k);
1167         else {
1168                 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
1169                 r = 0;
1170         }
1171
1172         if (r <= 0)
1173                 close_kdbus_msg(bus, k);
1174
1175         return r < 0 ? r : 1;
1176 }
1177
1178 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
1179         struct memfd_cache *c;
1180         int fd;
1181
1182         assert(address);
1183         assert(mapped);
1184         assert(allocated);
1185
1186         if (!bus || !bus->is_kernel)
1187                 return -ENOTSUP;
1188
1189         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1190
1191         if (bus->n_memfd_cache <= 0) {
1192                 int r;
1193
1194                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1195
1196                 r = memfd_new(bus->description);
1197                 if (r < 0)
1198                         return r;
1199
1200                 *address = NULL;
1201                 *mapped = 0;
1202                 *allocated = 0;
1203                 return r;
1204         }
1205
1206         c = &bus->memfd_cache[--bus->n_memfd_cache];
1207
1208         assert(c->fd >= 0);
1209         assert(c->mapped == 0 || c->address);
1210
1211         *address = c->address;
1212         *mapped = c->mapped;
1213         *allocated = c->allocated;
1214         fd = c->fd;
1215
1216         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1217
1218         return fd;
1219 }
1220
1221 static void close_and_munmap(int fd, void *address, size_t size) {
1222         if (size > 0)
1223                 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
1224
1225         safe_close(fd);
1226 }
1227
1228 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
1229         struct memfd_cache *c;
1230         uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
1231
1232         assert(fd >= 0);
1233         assert(mapped == 0 || address);
1234
1235         if (!bus || !bus->is_kernel) {
1236                 close_and_munmap(fd, address, mapped);
1237                 return;
1238         }
1239
1240         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
1241
1242         if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
1243                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1244
1245                 close_and_munmap(fd, address, mapped);
1246                 return;
1247         }
1248
1249         c = &bus->memfd_cache[bus->n_memfd_cache++];
1250         c->fd = fd;
1251         c->address = address;
1252
1253         /* If overly long, let's return a bit to the OS */
1254         if (mapped > max_mapped) {
1255                 assert_se(memfd_set_size(fd, max_mapped) >= 0);
1256                 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1257                 c->mapped = c->allocated = max_mapped;
1258         } else {
1259                 c->mapped = mapped;
1260                 c->allocated = allocated;
1261         }
1262
1263         assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
1264 }
1265
1266 void bus_kernel_flush_memfd(sd_bus *b) {
1267         unsigned i;
1268
1269         assert(b);
1270
1271         for (i = 0; i < b->n_memfd_cache; i++)
1272                 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
1273 }
1274
1275 int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1276         uint64_t f = 0;
1277
1278         assert(kdbus_flags);
1279
1280         if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1281                 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
1282
1283         if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1284                 f |= KDBUS_NAME_REPLACE_EXISTING;
1285
1286         if (flags & SD_BUS_NAME_QUEUE)
1287                 f |= KDBUS_NAME_QUEUE;
1288
1289         *kdbus_flags = f;
1290         return 0;
1291 }
1292
1293 int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1294         uint64_t m = 0;
1295
1296         assert(kdbus_mask);
1297
1298         if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
1299                     SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
1300                 m |= KDBUS_ATTACH_CREDS;
1301
1302         if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1303                 m |= KDBUS_ATTACH_PIDS;
1304
1305         if (mask & SD_BUS_CREDS_COMM)
1306                 m |= KDBUS_ATTACH_PID_COMM;
1307
1308         if (mask & SD_BUS_CREDS_TID_COMM)
1309                 m |= KDBUS_ATTACH_TID_COMM;
1310
1311         if (mask & SD_BUS_CREDS_EXE)
1312                 m |= KDBUS_ATTACH_EXE;
1313
1314         if (mask & SD_BUS_CREDS_CMDLINE)
1315                 m |= KDBUS_ATTACH_CMDLINE;
1316
1317         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))
1318                 m |= KDBUS_ATTACH_CGROUP;
1319
1320         if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1321                 m |= KDBUS_ATTACH_CAPS;
1322
1323         if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1324                 m |= KDBUS_ATTACH_SECLABEL;
1325
1326         if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1327                 m |= KDBUS_ATTACH_AUDIT;
1328
1329         if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1330                 m |= KDBUS_ATTACH_NAMES;
1331
1332         if (mask & SD_BUS_CREDS_DESCRIPTION)
1333                 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
1334
1335         *kdbus_mask = m;
1336         return 0;
1337 }
1338
1339 int bus_kernel_create_bus(const char *name, bool world, char **s) {
1340         struct kdbus_cmd_make *make;
1341         struct kdbus_item *n;
1342         int fd;
1343
1344         assert(name);
1345         assert(s);
1346
1347         fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1348         if (fd < 0)
1349                 return -errno;
1350
1351         make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1352                                     offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
1353                                     offsetof(struct kdbus_item, str) +
1354                                     DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
1355                              8);
1356
1357         make->size = offsetof(struct kdbus_cmd_make, items);
1358
1359         n = make->items;
1360         n->size = offsetof(struct kdbus_item, bloom_parameter) +
1361                   sizeof(struct kdbus_bloom_parameter);
1362         n->type = KDBUS_ITEM_BLOOM_PARAMETER;
1363
1364         n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1365         n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1366
1367         assert_cc(DEFAULT_BLOOM_SIZE > 0);
1368         assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1369
1370         make->size += ALIGN8(n->size);
1371
1372         n = KDBUS_ITEM_NEXT(n);
1373         sprintf(n->str, UID_FMT "-%s", getuid(), name);
1374         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1375         n->type = KDBUS_ITEM_MAKE_NAME;
1376         make->size += ALIGN8(n->size);
1377
1378         make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
1379
1380         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
1381                 safe_close(fd);
1382                 return -errno;
1383         }
1384
1385         if (s) {
1386                 char *p;
1387
1388                 p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
1389                 if (!p) {
1390                         safe_close(fd);
1391                         return -ENOMEM;
1392                 }
1393
1394                 *s = p;
1395         }
1396
1397         return fd;
1398 }
1399
1400 static int bus_kernel_translate_access(BusPolicyAccess access) {
1401         assert(access >= 0);
1402         assert(access < _BUS_POLICY_ACCESS_MAX);
1403
1404         switch (access) {
1405
1406         case BUS_POLICY_ACCESS_SEE:
1407                 return KDBUS_POLICY_SEE;
1408
1409         case BUS_POLICY_ACCESS_TALK:
1410                 return KDBUS_POLICY_TALK;
1411
1412         case BUS_POLICY_ACCESS_OWN:
1413                 return KDBUS_POLICY_OWN;
1414
1415         default:
1416                 assert_not_reached("Unknown policy access");
1417         }
1418 }
1419
1420 static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
1421         int r;
1422
1423         assert(policy);
1424         assert(item);
1425
1426         switch (policy->type) {
1427
1428         case BUSNAME_POLICY_TYPE_USER: {
1429                 const char *user = policy->name;
1430                 uid_t uid;
1431
1432                 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
1433                 if (r < 0)
1434                         return r;
1435
1436                 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1437                 item->policy_access.id = uid;
1438                 break;
1439         }
1440
1441         case BUSNAME_POLICY_TYPE_GROUP: {
1442                 const char *group = policy->name;
1443                 gid_t gid;
1444
1445                 r = get_group_creds(&group, &gid);
1446                 if (r < 0)
1447                         return r;
1448
1449                 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1450                 item->policy_access.id = gid;
1451                 break;
1452         }
1453
1454         default:
1455                 assert_not_reached("Unknown policy type");
1456         }
1457
1458         item->policy_access.access = bus_kernel_translate_access(policy->access);
1459
1460         return 0;
1461 }
1462
1463 int bus_kernel_open_bus_fd(const char *bus, char **path) {
1464         char *p;
1465         int fd;
1466         size_t len;
1467
1468         len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
1469
1470         if (path) {
1471                 p = malloc(len);
1472                 if (!p)
1473                         return -ENOMEM;
1474                 *path = p;
1475         } else
1476                 p = alloca(len);
1477         sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
1478
1479         fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1480         if (fd < 0)
1481                 return -errno;
1482
1483         return fd;
1484 }
1485
1486 int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
1487         _cleanup_free_ char *path = NULL;
1488         struct kdbus_cmd_make *make;
1489         struct kdbus_item *n;
1490         size_t size;
1491         int fd;
1492
1493         fd = bus_kernel_open_bus_fd(bus_name, &path);
1494         if (fd < 0)
1495                 return fd;
1496
1497         size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
1498         size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
1499
1500         make = alloca0_align(size, 8);
1501         make->size = size;
1502         make->flags = KDBUS_MAKE_ACCESS_WORLD;
1503
1504         n = make->items;
1505
1506         n->type = KDBUS_ITEM_MAKE_NAME;
1507         n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1;
1508         strcpy(n->str, ep_name);
1509
1510         if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
1511                 safe_close(fd);
1512                 return -errno;
1513         }
1514
1515         if (ep_path) {
1516                 char *p;
1517
1518                 p = strjoin(dirname(path), "/", ep_name, NULL);
1519                 if (!p) {
1520                         safe_close(fd);
1521                         return -ENOMEM;
1522                 }
1523
1524                 *ep_path = p;
1525         }
1526
1527         return fd;
1528 }
1529
1530 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
1531
1532         struct kdbus_cmd_update *update;
1533         struct kdbus_item *n;
1534         BusEndpointPolicy *po;
1535         Iterator i;
1536         size_t size;
1537         int r;
1538
1539         size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
1540
1541         HASHMAP_FOREACH(po, ep->policy_hash, i) {
1542                 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
1543                 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1544         }
1545
1546         update = alloca0_align(size, 8);
1547         update->size = size;
1548
1549         n = update->items;
1550
1551         HASHMAP_FOREACH(po, ep->policy_hash, i) {
1552                 n->type = KDBUS_ITEM_NAME;
1553                 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
1554                 strcpy(n->str, po->name);
1555                 n = KDBUS_ITEM_NEXT(n);
1556
1557                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1558                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1559
1560                 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1561                 n->policy_access.access = bus_kernel_translate_access(po->access);
1562                 n->policy_access.id = uid;
1563
1564                 n = KDBUS_ITEM_NEXT(n);
1565         }
1566
1567         r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
1568         if (r < 0)
1569                 return -errno;
1570
1571         return 0;
1572 }
1573
1574 int bus_kernel_make_starter(
1575                 int fd,
1576                 const char *name,
1577                 bool activating,
1578                 bool accept_fd,
1579                 BusNamePolicy *policy,
1580                 BusPolicyAccess world_policy) {
1581
1582         struct kdbus_cmd_hello *hello;
1583         struct kdbus_item *n;
1584         size_t policy_cnt = 0;
1585         BusNamePolicy *po;
1586         size_t size;
1587         int r;
1588
1589         assert(fd >= 0);
1590         assert(name);
1591
1592         LIST_FOREACH(policy, po, policy)
1593                 policy_cnt++;
1594
1595         if (world_policy >= 0)
1596                 policy_cnt++;
1597
1598         size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1599                ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1600                policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1601
1602         hello = alloca0_align(size, 8);
1603
1604         n = hello->items;
1605         strcpy(n->str, name);
1606         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1607         n->type = KDBUS_ITEM_NAME;
1608         n = KDBUS_ITEM_NEXT(n);
1609
1610         LIST_FOREACH(policy, po, policy) {
1611                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1612                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1613
1614                 r = bus_kernel_translate_policy(po, n);
1615                 if (r < 0)
1616                         return r;
1617
1618                 n = KDBUS_ITEM_NEXT(n);
1619         }
1620
1621         if (world_policy >= 0) {
1622                 n->type = KDBUS_ITEM_POLICY_ACCESS;
1623                 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1624                 n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1625                 n->policy_access.access = bus_kernel_translate_access(world_policy);
1626         }
1627
1628         hello->size = size;
1629         hello->flags =
1630                 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1631                 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
1632         hello->pool_size = KDBUS_POOL_SIZE;
1633         hello->attach_flags_send = _KDBUS_ATTACH_ANY;
1634         hello->attach_flags_recv = _KDBUS_ATTACH_ALL;
1635
1636         if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
1637                 return -errno;
1638
1639         /* The higher 32bit of the bus_flags fields are considered
1640          * 'incompatible flags'. Refuse them all for now. */
1641         if (hello->bus_flags > 0xFFFFFFFFULL)
1642                 return -ENOTSUP;
1643
1644         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
1645                 return -ENOTSUP;
1646
1647         return fd;
1648 }
1649
1650 int bus_kernel_try_close(sd_bus *bus) {
1651         assert(bus);
1652         assert(bus->is_kernel);
1653
1654         if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1655                 return -errno;
1656
1657         return 0;
1658 }
1659
1660 int bus_kernel_drop_one(int fd) {
1661         struct kdbus_cmd_recv recv = {
1662                 .flags = KDBUS_RECV_DROP
1663         };
1664
1665         assert(fd >= 0);
1666
1667         if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1668                 return -errno;
1669
1670         return 0;
1671 }