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