1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
29 #include <sys/prctl.h>
31 /* When we include libgen.h because we need dirname() we immediately
32 * undefine basename() since libgen.h defines it as a macro to the POSIX
33 * version which is really broken. We prefer GNU basename(). */
37 #include "alloc-util.h"
38 #include "bus-bloom.h"
39 #include "bus-internal.h"
40 #include "bus-kernel.h"
41 #include "bus-label.h"
42 #include "bus-message.h"
44 #include "capability-util.h"
47 #include "formats-util.h"
48 #include "memfd-util.h"
49 #include "parse-util.h"
50 #include "string-util.h"
52 #include "user-util.h"
55 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
57 int bus_kernel_parse_unique_name(const char *s
, uint64_t *id
) {
63 if (!startswith(s
, ":1."))
66 r
= safe_atou64(s
+ 3, id
);
73 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
79 /* Note that p can be NULL, which encodes a region full of
80 * zeroes, which is useful to optimize certain padding
83 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
84 (*d
)->type
= KDBUS_ITEM_PAYLOAD_VEC
;
85 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
88 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
91 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t start
, size_t sz
) {
97 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
98 (*d
)->type
= KDBUS_ITEM_PAYLOAD_MEMFD
;
99 (*d
)->memfd
.fd
= memfd
;
100 (*d
)->memfd
.start
= start
;
101 (*d
)->memfd
.size
= sz
;
103 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
106 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
112 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
113 (*d
)->type
= KDBUS_ITEM_DST_NAME
;
114 memcpy((*d
)->str
, s
, length
+ 1);
116 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
119 static struct kdbus_bloom_filter
*append_bloom(struct kdbus_item
**d
, size_t length
) {
120 struct kdbus_item
*i
;
126 i
->size
= offsetof(struct kdbus_item
, bloom_filter
) +
127 offsetof(struct kdbus_bloom_filter
, data
) +
129 i
->type
= KDBUS_ITEM_BLOOM_FILTER
;
131 *d
= (struct kdbus_item
*) ((uint8_t*) i
+ i
->size
);
133 return &i
->bloom_filter
;
136 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
142 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
143 (*d
)->type
= KDBUS_ITEM_FDS
;
144 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
146 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
149 static void add_bloom_arg(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
150 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
158 e
= stpcpy(buf
, "arg");
160 *(e
++) = '0' + (char) i
;
162 *(e
++) = '0' + (char) (i
/ 10);
163 *(e
++) = '0' + (char) (i
% 10);
167 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
169 strcpy(e
, "-dot-prefix");
170 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '.');
171 strcpy(e
, "-slash-prefix");
172 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '/');
175 static void add_bloom_arg_has(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
176 char buf
[sizeof("arg")-1 + 2 + sizeof("-has")];
184 e
= stpcpy(buf
, "arg");
186 *(e
++) = '0' + (char) i
;
188 *(e
++) = '0' + (char) (i
/ 10);
189 *(e
++) = '0' + (char) (i
% 10);
193 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
196 static int bus_message_setup_bloom(sd_bus_message
*m
, struct kdbus_bloom_filter
*bloom
) {
205 memzero(data
, m
->bus
->bloom_size
);
206 bloom
->generation
= 0;
208 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "message-type", bus_message_type_to_string(m
->header
->type
));
211 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "interface", m
->interface
);
213 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "member", m
->member
);
215 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path", m
->path
);
216 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
);
217 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
, '/');
220 r
= sd_bus_message_rewind(m
, true);
224 for (i
= 0; i
< 64; i
++) {
225 const char *t
, *contents
;
228 r
= sd_bus_message_peek_type(m
, &type
, &contents
);
232 if (IN_SET(type
, SD_BUS_TYPE_STRING
, SD_BUS_TYPE_OBJECT_PATH
, SD_BUS_TYPE_SIGNATURE
)) {
234 /* The bloom filter includes simple strings of any kind */
235 r
= sd_bus_message_read_basic(m
, type
, &t
);
239 add_bloom_arg(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
242 if (type
== SD_BUS_TYPE_ARRAY
&& STR_IN_SET(contents
, "s", "o", "g")) {
244 /* As well as array of simple strings of any kinds */
245 r
= sd_bus_message_enter_container(m
, type
, contents
);
249 while ((r
= sd_bus_message_read_basic(m
, contents
[0], &t
)) > 0)
250 add_bloom_arg_has(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
254 r
= sd_bus_message_exit_container(m
);
259 /* Stop adding to bloom filter as soon as we
260 * run into the first argument we cannot add
268 static int bus_message_setup_kmsg(sd_bus
*b
, sd_bus_message
*m
) {
269 struct bus_body_part
*part
;
270 struct kdbus_item
*d
;
271 const char *destination
;
282 /* We put this together only once, if this message is reused
283 * we reuse the earlier-built version */
287 destination
= m
->destination
?: m
->destination_ptr
;
290 r
= bus_kernel_parse_unique_name(destination
, &unique
);
298 sz
= offsetof(struct kdbus_msg
, items
);
300 /* Add in fixed header, fields header and payload */
301 sz
+= (1 + m
->n_body_parts
) * ALIGN8(offsetof(struct kdbus_item
, vec
) +
302 MAX(sizeof(struct kdbus_vec
),
303 sizeof(struct kdbus_memfd
)));
305 /* Add space for bloom filter */
306 sz
+= ALIGN8(offsetof(struct kdbus_item
, bloom_filter
) +
307 offsetof(struct kdbus_bloom_filter
, data
) +
310 /* Add in well-known destination header */
312 dl
= strlen(destination
);
313 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
316 /* Add space for unix fds */
318 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
320 m
->kdbus
= memalign(8, sz
);
326 m
->free_kdbus
= true;
327 memzero(m
->kdbus
, sz
);
330 ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_EXPECT_REPLY
) |
331 ((m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_NO_AUTO_START
: 0) |
332 ((m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) ? KDBUS_MSG_SIGNAL
: 0);
335 /* verify_destination_id will usually be 0, which makes the kernel driver only look
336 * at the provided well-known name. Otherwise, the kernel will make sure the provided
337 * destination id matches the owner of the provided weel-known-name, and fail if they
338 * differ. Currently, this is only needed for bus-proxyd. */
339 m
->kdbus
->dst_id
= m
->verify_destination_id
;
341 m
->kdbus
->dst_id
= destination
? unique
: KDBUS_DST_ID_BROADCAST
;
343 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS
;
344 m
->kdbus
->cookie
= m
->header
->dbus2
.cookie
;
345 m
->kdbus
->priority
= m
->priority
;
347 if (m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
)
348 m
->kdbus
->cookie_reply
= m
->reply_cookie
;
352 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE
, &now
) == 0);
353 m
->kdbus
->timeout_ns
= now
.tv_sec
* NSEC_PER_SEC
+ now
.tv_nsec
+
354 m
->timeout
* NSEC_PER_USEC
;
360 append_destination(&d
, destination
, dl
);
362 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
364 MESSAGE_FOREACH_PART(part
, i
, m
) {
366 /* If this is padding then simply send a
367 * vector with a NULL data pointer which the
368 * kernel will just pass through. This is the
369 * most efficient way to encode zeroes */
371 append_payload_vec(&d
, NULL
, part
->size
);
375 if (part
->memfd
>= 0 && part
->sealed
&& destination
) {
376 /* Try to send a memfd, if the part is
377 * sealed and this is not a broadcast. Since we can only */
379 append_payload_memfd(&d
, part
->memfd
, part
->memfd_offset
, part
->size
);
383 /* Otherwise, let's send a vector to the actual data.
384 * For that, we need to map it first. */
385 r
= bus_body_part_map(part
);
389 append_payload_vec(&d
, part
->data
, part
->size
);
392 if (m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) {
393 struct kdbus_bloom_filter
*bloom
;
395 bloom
= append_bloom(&d
, m
->bus
->bloom_size
);
396 r
= bus_message_setup_bloom(m
, bloom
);
402 append_fds(&d
, m
->fds
, m
->n_fds
);
404 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
405 assert(m
->kdbus
->size
<= sz
);
414 static void unset_memfds(struct sd_bus_message
*m
) {
415 struct bus_body_part
*part
;
420 /* Make sure the memfds are not freed twice */
421 MESSAGE_FOREACH_PART(part
, i
, m
)
422 if (part
->memfd
>= 0)
426 static void message_set_timestamp(sd_bus
*bus
, sd_bus_message
*m
, const struct kdbus_timestamp
*ts
) {
433 if (!(bus
->attach_flags
& KDBUS_ATTACH_TIMESTAMP
))
436 m
->realtime
= ts
->realtime_ns
/ NSEC_PER_USEC
;
437 m
->monotonic
= ts
->monotonic_ns
/ NSEC_PER_USEC
;
438 m
->seqnum
= ts
->seqnum
;
441 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
442 sd_bus_message
*m
= NULL
;
443 struct kdbus_item
*d
;
445 _cleanup_free_
int *fds
= NULL
;
446 struct bus_header
*header
= NULL
;
448 size_t header_size
= 0, footer_size
= 0;
449 size_t n_bytes
= 0, idx
= 0;
450 const char *destination
= NULL
, *seclabel
= NULL
;
451 bool last_was_memfd
= false;
456 assert(k
->payload_type
== KDBUS_PAYLOAD_DBUS
);
458 KDBUS_ITEM_FOREACH(d
, k
, items
) {
461 l
= d
->size
- offsetof(struct kdbus_item
, data
);
465 case KDBUS_ITEM_PAYLOAD_OFF
:
467 header
= (struct bus_header
*)((uint8_t*) k
+ d
->vec
.offset
);
468 header_size
= d
->vec
.size
;
471 footer
= (uint8_t*) k
+ d
->vec
.offset
;
472 footer_size
= d
->vec
.size
;
474 n_bytes
+= d
->vec
.size
;
475 last_was_memfd
= false;
478 case KDBUS_ITEM_PAYLOAD_MEMFD
:
479 if (!header
) /* memfd cannot be first part */
482 n_bytes
+= d
->memfd
.size
;
483 last_was_memfd
= true;
486 case KDBUS_ITEM_FDS
: {
491 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
496 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
501 case KDBUS_ITEM_SECLABEL
:
507 if (last_was_memfd
) /* memfd cannot be last part */
513 if (header_size
< sizeof(struct bus_header
))
516 /* on kdbus we only speak native endian gvariant, never dbus1
517 * marshalling or reverse endian */
518 if (header
->version
!= 2 ||
519 header
->endian
!= BUS_NATIVE_ENDIAN
)
522 r
= bus_message_from_header(
532 /* The well-known names list is different from the other
533 credentials. If we asked for it, but nothing is there, this
534 means that the list of well-known names is simply empty, not
535 that we lack any data */
537 m
->creds
.mask
|= (SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
) & bus
->creds_mask
;
539 KDBUS_ITEM_FOREACH(d
, k
, items
) {
542 l
= d
->size
- offsetof(struct kdbus_item
, data
);
546 case KDBUS_ITEM_PAYLOAD_OFF
: {
549 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
551 if (idx
+ d
->vec
.size
> begin_body
) {
552 struct bus_body_part
*part
;
554 /* Contains body material */
556 part
= message_append_part(m
);
562 /* A -1 offset is NUL padding. */
563 part
->is_zero
= d
->vec
.offset
== ~0ULL;
565 if (idx
>= begin_body
) {
567 part
->data
= (uint8_t* )k
+ d
->vec
.offset
;
568 part
->size
= d
->vec
.size
;
571 part
->data
= (uint8_t*) k
+ d
->vec
.offset
+ (begin_body
- idx
);
572 part
->size
= d
->vec
.size
- (begin_body
- idx
);
582 case KDBUS_ITEM_PAYLOAD_MEMFD
: {
583 struct bus_body_part
*part
;
585 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
590 part
= message_append_part(m
);
596 part
->memfd
= d
->memfd
.fd
;
597 part
->memfd_offset
= d
->memfd
.start
;
598 part
->size
= d
->memfd
.size
;
601 idx
+= d
->memfd
.size
;
605 case KDBUS_ITEM_PIDS
:
607 /* The PID/TID might be missing, when the data
608 * is faked by a bus proxy and it lacks that
609 * information about the real client (since
610 * SO_PEERCRED is used for that). Also kernel
611 * namespacing might make some of this data
612 * unavailable when untranslatable. */
614 if (d
->pids
.pid
> 0) {
615 m
->creds
.pid
= (pid_t
) d
->pids
.pid
;
616 m
->creds
.mask
|= SD_BUS_CREDS_PID
& bus
->creds_mask
;
619 if (d
->pids
.tid
> 0) {
620 m
->creds
.tid
= (pid_t
) d
->pids
.tid
;
621 m
->creds
.mask
|= SD_BUS_CREDS_TID
& bus
->creds_mask
;
624 if (d
->pids
.ppid
> 0) {
625 m
->creds
.ppid
= (pid_t
) d
->pids
.ppid
;
626 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
627 } else if (d
->pids
.pid
== 1) {
629 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
634 case KDBUS_ITEM_CREDS
:
636 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
637 * missing too (see above). */
639 if ((uid_t
) d
->creds
.uid
!= UID_INVALID
) {
640 m
->creds
.uid
= (uid_t
) d
->creds
.uid
;
641 m
->creds
.mask
|= SD_BUS_CREDS_UID
& bus
->creds_mask
;
644 if ((uid_t
) d
->creds
.euid
!= UID_INVALID
) {
645 m
->creds
.euid
= (uid_t
) d
->creds
.euid
;
646 m
->creds
.mask
|= SD_BUS_CREDS_EUID
& bus
->creds_mask
;
649 if ((uid_t
) d
->creds
.suid
!= UID_INVALID
) {
650 m
->creds
.suid
= (uid_t
) d
->creds
.suid
;
651 m
->creds
.mask
|= SD_BUS_CREDS_SUID
& bus
->creds_mask
;
654 if ((uid_t
) d
->creds
.fsuid
!= UID_INVALID
) {
655 m
->creds
.fsuid
= (uid_t
) d
->creds
.fsuid
;
656 m
->creds
.mask
|= SD_BUS_CREDS_FSUID
& bus
->creds_mask
;
659 if ((gid_t
) d
->creds
.gid
!= GID_INVALID
) {
660 m
->creds
.gid
= (gid_t
) d
->creds
.gid
;
661 m
->creds
.mask
|= SD_BUS_CREDS_GID
& bus
->creds_mask
;
664 if ((gid_t
) d
->creds
.egid
!= GID_INVALID
) {
665 m
->creds
.egid
= (gid_t
) d
->creds
.egid
;
666 m
->creds
.mask
|= SD_BUS_CREDS_EGID
& bus
->creds_mask
;
669 if ((gid_t
) d
->creds
.sgid
!= GID_INVALID
) {
670 m
->creds
.sgid
= (gid_t
) d
->creds
.sgid
;
671 m
->creds
.mask
|= SD_BUS_CREDS_SGID
& bus
->creds_mask
;
674 if ((gid_t
) d
->creds
.fsgid
!= GID_INVALID
) {
675 m
->creds
.fsgid
= (gid_t
) d
->creds
.fsgid
;
676 m
->creds
.mask
|= SD_BUS_CREDS_FSGID
& bus
->creds_mask
;
681 case KDBUS_ITEM_TIMESTAMP
:
682 message_set_timestamp(bus
, m
, &d
->timestamp
);
685 case KDBUS_ITEM_PID_COMM
:
686 m
->creds
.comm
= d
->str
;
687 m
->creds
.mask
|= SD_BUS_CREDS_COMM
& bus
->creds_mask
;
690 case KDBUS_ITEM_TID_COMM
:
691 m
->creds
.tid_comm
= d
->str
;
692 m
->creds
.mask
|= SD_BUS_CREDS_TID_COMM
& bus
->creds_mask
;
696 m
->creds
.exe
= d
->str
;
697 m
->creds
.mask
|= SD_BUS_CREDS_EXE
& bus
->creds_mask
;
700 case KDBUS_ITEM_CMDLINE
:
701 m
->creds
.cmdline
= d
->str
;
702 m
->creds
.cmdline_size
= l
;
703 m
->creds
.mask
|= SD_BUS_CREDS_CMDLINE
& bus
->creds_mask
;
706 case KDBUS_ITEM_CGROUP
:
707 m
->creds
.cgroup
= d
->str
;
708 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
;
710 r
= bus_get_root_path(bus
);
714 m
->creds
.cgroup_root
= bus
->cgroup_root
;
717 case KDBUS_ITEM_AUDIT
:
718 m
->creds
.audit_session_id
= (uint32_t) d
->audit
.sessionid
;
719 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
& bus
->creds_mask
;
721 m
->creds
.audit_login_uid
= (uid_t
) d
->audit
.loginuid
;
722 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
& bus
->creds_mask
;
725 case KDBUS_ITEM_CAPS
:
726 if (d
->caps
.last_cap
!= cap_last_cap() ||
727 d
->size
- offsetof(struct kdbus_item
, caps
.caps
) < DIV_ROUND_UP(d
->caps
.last_cap
, 32U) * 4 * 4) {
732 m
->creds
.capability
= d
->caps
.caps
;
733 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
;
736 case KDBUS_ITEM_DST_NAME
:
737 if (!service_name_is_valid(d
->str
)) {
742 destination
= d
->str
;
745 case KDBUS_ITEM_OWNED_NAME
:
746 if (!service_name_is_valid(d
->name
.name
)) {
751 if (bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
755 /* We just extend the array here, but
756 * do not allocate the strings inside
757 * of it, instead we just point to our
758 * buffer directly. */
759 n
= strv_length(m
->creds
.well_known_names
);
760 wkn
= realloc(m
->creds
.well_known_names
, (n
+ 2) * sizeof(char*));
766 wkn
[n
] = d
->name
.name
;
768 m
->creds
.well_known_names
= wkn
;
770 m
->creds
.mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
774 case KDBUS_ITEM_CONN_DESCRIPTION
:
775 m
->creds
.description
= d
->str
;
776 m
->creds
.mask
|= SD_BUS_CREDS_DESCRIPTION
& bus
->creds_mask
;
779 case KDBUS_ITEM_AUXGROUPS
:
781 if (bus
->creds_mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
785 n
= (d
->size
- offsetof(struct kdbus_item
, data64
)) / sizeof(uint64_t);
792 for (i
= 0; i
< n
; i
++)
795 m
->creds
.supplementary_gids
= g
;
796 m
->creds
.n_supplementary_gids
= n
;
797 m
->creds
.mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
803 case KDBUS_ITEM_SECLABEL
:
804 case KDBUS_ITEM_BLOOM_FILTER
:
808 log_debug("Got unknown field from kernel %llu", d
->type
);
812 /* If we requested the list of well-known names to be appended
813 * and the sender had none no item for it will be
814 * attached. However, this does *not* mean that the kernel
815 * didn't want to provide this information to us. Hence, let's
816 * explicitly mark this information as available if it was
818 m
->creds
.mask
|= bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
;
820 r
= bus_message_parse_fields(m
);
824 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
825 if ((uint64_t) m
->header
->dbus2
.cookie
!= k
->cookie
) {
830 /* Refuse messages where the reply flag doesn't match up */
831 if (!(m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) != !!(k
->flags
& KDBUS_MSG_EXPECT_REPLY
)) {
836 /* Refuse reply messages where the reply cookie doesn't match up */
837 if ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) && m
->reply_cookie
!= k
->cookie_reply
) {
842 /* Refuse messages where the autostart flag doesn't match up */
843 if (!(m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) != !(k
->flags
& KDBUS_MSG_NO_AUTO_START
)) {
848 /* Override information from the user header with data from the kernel */
849 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
850 bus_message_set_sender_driver(bus
, m
);
852 snprintf(m
->sender_buffer
, sizeof(m
->sender_buffer
), ":1.%llu", (unsigned long long) k
->src_id
);
853 m
->sender
= m
->creds
.unique_name
= m
->sender_buffer
;
857 m
->destination
= destination
;
858 else if (k
->dst_id
== KDBUS_DST_ID_BROADCAST
)
859 m
->destination
= NULL
;
860 else if (k
->dst_id
== KDBUS_DST_ID_NAME
)
861 m
->destination
= bus
->unique_name
; /* fill in unique name if the well-known name is missing */
863 snprintf(m
->destination_buffer
, sizeof(m
->destination_buffer
), ":1.%llu", (unsigned long long) k
->dst_id
);
864 m
->destination
= m
->destination_buffer
;
867 /* We take possession of the kmsg struct now */
869 m
->release_kdbus
= true;
873 bus
->rqueue
[bus
->rqueue_size
++] = m
;
879 sd_bus_message_unref(m
);
884 int bus_kernel_take_fd(sd_bus
*b
) {
885 struct kdbus_bloom_parameter
*bloom
= NULL
;
886 struct kdbus_item
*items
, *item
;
887 struct kdbus_cmd_hello
*hello
;
888 _cleanup_free_
char *g
= NULL
;
890 size_t l
= 0, m
= 0, sz
;
900 if (b
->description
) {
901 g
= bus_label_escape(b
->description
);
909 /* If no name is explicitly set, we'll include a hint
910 * indicating the library implementation, a hint which
911 * kind of bus this is and the thread name */
913 assert_se(prctl(PR_GET_NAME
, (unsigned long) pr
) >= 0);
916 name
= b
->is_system
? "sd-system" :
917 b
->is_user
? "sd-user" : "sd";
919 _cleanup_free_
char *e
= NULL
;
921 e
= bus_label_escape(pr
);
925 g
= strappend(b
->is_system
? "sd-system-" :
926 b
->is_user
? "sd-user-" : "sd-",
934 b
->description
= bus_label_unescape(name
);
941 sz
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
)) +
942 ALIGN8(offsetof(struct kdbus_item
, str
) + m
+ 1);
944 if (b
->fake_creds_valid
)
945 sz
+= ALIGN8(offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
));
947 if (b
->fake_pids_valid
)
948 sz
+= ALIGN8(offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
));
951 l
= strlen(b
->fake_label
);
952 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + l
+ 1);
955 hello
= alloca0_align(sz
, 8);
957 hello
->flags
= b
->hello_flags
;
958 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
959 hello
->attach_flags_recv
= b
->attach_flags
;
960 hello
->pool_size
= KDBUS_POOL_SIZE
;
964 item
->size
= offsetof(struct kdbus_item
, str
) + m
+ 1;
965 item
->type
= KDBUS_ITEM_CONN_DESCRIPTION
;
966 memcpy(item
->str
, name
, m
+ 1);
967 item
= KDBUS_ITEM_NEXT(item
);
969 if (b
->fake_creds_valid
) {
970 item
->size
= offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
);
971 item
->type
= KDBUS_ITEM_CREDS
;
972 item
->creds
= b
->fake_creds
;
974 item
= KDBUS_ITEM_NEXT(item
);
977 if (b
->fake_pids_valid
) {
978 item
->size
= offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
);
979 item
->type
= KDBUS_ITEM_PIDS
;
980 item
->pids
= b
->fake_pids
;
982 item
= KDBUS_ITEM_NEXT(item
);
986 item
->size
= offsetof(struct kdbus_item
, str
) + l
+ 1;
987 item
->type
= KDBUS_ITEM_SECLABEL
;
988 memcpy(item
->str
, b
->fake_label
, l
+1);
991 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
994 /* If the ioctl is not supported we assume that the
995 * API version changed in a major incompatible way,
996 * let's indicate an API incompatibility in this
998 return -ESOCKTNOSUPPORT
;
1003 if (!b
->kdbus_buffer
) {
1004 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
, MAP_SHARED
, b
->input_fd
, 0);
1005 if (b
->kdbus_buffer
== MAP_FAILED
) {
1006 b
->kdbus_buffer
= NULL
;
1012 /* The higher 32bit of the bus_flags fields are considered
1013 * 'incompatible flags'. Refuse them all for now. */
1014 if (hello
->bus_flags
> 0xFFFFFFFFULL
) {
1015 r
= -ESOCKTNOSUPPORT
;
1019 /* extract bloom parameters from items */
1020 items
= (void*)((uint8_t*)b
->kdbus_buffer
+ hello
->offset
);
1021 KDBUS_FOREACH(item
, items
, hello
->items_size
) {
1022 switch (item
->type
) {
1023 case KDBUS_ITEM_BLOOM_PARAMETER
:
1024 bloom
= &item
->bloom_parameter
;
1029 if (!bloom
|| !bloom_validate_parameters((size_t) bloom
->size
, (unsigned) bloom
->n_hash
)) {
1034 b
->bloom_size
= (size_t) bloom
->size
;
1035 b
->bloom_n_hash
= (unsigned) bloom
->n_hash
;
1037 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0) {
1042 b
->unique_id
= hello
->id
;
1044 b
->is_kernel
= true;
1045 b
->bus_client
= true;
1046 b
->can_fds
= !!(hello
->flags
& KDBUS_HELLO_ACCEPT_FD
);
1047 b
->message_version
= 2;
1048 b
->message_endian
= BUS_NATIVE_ENDIAN
;
1050 /* the kernel told us the UUID of the underlying bus */
1051 memcpy(b
->server_id
.bytes
, hello
->id128
, sizeof(b
->server_id
.bytes
));
1053 /* free returned items */
1054 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1055 return bus_start_running(b
);
1058 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1062 int bus_kernel_connect(sd_bus
*b
) {
1064 assert(b
->input_fd
< 0);
1065 assert(b
->output_fd
< 0);
1071 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1072 if (b
->input_fd
< 0)
1075 b
->output_fd
= b
->input_fd
;
1077 return bus_kernel_take_fd(b
);
1080 int bus_kernel_cmd_free(sd_bus
*bus
, uint64_t offset
) {
1081 struct kdbus_cmd_free cmd
= {
1082 .size
= sizeof(cmd
),
1088 assert(bus
->is_kernel
);
1090 r
= ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &cmd
);
1097 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
1098 struct kdbus_item
*d
;
1103 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1104 if (d
->type
== KDBUS_ITEM_FDS
)
1105 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
1106 else if (d
->type
== KDBUS_ITEM_PAYLOAD_MEMFD
)
1107 safe_close(d
->memfd
.fd
);
1110 bus_kernel_cmd_free(bus
, (uint8_t*) k
- (uint8_t*) bus
->kdbus_buffer
);
1113 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
, bool hint_sync_call
) {
1114 struct kdbus_cmd_send cmd
= { };
1119 assert(bus
->state
== BUS_RUNNING
);
1121 /* If we can't deliver, we want room for the error message */
1122 r
= bus_rqueue_make_room(bus
);
1126 r
= bus_message_setup_kmsg(bus
, m
);
1130 cmd
.size
= sizeof(cmd
);
1131 cmd
.msg_address
= (uintptr_t)m
->kdbus
;
1133 /* If this is a synchronous method call, then let's tell the
1134 * kernel, so that it can pass CPU time/scheduling to the
1135 * destination for the time, if it wants to. If we
1136 * synchronously wait for the result anyway, we won't need CPU
1138 if (hint_sync_call
) {
1139 m
->kdbus
->flags
|= KDBUS_MSG_EXPECT_REPLY
;
1140 cmd
.flags
|= KDBUS_SEND_SYNC_REPLY
;
1143 r
= ioctl(bus
->output_fd
, KDBUS_CMD_SEND
, &cmd
);
1145 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1146 sd_bus_message
*reply
;
1148 if (errno
== EAGAIN
|| errno
== EINTR
)
1150 else if (errno
== ENXIO
|| errno
== ESRCH
) {
1152 /* ENXIO: unique name not known
1153 * ESRCH: well-known name not known */
1155 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1156 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Destination %s not known", m
->destination
);
1158 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m
->destination
);
1162 } else if (errno
== EADDRNOTAVAIL
) {
1164 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1166 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1167 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Activation of %s not requested", m
->destination
);
1169 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m
->destination
);
1175 r
= bus_message_new_synthetic_error(
1177 BUS_MESSAGE_COOKIE(m
),
1184 r
= bus_seal_synthetic_message(bus
, reply
);
1188 bus
->rqueue
[bus
->rqueue_size
++] = reply
;
1190 } else if (hint_sync_call
) {
1191 struct kdbus_msg
*k
;
1193 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ cmd
.reply
.offset
);
1196 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1198 r
= bus_kernel_make_message(bus
, k
);
1200 close_kdbus_msg(bus
, k
);
1202 /* Anybody can send us invalid messages, let's just drop them. */
1203 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
)
1204 log_debug_errno(r
, "Ignoring invalid synchronous reply: %m");
1209 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1210 close_kdbus_msg(bus
, k
);
1217 static int push_name_owner_changed(
1220 const char *old_owner
,
1221 const char *new_owner
,
1222 const struct kdbus_timestamp
*ts
) {
1224 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1229 r
= sd_bus_message_new_signal(
1232 "/org/freedesktop/DBus",
1233 "org.freedesktop.DBus",
1234 "NameOwnerChanged");
1238 r
= sd_bus_message_append(m
, "sss", name
, old_owner
, new_owner
);
1242 bus_message_set_sender_driver(bus
, m
);
1243 message_set_timestamp(bus
, m
, ts
);
1245 r
= bus_seal_synthetic_message(bus
, m
);
1249 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1255 static int translate_name_change(
1257 const struct kdbus_msg
*k
,
1258 const struct kdbus_item
*d
,
1259 const struct kdbus_timestamp
*ts
) {
1261 char new_owner
[UNIQUE_NAME_MAX
], old_owner
[UNIQUE_NAME_MAX
];
1267 if (d
->type
== KDBUS_ITEM_NAME_ADD
|| (d
->name_change
.old_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
)))
1270 sprintf(old_owner
, ":1.%llu", (unsigned long long) d
->name_change
.old_id
.id
);
1272 if (d
->type
== KDBUS_ITEM_NAME_REMOVE
|| (d
->name_change
.new_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
))) {
1274 if (isempty(old_owner
))
1279 sprintf(new_owner
, ":1.%llu", (unsigned long long) d
->name_change
.new_id
.id
);
1281 return push_name_owner_changed(bus
, d
->name_change
.name
, old_owner
, new_owner
, ts
);
1284 static int translate_id_change(
1286 const struct kdbus_msg
*k
,
1287 const struct kdbus_item
*d
,
1288 const struct kdbus_timestamp
*ts
) {
1290 char owner
[UNIQUE_NAME_MAX
];
1296 sprintf(owner
, ":1.%llu", d
->id_change
.id
);
1298 return push_name_owner_changed(
1300 d
->type
== KDBUS_ITEM_ID_ADD
? NULL
: owner
,
1301 d
->type
== KDBUS_ITEM_ID_ADD
? owner
: NULL
,
1305 static int translate_reply(
1307 const struct kdbus_msg
*k
,
1308 const struct kdbus_item
*d
,
1309 const struct kdbus_timestamp
*ts
) {
1311 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1318 r
= bus_message_new_synthetic_error(
1321 d
->type
== KDBUS_ITEM_REPLY_TIMEOUT
?
1322 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call timed out") :
1323 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call peer died"),
1328 message_set_timestamp(bus
, m
, ts
);
1330 r
= bus_seal_synthetic_message(bus
, m
);
1334 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1340 static int bus_kernel_translate_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
1341 static int (* const translate
[])(sd_bus
*bus
, const struct kdbus_msg
*k
, const struct kdbus_item
*d
, const struct kdbus_timestamp
*ts
) = {
1342 [KDBUS_ITEM_NAME_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1343 [KDBUS_ITEM_NAME_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1344 [KDBUS_ITEM_NAME_CHANGE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1346 [KDBUS_ITEM_ID_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1347 [KDBUS_ITEM_ID_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1349 [KDBUS_ITEM_REPLY_TIMEOUT
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1350 [KDBUS_ITEM_REPLY_DEAD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1353 struct kdbus_item
*d
, *found
= NULL
;
1354 struct kdbus_timestamp
*ts
= NULL
;
1358 assert(k
->payload_type
== KDBUS_PAYLOAD_KERNEL
);
1360 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1361 if (d
->type
== KDBUS_ITEM_TIMESTAMP
)
1363 else if (d
->type
>= _KDBUS_ITEM_KERNEL_BASE
&& d
->type
< _KDBUS_ITEM_KERNEL_BASE
+ ELEMENTSOF(translate
)) {
1368 log_debug("Got unknown field from kernel %llu", d
->type
);
1372 log_debug("Didn't find a kernel message to translate.");
1376 return translate
[found
->type
- _KDBUS_ITEM_KERNEL_BASE
](bus
, k
, found
, ts
);
1379 int bus_kernel_read_message(sd_bus
*bus
, bool hint_priority
, int64_t priority
) {
1380 struct kdbus_cmd_recv recv
= { .size
= sizeof(recv
) };
1381 struct kdbus_msg
*k
;
1386 r
= bus_rqueue_make_room(bus
);
1390 if (hint_priority
) {
1391 recv
.flags
|= KDBUS_RECV_USE_PRIORITY
;
1392 recv
.priority
= priority
;
1395 r
= ioctl(bus
->input_fd
, KDBUS_CMD_RECV
, &recv
);
1396 if (recv
.return_flags
& KDBUS_RECV_RETURN_DROPPED_MSGS
)
1397 log_debug("%s: kdbus reports %" PRIu64
" dropped broadcast messages, ignoring.", strna(bus
->description
), (uint64_t) recv
.dropped_msgs
);
1399 if (errno
== EAGAIN
)
1405 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ recv
.msg
.offset
);
1406 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1407 r
= bus_kernel_make_message(bus
, k
);
1409 /* Anybody can send us invalid messages, let's just drop them. */
1410 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
) {
1411 log_debug_errno(r
, "Ignoring invalid message: %m");
1416 close_kdbus_msg(bus
, k
);
1417 } else if (k
->payload_type
== KDBUS_PAYLOAD_KERNEL
) {
1418 r
= bus_kernel_translate_message(bus
, k
);
1419 close_kdbus_msg(bus
, k
);
1421 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1423 close_kdbus_msg(bus
, k
);
1426 return r
< 0 ? r
: 1;
1429 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *mapped
, size_t *allocated
) {
1430 struct memfd_cache
*c
;
1437 if (!bus
|| !bus
->is_kernel
)
1440 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1442 if (bus
->n_memfd_cache
<= 0) {
1445 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1447 r
= memfd_new(bus
->description
);
1457 c
= &bus
->memfd_cache
[--bus
->n_memfd_cache
];
1460 assert(c
->mapped
== 0 || c
->address
);
1462 *address
= c
->address
;
1463 *mapped
= c
->mapped
;
1464 *allocated
= c
->allocated
;
1467 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1472 static void close_and_munmap(int fd
, void *address
, size_t size
) {
1474 assert_se(munmap(address
, PAGE_ALIGN(size
)) >= 0);
1479 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t mapped
, size_t allocated
) {
1480 struct memfd_cache
*c
;
1481 uint64_t max_mapped
= PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX
);
1484 assert(mapped
== 0 || address
);
1486 if (!bus
|| !bus
->is_kernel
) {
1487 close_and_munmap(fd
, address
, mapped
);
1491 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1493 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
1494 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1496 close_and_munmap(fd
, address
, mapped
);
1500 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
1502 c
->address
= address
;
1504 /* If overly long, let's return a bit to the OS */
1505 if (mapped
> max_mapped
) {
1506 assert_se(memfd_set_size(fd
, max_mapped
) >= 0);
1507 assert_se(munmap((uint8_t*) address
+ max_mapped
, PAGE_ALIGN(mapped
- max_mapped
)) >= 0);
1508 c
->mapped
= c
->allocated
= max_mapped
;
1511 c
->allocated
= allocated
;
1514 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1517 void bus_kernel_flush_memfd(sd_bus
*b
) {
1522 for (i
= 0; i
< b
->n_memfd_cache
; i
++)
1523 close_and_munmap(b
->memfd_cache
[i
].fd
, b
->memfd_cache
[i
].address
, b
->memfd_cache
[i
].mapped
);
1526 uint64_t request_name_flags_to_kdbus(uint64_t flags
) {
1529 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
1530 f
|= KDBUS_NAME_ALLOW_REPLACEMENT
;
1532 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
1533 f
|= KDBUS_NAME_REPLACE_EXISTING
;
1535 if (flags
& SD_BUS_NAME_QUEUE
)
1536 f
|= KDBUS_NAME_QUEUE
;
1541 uint64_t attach_flags_to_kdbus(uint64_t mask
) {
1544 if (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
|
1545 SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
))
1546 m
|= KDBUS_ATTACH_CREDS
;
1548 if (mask
& (SD_BUS_CREDS_PID
|SD_BUS_CREDS_TID
|SD_BUS_CREDS_PPID
))
1549 m
|= KDBUS_ATTACH_PIDS
;
1551 if (mask
& SD_BUS_CREDS_COMM
)
1552 m
|= KDBUS_ATTACH_PID_COMM
;
1554 if (mask
& SD_BUS_CREDS_TID_COMM
)
1555 m
|= KDBUS_ATTACH_TID_COMM
;
1557 if (mask
& SD_BUS_CREDS_EXE
)
1558 m
|= KDBUS_ATTACH_EXE
;
1560 if (mask
& SD_BUS_CREDS_CMDLINE
)
1561 m
|= KDBUS_ATTACH_CMDLINE
;
1563 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
))
1564 m
|= KDBUS_ATTACH_CGROUP
;
1566 if (mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
))
1567 m
|= KDBUS_ATTACH_CAPS
;
1569 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
)
1570 m
|= KDBUS_ATTACH_SECLABEL
;
1572 if (mask
& (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
))
1573 m
|= KDBUS_ATTACH_AUDIT
;
1575 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
)
1576 m
|= KDBUS_ATTACH_NAMES
;
1578 if (mask
& SD_BUS_CREDS_DESCRIPTION
)
1579 m
|= KDBUS_ATTACH_CONN_DESCRIPTION
;
1581 if (mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
)
1582 m
|= KDBUS_ATTACH_AUXGROUPS
;
1587 int bus_kernel_create_bus(const char *name
, bool world
, char **s
) {
1588 struct kdbus_cmd
*make
;
1589 struct kdbus_item
*n
;
1596 fd
= open("/sys/fs/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1601 make
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1602 ALIGN8(offsetof(struct kdbus_item
, bloom_parameter
) + sizeof(struct kdbus_bloom_parameter
)) +
1603 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)) +
1604 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + l
+ 1),
1607 make
->size
= offsetof(struct kdbus_cmd
, items
);
1609 /* Set the bloom parameters */
1611 n
->size
= offsetof(struct kdbus_item
, bloom_parameter
) +
1612 sizeof(struct kdbus_bloom_parameter
);
1613 n
->type
= KDBUS_ITEM_BLOOM_PARAMETER
;
1614 n
->bloom_parameter
.size
= DEFAULT_BLOOM_SIZE
;
1615 n
->bloom_parameter
.n_hash
= DEFAULT_BLOOM_N_HASH
;
1617 assert_cc(DEFAULT_BLOOM_SIZE
> 0);
1618 assert_cc(DEFAULT_BLOOM_N_HASH
> 0);
1620 make
->size
+= ALIGN8(n
->size
);
1622 /* Provide all metadata via bus-owner queries */
1623 n
= KDBUS_ITEM_NEXT(n
);
1624 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_SEND
;
1625 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1626 n
->data64
[0] = _KDBUS_ATTACH_ANY
;
1627 make
->size
+= ALIGN8(n
->size
);
1629 /* Set the a good name */
1630 n
= KDBUS_ITEM_NEXT(n
);
1631 sprintf(n
->str
, UID_FMT
"-%s", getuid(), name
);
1632 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1633 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1634 make
->size
+= ALIGN8(n
->size
);
1636 make
->flags
= world
? KDBUS_MAKE_ACCESS_WORLD
: 0;
1638 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
1641 /* Major API change? then the ioctls got shuffled around. */
1642 if (errno
== ENOTTY
)
1643 return -ESOCKTNOSUPPORT
;
1651 p
= strjoin("/sys/fs/kdbus/", n
->str
, "/bus", NULL
);
1663 int bus_kernel_open_bus_fd(const char *bus
, char **path
) {
1670 len
= strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + strlen("/bus") + 1;
1677 p
= newa(char, len
);
1679 sprintf(p
, "/sys/fs/kdbus/" UID_FMT
"-%s/bus", getuid(), bus
);
1681 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1695 int bus_kernel_create_endpoint(const char *bus_name
, const char *ep_name
, char **ep_path
) {
1696 _cleanup_free_
char *path
= NULL
;
1697 struct kdbus_cmd
*make
;
1698 struct kdbus_item
*n
;
1702 fd
= bus_kernel_open_bus_fd(bus_name
, &path
);
1706 make
= alloca0_align(ALIGN8(offsetof(struct kdbus_cmd
, items
)) +
1707 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(ep_name
) + 1),
1709 make
->size
= ALIGN8(offsetof(struct kdbus_cmd
, items
));
1710 make
->flags
= KDBUS_MAKE_ACCESS_WORLD
;
1713 sprintf(n
->str
, UID_FMT
"-%s", getuid(), ep_name
);
1714 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1715 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1716 make
->size
+= ALIGN8(n
->size
);
1719 if (ioctl(fd
, KDBUS_CMD_ENDPOINT_MAKE
, make
) < 0) {
1727 p
= strjoin(dirname(path
), "/", name
, NULL
);
1739 int bus_kernel_try_close(sd_bus
*bus
) {
1740 struct kdbus_cmd byebye
= { .size
= sizeof(byebye
) };
1743 assert(bus
->is_kernel
);
1745 if (ioctl(bus
->input_fd
, KDBUS_CMD_BYEBYE
, &byebye
) < 0)
1751 int bus_kernel_drop_one(int fd
) {
1752 struct kdbus_cmd_recv recv
= {
1753 .size
= sizeof(recv
),
1754 .flags
= KDBUS_RECV_DROP
,
1759 if (ioctl(fd
, KDBUS_CMD_RECV
, &recv
) < 0)
1765 int bus_kernel_realize_attach_flags(sd_bus
*bus
) {
1766 struct kdbus_cmd
*update
;
1767 struct kdbus_item
*n
;
1770 assert(bus
->is_kernel
);
1772 update
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1773 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)),
1777 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_RECV
;
1778 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1779 n
->data64
[0] = bus
->attach_flags
;
1782 offsetof(struct kdbus_cmd
, items
) +
1785 if (ioctl(bus
->input_fd
, KDBUS_CMD_UPDATE
, update
) < 0)
1791 int bus_kernel_get_bus_name(sd_bus
*bus
, char **name
) {
1792 struct kdbus_cmd_info cmd
= {
1793 .size
= sizeof(struct kdbus_cmd_info
),
1795 struct kdbus_info
*info
;
1796 struct kdbus_item
*item
;
1802 assert(bus
->is_kernel
);
1804 r
= ioctl(bus
->input_fd
, KDBUS_CMD_BUS_CREATOR_INFO
, &cmd
);
1808 info
= (struct kdbus_info
*) ((uint8_t*) bus
->kdbus_buffer
+ cmd
.offset
);
1810 KDBUS_ITEM_FOREACH(item
, info
, items
)
1811 if (item
->type
== KDBUS_ITEM_MAKE_NAME
) {
1812 r
= free_and_strdup(&n
, item
->str
);
1816 bus_kernel_cmd_free(bus
, cmd
.offset
);