]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-kernel.c
e229baf2664f9d99e4b9e8cf3528d5e47850d0e8
[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 switch (policy->type) {
1345 case BUSNAME_POLICY_TYPE_USER:
1346 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1347 item->policy_access.id = policy->uid;
1348 break;
1349
1350 case BUSNAME_POLICY_TYPE_GROUP:
1351 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1352 item->policy_access.id = policy->gid;
1353 break;
1354
1355 case BUSNAME_POLICY_TYPE_WORLD:
1356 item->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1357 break;
1358
1359 default:
1360 assert_not_reached("Unknown policy type");
1361 }
1362
1363 switch (policy->access) {
1364 case BUSNAME_POLICY_ACCESS_SEE:
1365 item->policy_access.access = KDBUS_POLICY_SEE;
1366 break;
1367
1368 case BUSNAME_POLICY_ACCESS_TALK:
1369 item->policy_access.access = KDBUS_POLICY_TALK;
1370 break;
1371
1372 case BUSNAME_POLICY_ACCESS_OWN:
1373 item->policy_access.access = KDBUS_POLICY_OWN;
1374 break;
1375
1376 default:
1377 assert_not_reached("Unknown policy access");
1378 }
1379 }
1380
1381 int bus_kernel_create_starter(const char *bus, const char *name, BusNamePolicy *policy) {
1382 struct kdbus_cmd_hello *hello;
1383 struct kdbus_item *n;
1384 size_t policy_cnt = 0;
1385 BusNamePolicy *po;
1386 size_t size;
1387 char *p;
1388 int fd;
1389
1390 assert(bus);
1391 assert(name);
1392
1393 p = alloca(strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1);
1394 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1395
1396 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1397 if (fd < 0)
1398 return -errno;
1399
1400 LIST_FOREACH(policy, po, policy)
1401 policy_cnt++;
1402
1403 size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1404 ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1405 policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1406
1407 hello = alloca0(size);
1408
1409 n = hello->items;
1410 strcpy(n->str, name);
1411 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1412 n->type = KDBUS_ITEM_NAME;
1413 n = KDBUS_ITEM_NEXT(n);
1414
1415 LIST_FOREACH(policy, po, policy) {
1416 n->type = KDBUS_ITEM_POLICY_ACCESS;
1417 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1418 bus_kernel_translate_policy(po, n);
1419 n = KDBUS_ITEM_NEXT(n);
1420 }
1421
1422 hello->size = size;
1423 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1424 hello->pool_size = KDBUS_POOL_SIZE;
1425
1426 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1427 safe_close(fd);
1428 return -errno;
1429 }
1430
1431 /* The higher 32bit of both flags fields are considered
1432 * 'incompatible flags'. Refuse them all for now. */
1433 if (hello->bus_flags > 0xFFFFFFFFULL ||
1434 hello->conn_flags > 0xFFFFFFFFULL) {
1435 safe_close(fd);
1436 return -ENOTSUP;
1437 }
1438
1439 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash)) {
1440 safe_close(fd);
1441 return -ENOTSUP;
1442 }
1443
1444 return fd;
1445 }
1446
1447 int bus_kernel_create_domain(const char *name, char **s) {
1448 struct kdbus_cmd_make *make;
1449 struct kdbus_item *n;
1450 int fd;
1451
1452 assert(name);
1453 assert(s);
1454
1455 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1456 if (fd < 0)
1457 return -errno;
1458
1459 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1460 offsetof(struct kdbus_item, str) +
1461 strlen(name) + 1));
1462
1463 n = make->items;
1464 strcpy(n->str, name);
1465 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
1466 n->type = KDBUS_ITEM_MAKE_NAME;
1467
1468 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
1469 make->flags = KDBUS_MAKE_ACCESS_WORLD;
1470
1471 if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
1472 safe_close(fd);
1473 return -errno;
1474 }
1475
1476 /* The higher 32bit of the flags field are considered
1477 * 'incompatible flags'. Refuse them all for now. */
1478 if (make->flags > 0xFFFFFFFFULL) {
1479 safe_close(fd);
1480 return -ENOTSUP;
1481 }
1482
1483 if (s) {
1484 char *p;
1485
1486 p = strappend("/dev/kdbus/domain/", name);
1487 if (!p) {
1488 safe_close(fd);
1489 return -ENOMEM;
1490 }
1491
1492 *s = p;
1493 }
1494
1495 return fd;
1496 }
1497
1498 int bus_kernel_create_monitor(const char *bus) {
1499 struct kdbus_cmd_hello *hello;
1500 char *p;
1501 int fd;
1502
1503 assert(bus);
1504
1505 p = alloca(strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1);
1506 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1507
1508 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1509 if (fd < 0)
1510 return -errno;
1511
1512 hello = alloca0(sizeof(struct kdbus_cmd_hello));
1513 hello->size = sizeof(struct kdbus_cmd_hello);
1514 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1515 hello->pool_size = KDBUS_POOL_SIZE;
1516
1517 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
1518 safe_close(fd);
1519 return -errno;
1520 }
1521
1522 /* The higher 32bit of both flags fields are considered
1523 * 'incompatible flags'. Refuse them all for now. */
1524 if (hello->bus_flags > 0xFFFFFFFFULL ||
1525 hello->conn_flags > 0xFFFFFFFFULL) {
1526 safe_close(fd);
1527 return -ENOTSUP;
1528 }
1529
1530 return fd;
1531 }
1532
1533 int bus_kernel_try_close(sd_bus *bus) {
1534 assert(bus);
1535 assert(bus->is_kernel);
1536
1537 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1538 return -errno;
1539
1540 return 0;
1541 }
1542
1543 int bus_kernel_drop_one(int fd) {
1544 struct kdbus_cmd_recv recv = {
1545 .flags = KDBUS_RECV_DROP
1546 };
1547
1548 assert(fd >= 0);
1549
1550 if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1551 return -errno;
1552
1553 return 0;
1554 }