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