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