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