2 This file is part of systemd.
4 Copyright 2013 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_VALGRIND_MEMCHECK_H
21 #include <valgrind/memcheck.h>
27 #include <sys/prctl.h>
29 /* When we include libgen.h because we need dirname() we immediately
30 * undefine basename() since libgen.h defines it as a macro to the POSIX
31 * version which is really broken. We prefer GNU basename(). */
35 #include "alloc-util.h"
36 #include "bus-bloom.h"
37 #include "bus-internal.h"
38 #include "bus-kernel.h"
39 #include "bus-label.h"
40 #include "bus-message.h"
42 #include "capability-util.h"
45 #include "formats-util.h"
46 #include "memfd-util.h"
47 #include "parse-util.h"
48 #include "stdio-util.h"
49 #include "string-util.h"
51 #include "user-util.h"
54 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
56 int bus_kernel_parse_unique_name(const char *s
, uint64_t *id
) {
62 if (!startswith(s
, ":1."))
65 r
= safe_atou64(s
+ 3, id
);
72 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
78 /* Note that p can be NULL, which encodes a region full of
79 * zeroes, which is useful to optimize certain padding
82 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
83 (*d
)->type
= KDBUS_ITEM_PAYLOAD_VEC
;
84 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
87 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
90 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t start
, size_t sz
) {
96 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
97 (*d
)->type
= KDBUS_ITEM_PAYLOAD_MEMFD
;
98 (*d
)->memfd
.fd
= memfd
;
99 (*d
)->memfd
.start
= start
;
100 (*d
)->memfd
.size
= sz
;
102 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
105 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
111 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
112 (*d
)->type
= KDBUS_ITEM_DST_NAME
;
113 memcpy((*d
)->str
, s
, length
+ 1);
115 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
118 static struct kdbus_bloom_filter
*append_bloom(struct kdbus_item
**d
, size_t length
) {
119 struct kdbus_item
*i
;
125 i
->size
= offsetof(struct kdbus_item
, bloom_filter
) +
126 offsetof(struct kdbus_bloom_filter
, data
) +
128 i
->type
= KDBUS_ITEM_BLOOM_FILTER
;
130 *d
= (struct kdbus_item
*) ((uint8_t*) i
+ i
->size
);
132 return &i
->bloom_filter
;
135 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
141 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
142 (*d
)->type
= KDBUS_ITEM_FDS
;
143 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
145 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
148 static void add_bloom_arg(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
149 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
157 e
= stpcpy(buf
, "arg");
159 *(e
++) = '0' + (char) i
;
161 *(e
++) = '0' + (char) (i
/ 10);
162 *(e
++) = '0' + (char) (i
% 10);
166 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
168 strcpy(e
, "-dot-prefix");
169 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '.');
170 strcpy(e
, "-slash-prefix");
171 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '/');
174 static void add_bloom_arg_has(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
175 char buf
[sizeof("arg")-1 + 2 + sizeof("-has")];
183 e
= stpcpy(buf
, "arg");
185 *(e
++) = '0' + (char) i
;
187 *(e
++) = '0' + (char) (i
/ 10);
188 *(e
++) = '0' + (char) (i
% 10);
192 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
195 static int bus_message_setup_bloom(sd_bus_message
*m
, struct kdbus_bloom_filter
*bloom
) {
204 memzero(data
, m
->bus
->bloom_size
);
205 bloom
->generation
= 0;
207 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "message-type", bus_message_type_to_string(m
->header
->type
));
210 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "interface", m
->interface
);
212 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "member", m
->member
);
214 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path", m
->path
);
215 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
);
216 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
, '/');
219 r
= sd_bus_message_rewind(m
, true);
223 for (i
= 0; i
< 64; i
++) {
224 const char *t
, *contents
;
227 r
= sd_bus_message_peek_type(m
, &type
, &contents
);
231 if (IN_SET(type
, SD_BUS_TYPE_STRING
, SD_BUS_TYPE_OBJECT_PATH
, SD_BUS_TYPE_SIGNATURE
)) {
233 /* The bloom filter includes simple strings of any kind */
234 r
= sd_bus_message_read_basic(m
, type
, &t
);
238 add_bloom_arg(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
241 if (type
== SD_BUS_TYPE_ARRAY
&& STR_IN_SET(contents
, "s", "o", "g")) {
243 /* As well as array of simple strings of any kinds */
244 r
= sd_bus_message_enter_container(m
, type
, contents
);
248 while ((r
= sd_bus_message_read_basic(m
, contents
[0], &t
)) > 0)
249 add_bloom_arg_has(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
253 r
= sd_bus_message_exit_container(m
);
258 /* Stop adding to bloom filter as soon as we
259 * run into the first argument we cannot add
267 static int bus_message_setup_kmsg(sd_bus
*b
, sd_bus_message
*m
) {
268 struct bus_body_part
*part
;
269 struct kdbus_item
*d
;
270 const char *destination
;
271 bool well_known
= false;
281 /* We put this together only once, if this message is reused
282 * we reuse the earlier-built version */
286 destination
= m
->destination
?: m
->destination_ptr
;
289 r
= bus_kernel_parse_unique_name(destination
, &dst_id
);
295 /* verify_destination_id will usually be 0, which makes the kernel
296 * driver only look at the provided well-known name. Otherwise,
297 * the kernel will make sure the provided destination id matches
298 * the owner of the provided well-known-name, and fail if they
299 * differ. Currently, this is only needed for bus-proxyd. */
300 dst_id
= m
->verify_destination_id
;
303 dst_id
= KDBUS_DST_ID_BROADCAST
;
305 sz
= offsetof(struct kdbus_msg
, items
);
307 /* Add in fixed header, fields header and payload */
308 sz
+= (1 + m
->n_body_parts
) * ALIGN8(offsetof(struct kdbus_item
, vec
) +
309 MAX(sizeof(struct kdbus_vec
),
310 sizeof(struct kdbus_memfd
)));
312 /* Add space for bloom filter */
313 sz
+= ALIGN8(offsetof(struct kdbus_item
, bloom_filter
) +
314 offsetof(struct kdbus_bloom_filter
, data
) +
317 /* Add in well-known destination header */
319 dl
= strlen(destination
);
320 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
323 /* Add space for unix fds */
325 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
327 m
->kdbus
= memalign(8, sz
);
333 m
->free_kdbus
= true;
334 memzero(m
->kdbus
, sz
);
337 ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_EXPECT_REPLY
) |
338 ((m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_NO_AUTO_START
: 0) |
339 ((m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) ? KDBUS_MSG_SIGNAL
: 0);
341 m
->kdbus
->dst_id
= dst_id
;
342 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS
;
343 m
->kdbus
->cookie
= m
->header
->dbus2
.cookie
;
344 m
->kdbus
->priority
= m
->priority
;
346 if (m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
)
347 m
->kdbus
->cookie_reply
= m
->reply_cookie
;
351 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE
, &now
) == 0);
352 m
->kdbus
->timeout_ns
= now
.tv_sec
* NSEC_PER_SEC
+ now
.tv_nsec
+
353 m
->timeout
* NSEC_PER_USEC
;
359 append_destination(&d
, destination
, dl
);
361 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
363 MESSAGE_FOREACH_PART(part
, i
, m
) {
365 /* If this is padding then simply send a
366 * vector with a NULL data pointer which the
367 * kernel will just pass through. This is the
368 * most efficient way to encode zeroes */
370 append_payload_vec(&d
, NULL
, part
->size
);
374 if (part
->memfd
>= 0 && part
->sealed
&& destination
) {
375 /* Try to send a memfd, if the part is
376 * sealed and this is not a broadcast. Since we can only */
378 append_payload_memfd(&d
, part
->memfd
, part
->memfd_offset
, part
->size
);
382 /* Otherwise, let's send a vector to the actual data.
383 * For that, we need to map it first. */
384 r
= bus_body_part_map(part
);
388 append_payload_vec(&d
, part
->data
, part
->size
);
391 if (m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) {
392 struct kdbus_bloom_filter
*bloom
;
394 bloom
= append_bloom(&d
, m
->bus
->bloom_size
);
395 r
= bus_message_setup_bloom(m
, bloom
);
401 append_fds(&d
, m
->fds
, m
->n_fds
);
403 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
404 assert(m
->kdbus
->size
<= sz
);
413 static void unset_memfds(struct sd_bus_message
*m
) {
414 struct bus_body_part
*part
;
419 /* Make sure the memfds are not freed twice */
420 MESSAGE_FOREACH_PART(part
, i
, m
)
421 if (part
->memfd
>= 0)
425 static void message_set_timestamp(sd_bus
*bus
, sd_bus_message
*m
, const struct kdbus_timestamp
*ts
) {
432 if (!(bus
->attach_flags
& KDBUS_ATTACH_TIMESTAMP
))
435 m
->realtime
= ts
->realtime_ns
/ NSEC_PER_USEC
;
436 m
->monotonic
= ts
->monotonic_ns
/ NSEC_PER_USEC
;
437 m
->seqnum
= ts
->seqnum
;
440 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
441 sd_bus_message
*m
= NULL
;
442 struct kdbus_item
*d
;
444 _cleanup_free_
int *fds
= NULL
;
445 struct bus_header
*header
= NULL
;
447 size_t header_size
= 0, footer_size
= 0;
448 size_t n_bytes
= 0, idx
= 0;
449 const char *destination
= NULL
, *seclabel
= NULL
;
450 bool last_was_memfd
= false;
455 assert(k
->payload_type
== KDBUS_PAYLOAD_DBUS
);
457 KDBUS_ITEM_FOREACH(d
, k
, items
) {
460 l
= d
->size
- offsetof(struct kdbus_item
, data
);
464 case KDBUS_ITEM_PAYLOAD_OFF
:
466 header
= (struct bus_header
*)((uint8_t*) k
+ d
->vec
.offset
);
467 header_size
= d
->vec
.size
;
470 footer
= (uint8_t*) k
+ d
->vec
.offset
;
471 footer_size
= d
->vec
.size
;
473 n_bytes
+= d
->vec
.size
;
474 last_was_memfd
= false;
477 case KDBUS_ITEM_PAYLOAD_MEMFD
:
478 if (!header
) /* memfd cannot be first part */
481 n_bytes
+= d
->memfd
.size
;
482 last_was_memfd
= true;
485 case KDBUS_ITEM_FDS
: {
490 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
495 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
500 case KDBUS_ITEM_SECLABEL
:
506 if (last_was_memfd
) /* memfd cannot be last part */
512 if (header_size
< sizeof(struct bus_header
))
515 /* on kdbus we only speak native endian gvariant, never dbus1
516 * marshalling or reverse endian */
517 if (header
->version
!= 2 ||
518 header
->endian
!= BUS_NATIVE_ENDIAN
)
521 r
= bus_message_from_header(
531 /* The well-known names list is different from the other
532 credentials. If we asked for it, but nothing is there, this
533 means that the list of well-known names is simply empty, not
534 that we lack any data */
536 m
->creds
.mask
|= (SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
) & bus
->creds_mask
;
538 KDBUS_ITEM_FOREACH(d
, k
, items
) {
541 l
= d
->size
- offsetof(struct kdbus_item
, data
);
545 case KDBUS_ITEM_PAYLOAD_OFF
: {
548 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
550 if (idx
+ d
->vec
.size
> begin_body
) {
551 struct bus_body_part
*part
;
553 /* Contains body material */
555 part
= message_append_part(m
);
561 /* A -1 offset is NUL padding. */
562 part
->is_zero
= d
->vec
.offset
== ~0ULL;
564 if (idx
>= begin_body
) {
566 part
->data
= (uint8_t* )k
+ d
->vec
.offset
;
567 part
->size
= d
->vec
.size
;
570 part
->data
= (uint8_t*) k
+ d
->vec
.offset
+ (begin_body
- idx
);
571 part
->size
= d
->vec
.size
- (begin_body
- idx
);
581 case KDBUS_ITEM_PAYLOAD_MEMFD
: {
582 struct bus_body_part
*part
;
584 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
589 part
= message_append_part(m
);
595 part
->memfd
= d
->memfd
.fd
;
596 part
->memfd_offset
= d
->memfd
.start
;
597 part
->size
= d
->memfd
.size
;
600 idx
+= d
->memfd
.size
;
604 case KDBUS_ITEM_PIDS
:
606 /* The PID/TID might be missing, when the data
607 * is faked by a bus proxy and it lacks that
608 * information about the real client (since
609 * SO_PEERCRED is used for that). Also kernel
610 * namespacing might make some of this data
611 * unavailable when untranslatable. */
613 if (d
->pids
.pid
> 0) {
614 m
->creds
.pid
= (pid_t
) d
->pids
.pid
;
615 m
->creds
.mask
|= SD_BUS_CREDS_PID
& bus
->creds_mask
;
618 if (d
->pids
.tid
> 0) {
619 m
->creds
.tid
= (pid_t
) d
->pids
.tid
;
620 m
->creds
.mask
|= SD_BUS_CREDS_TID
& bus
->creds_mask
;
623 if (d
->pids
.ppid
> 0) {
624 m
->creds
.ppid
= (pid_t
) d
->pids
.ppid
;
625 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
626 } else if (d
->pids
.pid
== 1) {
628 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
633 case KDBUS_ITEM_CREDS
:
635 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
636 * missing too (see above). */
638 if ((uid_t
) d
->creds
.uid
!= UID_INVALID
) {
639 m
->creds
.uid
= (uid_t
) d
->creds
.uid
;
640 m
->creds
.mask
|= SD_BUS_CREDS_UID
& bus
->creds_mask
;
643 if ((uid_t
) d
->creds
.euid
!= UID_INVALID
) {
644 m
->creds
.euid
= (uid_t
) d
->creds
.euid
;
645 m
->creds
.mask
|= SD_BUS_CREDS_EUID
& bus
->creds_mask
;
648 if ((uid_t
) d
->creds
.suid
!= UID_INVALID
) {
649 m
->creds
.suid
= (uid_t
) d
->creds
.suid
;
650 m
->creds
.mask
|= SD_BUS_CREDS_SUID
& bus
->creds_mask
;
653 if ((uid_t
) d
->creds
.fsuid
!= UID_INVALID
) {
654 m
->creds
.fsuid
= (uid_t
) d
->creds
.fsuid
;
655 m
->creds
.mask
|= SD_BUS_CREDS_FSUID
& bus
->creds_mask
;
658 if ((gid_t
) d
->creds
.gid
!= GID_INVALID
) {
659 m
->creds
.gid
= (gid_t
) d
->creds
.gid
;
660 m
->creds
.mask
|= SD_BUS_CREDS_GID
& bus
->creds_mask
;
663 if ((gid_t
) d
->creds
.egid
!= GID_INVALID
) {
664 m
->creds
.egid
= (gid_t
) d
->creds
.egid
;
665 m
->creds
.mask
|= SD_BUS_CREDS_EGID
& bus
->creds_mask
;
668 if ((gid_t
) d
->creds
.sgid
!= GID_INVALID
) {
669 m
->creds
.sgid
= (gid_t
) d
->creds
.sgid
;
670 m
->creds
.mask
|= SD_BUS_CREDS_SGID
& bus
->creds_mask
;
673 if ((gid_t
) d
->creds
.fsgid
!= GID_INVALID
) {
674 m
->creds
.fsgid
= (gid_t
) d
->creds
.fsgid
;
675 m
->creds
.mask
|= SD_BUS_CREDS_FSGID
& bus
->creds_mask
;
680 case KDBUS_ITEM_TIMESTAMP
:
681 message_set_timestamp(bus
, m
, &d
->timestamp
);
684 case KDBUS_ITEM_PID_COMM
:
685 m
->creds
.comm
= d
->str
;
686 m
->creds
.mask
|= SD_BUS_CREDS_COMM
& bus
->creds_mask
;
689 case KDBUS_ITEM_TID_COMM
:
690 m
->creds
.tid_comm
= d
->str
;
691 m
->creds
.mask
|= SD_BUS_CREDS_TID_COMM
& bus
->creds_mask
;
695 m
->creds
.exe
= d
->str
;
696 m
->creds
.mask
|= SD_BUS_CREDS_EXE
& bus
->creds_mask
;
699 case KDBUS_ITEM_CMDLINE
:
700 m
->creds
.cmdline
= d
->str
;
701 m
->creds
.cmdline_size
= l
;
702 m
->creds
.mask
|= SD_BUS_CREDS_CMDLINE
& bus
->creds_mask
;
705 case KDBUS_ITEM_CGROUP
:
706 m
->creds
.cgroup
= d
->str
;
707 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
;
709 r
= bus_get_root_path(bus
);
713 m
->creds
.cgroup_root
= bus
->cgroup_root
;
716 case KDBUS_ITEM_AUDIT
:
717 m
->creds
.audit_session_id
= (uint32_t) d
->audit
.sessionid
;
718 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
& bus
->creds_mask
;
720 m
->creds
.audit_login_uid
= (uid_t
) d
->audit
.loginuid
;
721 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
& bus
->creds_mask
;
724 case KDBUS_ITEM_CAPS
:
725 if (d
->caps
.last_cap
!= cap_last_cap() ||
726 d
->size
- offsetof(struct kdbus_item
, caps
.caps
) < DIV_ROUND_UP(d
->caps
.last_cap
, 32U) * 4 * 4) {
731 m
->creds
.capability
= d
->caps
.caps
;
732 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
;
735 case KDBUS_ITEM_DST_NAME
:
736 if (!service_name_is_valid(d
->str
)) {
741 destination
= d
->str
;
744 case KDBUS_ITEM_OWNED_NAME
:
745 if (!service_name_is_valid(d
->name
.name
)) {
750 if (bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
754 /* We just extend the array here, but
755 * do not allocate the strings inside
756 * of it, instead we just point to our
757 * buffer directly. */
758 n
= strv_length(m
->creds
.well_known_names
);
759 wkn
= realloc(m
->creds
.well_known_names
, (n
+ 2) * sizeof(char*));
765 wkn
[n
] = d
->name
.name
;
767 m
->creds
.well_known_names
= wkn
;
769 m
->creds
.mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
773 case KDBUS_ITEM_CONN_DESCRIPTION
:
774 m
->creds
.description
= d
->str
;
775 m
->creds
.mask
|= SD_BUS_CREDS_DESCRIPTION
& bus
->creds_mask
;
778 case KDBUS_ITEM_AUXGROUPS
:
780 if (bus
->creds_mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
784 n
= (d
->size
- offsetof(struct kdbus_item
, data64
)) / sizeof(uint64_t);
791 for (i
= 0; i
< n
; i
++)
794 m
->creds
.supplementary_gids
= g
;
795 m
->creds
.n_supplementary_gids
= n
;
796 m
->creds
.mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
802 case KDBUS_ITEM_SECLABEL
:
803 case KDBUS_ITEM_BLOOM_FILTER
:
807 log_debug("Got unknown field from kernel %llu", d
->type
);
811 /* If we requested the list of well-known names to be appended
812 * and the sender had none no item for it will be
813 * attached. However, this does *not* mean that the kernel
814 * didn't want to provide this information to us. Hence, let's
815 * explicitly mark this information as available if it was
817 m
->creds
.mask
|= bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
;
819 r
= bus_message_parse_fields(m
);
823 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
824 if ((uint64_t) m
->header
->dbus2
.cookie
!= k
->cookie
) {
829 /* Refuse messages where the reply flag doesn't match up */
830 if (!(m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) != !!(k
->flags
& KDBUS_MSG_EXPECT_REPLY
)) {
835 /* Refuse reply messages where the reply cookie doesn't match up */
836 if ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) && m
->reply_cookie
!= k
->cookie_reply
) {
841 /* Refuse messages where the autostart flag doesn't match up */
842 if (!(m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) != !(k
->flags
& KDBUS_MSG_NO_AUTO_START
)) {
847 /* Override information from the user header with data from the kernel */
848 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
849 bus_message_set_sender_driver(bus
, m
);
851 xsprintf(m
->sender_buffer
, ":1.%llu",
852 (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 xsprintf(m
->destination_buffer
, ":1.%llu",
864 (unsigned long long)k
->dst_id
);
865 m
->destination
= m
->destination_buffer
;
868 /* We take possession of the kmsg struct now */
870 m
->release_kdbus
= true;
874 bus
->rqueue
[bus
->rqueue_size
++] = m
;
880 sd_bus_message_unref(m
);
885 int bus_kernel_take_fd(sd_bus
*b
) {
886 struct kdbus_bloom_parameter
*bloom
= NULL
;
887 struct kdbus_item
*items
, *item
;
888 struct kdbus_cmd_hello
*hello
;
889 _cleanup_free_
char *g
= NULL
;
891 size_t l
= 0, m
= 0, sz
;
901 if (b
->description
) {
902 g
= bus_label_escape(b
->description
);
910 /* If no name is explicitly set, we'll include a hint
911 * indicating the library implementation, a hint which
912 * kind of bus this is and the thread name */
914 assert_se(prctl(PR_GET_NAME
, (unsigned long) pr
) >= 0);
917 name
= b
->is_system
? "sd-system" :
918 b
->is_user
? "sd-user" : "sd";
920 _cleanup_free_
char *e
= NULL
;
922 e
= bus_label_escape(pr
);
926 g
= strappend(b
->is_system
? "sd-system-" :
927 b
->is_user
? "sd-user-" : "sd-",
935 b
->description
= bus_label_unescape(name
);
942 sz
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
)) +
943 ALIGN8(offsetof(struct kdbus_item
, str
) + m
+ 1);
945 if (b
->fake_creds_valid
)
946 sz
+= ALIGN8(offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
));
948 if (b
->fake_pids_valid
)
949 sz
+= ALIGN8(offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
));
952 l
= strlen(b
->fake_label
);
953 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + l
+ 1);
956 hello
= alloca0_align(sz
, 8);
958 hello
->flags
= b
->hello_flags
;
959 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
960 hello
->attach_flags_recv
= b
->attach_flags
;
961 hello
->pool_size
= KDBUS_POOL_SIZE
;
965 item
->size
= offsetof(struct kdbus_item
, str
) + m
+ 1;
966 item
->type
= KDBUS_ITEM_CONN_DESCRIPTION
;
967 memcpy(item
->str
, name
, m
+ 1);
968 item
= KDBUS_ITEM_NEXT(item
);
970 if (b
->fake_creds_valid
) {
971 item
->size
= offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
);
972 item
->type
= KDBUS_ITEM_CREDS
;
973 item
->creds
= b
->fake_creds
;
975 item
= KDBUS_ITEM_NEXT(item
);
978 if (b
->fake_pids_valid
) {
979 item
->size
= offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
);
980 item
->type
= KDBUS_ITEM_PIDS
;
981 item
->pids
= b
->fake_pids
;
983 item
= KDBUS_ITEM_NEXT(item
);
987 item
->size
= offsetof(struct kdbus_item
, str
) + l
+ 1;
988 item
->type
= KDBUS_ITEM_SECLABEL
;
989 memcpy(item
->str
, b
->fake_label
, l
+1);
992 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
995 /* If the ioctl is not supported we assume that the
996 * API version changed in a major incompatible way,
997 * let's indicate an API incompatibility in this
999 return -ESOCKTNOSUPPORT
;
1004 if (!b
->kdbus_buffer
) {
1005 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
, MAP_SHARED
, b
->input_fd
, 0);
1006 if (b
->kdbus_buffer
== MAP_FAILED
) {
1007 b
->kdbus_buffer
= NULL
;
1013 /* The higher 32bit of the bus_flags fields are considered
1014 * 'incompatible flags'. Refuse them all for now. */
1015 if (hello
->bus_flags
> 0xFFFFFFFFULL
) {
1016 r
= -ESOCKTNOSUPPORT
;
1020 /* extract bloom parameters from items */
1021 items
= (void*)((uint8_t*)b
->kdbus_buffer
+ hello
->offset
);
1022 KDBUS_FOREACH(item
, items
, hello
->items_size
) {
1023 switch (item
->type
) {
1024 case KDBUS_ITEM_BLOOM_PARAMETER
:
1025 bloom
= &item
->bloom_parameter
;
1030 if (!bloom
|| !bloom_validate_parameters((size_t) bloom
->size
, (unsigned) bloom
->n_hash
)) {
1035 b
->bloom_size
= (size_t) bloom
->size
;
1036 b
->bloom_n_hash
= (unsigned) bloom
->n_hash
;
1038 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0) {
1043 b
->unique_id
= hello
->id
;
1045 b
->is_kernel
= true;
1046 b
->bus_client
= true;
1047 b
->can_fds
= !!(hello
->flags
& KDBUS_HELLO_ACCEPT_FD
);
1048 b
->message_version
= 2;
1049 b
->message_endian
= BUS_NATIVE_ENDIAN
;
1051 /* the kernel told us the UUID of the underlying bus */
1052 memcpy(b
->server_id
.bytes
, hello
->id128
, sizeof(b
->server_id
.bytes
));
1054 /* free returned items */
1055 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1056 return bus_start_running(b
);
1059 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1063 int bus_kernel_connect(sd_bus
*b
) {
1065 assert(b
->input_fd
< 0);
1066 assert(b
->output_fd
< 0);
1072 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1073 if (b
->input_fd
< 0)
1076 b
->output_fd
= b
->input_fd
;
1078 return bus_kernel_take_fd(b
);
1081 int bus_kernel_cmd_free(sd_bus
*bus
, uint64_t offset
) {
1082 struct kdbus_cmd_free cmd
= {
1083 .size
= sizeof(cmd
),
1089 assert(bus
->is_kernel
);
1091 r
= ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &cmd
);
1098 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
1099 struct kdbus_item
*d
;
1104 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1105 if (d
->type
== KDBUS_ITEM_FDS
)
1106 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
1107 else if (d
->type
== KDBUS_ITEM_PAYLOAD_MEMFD
)
1108 safe_close(d
->memfd
.fd
);
1111 bus_kernel_cmd_free(bus
, (uint8_t*) k
- (uint8_t*) bus
->kdbus_buffer
);
1114 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
, bool hint_sync_call
) {
1115 struct kdbus_cmd_send cmd
= { };
1120 assert(bus
->state
== BUS_RUNNING
);
1122 /* If we can't deliver, we want room for the error message */
1123 r
= bus_rqueue_make_room(bus
);
1127 r
= bus_message_setup_kmsg(bus
, m
);
1131 cmd
.size
= sizeof(cmd
);
1132 cmd
.msg_address
= (uintptr_t)m
->kdbus
;
1134 /* If this is a synchronous method call, then let's tell the
1135 * kernel, so that it can pass CPU time/scheduling to the
1136 * destination for the time, if it wants to. If we
1137 * synchronously wait for the result anyway, we won't need CPU
1139 if (hint_sync_call
) {
1140 m
->kdbus
->flags
|= KDBUS_MSG_EXPECT_REPLY
;
1141 cmd
.flags
|= KDBUS_SEND_SYNC_REPLY
;
1144 r
= ioctl(bus
->output_fd
, KDBUS_CMD_SEND
, &cmd
);
1146 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1147 sd_bus_message
*reply
;
1149 if (errno
== EAGAIN
|| errno
== EINTR
)
1151 else if (errno
== ENXIO
|| errno
== ESRCH
) {
1153 /* ENXIO: unique name not known
1154 * ESRCH: well-known name not known */
1156 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1157 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Destination %s not known", m
->destination
);
1159 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m
->destination
);
1163 } else if (errno
== EADDRNOTAVAIL
) {
1165 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1167 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1168 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Activation of %s not requested", m
->destination
);
1170 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m
->destination
);
1176 r
= bus_message_new_synthetic_error(
1178 BUS_MESSAGE_COOKIE(m
),
1185 r
= bus_seal_synthetic_message(bus
, reply
);
1189 bus
->rqueue
[bus
->rqueue_size
++] = reply
;
1191 } else if (hint_sync_call
) {
1192 struct kdbus_msg
*k
;
1194 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ cmd
.reply
.offset
);
1197 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1199 r
= bus_kernel_make_message(bus
, k
);
1201 close_kdbus_msg(bus
, k
);
1203 /* Anybody can send us invalid messages, let's just drop them. */
1204 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
)
1205 log_debug_errno(r
, "Ignoring invalid synchronous reply: %m");
1210 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1211 close_kdbus_msg(bus
, k
);
1218 static int push_name_owner_changed(
1221 const char *old_owner
,
1222 const char *new_owner
,
1223 const struct kdbus_timestamp
*ts
) {
1225 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1230 r
= sd_bus_message_new_signal(
1233 "/org/freedesktop/DBus",
1234 "org.freedesktop.DBus",
1235 "NameOwnerChanged");
1239 r
= sd_bus_message_append(m
, "sss", name
, old_owner
, new_owner
);
1243 bus_message_set_sender_driver(bus
, m
);
1244 message_set_timestamp(bus
, m
, ts
);
1246 r
= bus_seal_synthetic_message(bus
, m
);
1250 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1256 static int translate_name_change(
1258 const struct kdbus_msg
*k
,
1259 const struct kdbus_item
*d
,
1260 const struct kdbus_timestamp
*ts
) {
1262 char new_owner
[UNIQUE_NAME_MAX
], old_owner
[UNIQUE_NAME_MAX
];
1268 if (d
->type
== KDBUS_ITEM_NAME_ADD
|| (d
->name_change
.old_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
)))
1271 sprintf(old_owner
, ":1.%llu", (unsigned long long) d
->name_change
.old_id
.id
);
1273 if (d
->type
== KDBUS_ITEM_NAME_REMOVE
|| (d
->name_change
.new_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
))) {
1275 if (isempty(old_owner
))
1280 sprintf(new_owner
, ":1.%llu", (unsigned long long) d
->name_change
.new_id
.id
);
1282 return push_name_owner_changed(bus
, d
->name_change
.name
, old_owner
, new_owner
, ts
);
1285 static int translate_id_change(
1287 const struct kdbus_msg
*k
,
1288 const struct kdbus_item
*d
,
1289 const struct kdbus_timestamp
*ts
) {
1291 char owner
[UNIQUE_NAME_MAX
];
1297 sprintf(owner
, ":1.%llu", d
->id_change
.id
);
1299 return push_name_owner_changed(
1301 d
->type
== KDBUS_ITEM_ID_ADD
? NULL
: owner
,
1302 d
->type
== KDBUS_ITEM_ID_ADD
? owner
: NULL
,
1306 static int translate_reply(
1308 const struct kdbus_msg
*k
,
1309 const struct kdbus_item
*d
,
1310 const struct kdbus_timestamp
*ts
) {
1312 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1319 r
= bus_message_new_synthetic_error(
1322 d
->type
== KDBUS_ITEM_REPLY_TIMEOUT
?
1323 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call timed out") :
1324 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call peer died"),
1329 message_set_timestamp(bus
, m
, ts
);
1331 r
= bus_seal_synthetic_message(bus
, m
);
1335 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1341 static int bus_kernel_translate_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
1342 static int (* const translate
[])(sd_bus
*bus
, const struct kdbus_msg
*k
, const struct kdbus_item
*d
, const struct kdbus_timestamp
*ts
) = {
1343 [KDBUS_ITEM_NAME_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1344 [KDBUS_ITEM_NAME_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1345 [KDBUS_ITEM_NAME_CHANGE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1347 [KDBUS_ITEM_ID_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1348 [KDBUS_ITEM_ID_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1350 [KDBUS_ITEM_REPLY_TIMEOUT
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1351 [KDBUS_ITEM_REPLY_DEAD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1354 struct kdbus_item
*d
, *found
= NULL
;
1355 struct kdbus_timestamp
*ts
= NULL
;
1359 assert(k
->payload_type
== KDBUS_PAYLOAD_KERNEL
);
1361 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1362 if (d
->type
== KDBUS_ITEM_TIMESTAMP
)
1364 else if (d
->type
>= _KDBUS_ITEM_KERNEL_BASE
&& d
->type
< _KDBUS_ITEM_KERNEL_BASE
+ ELEMENTSOF(translate
)) {
1369 log_debug("Got unknown field from kernel %llu", d
->type
);
1373 log_debug("Didn't find a kernel message to translate.");
1377 return translate
[found
->type
- _KDBUS_ITEM_KERNEL_BASE
](bus
, k
, found
, ts
);
1380 int bus_kernel_read_message(sd_bus
*bus
, bool hint_priority
, int64_t priority
) {
1381 struct kdbus_cmd_recv recv
= { .size
= sizeof(recv
) };
1382 struct kdbus_msg
*k
;
1387 r
= bus_rqueue_make_room(bus
);
1391 if (hint_priority
) {
1392 recv
.flags
|= KDBUS_RECV_USE_PRIORITY
;
1393 recv
.priority
= priority
;
1396 r
= ioctl(bus
->input_fd
, KDBUS_CMD_RECV
, &recv
);
1397 if (recv
.return_flags
& KDBUS_RECV_RETURN_DROPPED_MSGS
)
1398 log_debug("%s: kdbus reports %" PRIu64
" dropped broadcast messages, ignoring.", strna(bus
->description
), (uint64_t) recv
.dropped_msgs
);
1400 if (errno
== EAGAIN
)
1406 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ recv
.msg
.offset
);
1407 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1408 r
= bus_kernel_make_message(bus
, k
);
1410 /* Anybody can send us invalid messages, let's just drop them. */
1411 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
) {
1412 log_debug_errno(r
, "Ignoring invalid message: %m");
1417 close_kdbus_msg(bus
, k
);
1418 } else if (k
->payload_type
== KDBUS_PAYLOAD_KERNEL
) {
1419 r
= bus_kernel_translate_message(bus
, k
);
1420 close_kdbus_msg(bus
, k
);
1422 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1424 close_kdbus_msg(bus
, k
);
1427 return r
< 0 ? r
: 1;
1430 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *mapped
, size_t *allocated
) {
1431 struct memfd_cache
*c
;
1438 if (!bus
|| !bus
->is_kernel
)
1441 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1443 if (bus
->n_memfd_cache
<= 0) {
1446 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1448 r
= memfd_new(bus
->description
);
1458 c
= &bus
->memfd_cache
[--bus
->n_memfd_cache
];
1461 assert(c
->mapped
== 0 || c
->address
);
1463 *address
= c
->address
;
1464 *mapped
= c
->mapped
;
1465 *allocated
= c
->allocated
;
1468 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1473 static void close_and_munmap(int fd
, void *address
, size_t size
) {
1475 assert_se(munmap(address
, PAGE_ALIGN(size
)) >= 0);
1480 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t mapped
, size_t allocated
) {
1481 struct memfd_cache
*c
;
1482 uint64_t max_mapped
= PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX
);
1485 assert(mapped
== 0 || address
);
1487 if (!bus
|| !bus
->is_kernel
) {
1488 close_and_munmap(fd
, address
, mapped
);
1492 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1494 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
1495 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1497 close_and_munmap(fd
, address
, mapped
);
1501 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
1503 c
->address
= address
;
1505 /* If overly long, let's return a bit to the OS */
1506 if (mapped
> max_mapped
) {
1507 assert_se(memfd_set_size(fd
, max_mapped
) >= 0);
1508 assert_se(munmap((uint8_t*) address
+ max_mapped
, PAGE_ALIGN(mapped
- max_mapped
)) >= 0);
1509 c
->mapped
= c
->allocated
= max_mapped
;
1512 c
->allocated
= allocated
;
1515 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1518 void bus_kernel_flush_memfd(sd_bus
*b
) {
1523 for (i
= 0; i
< b
->n_memfd_cache
; i
++)
1524 close_and_munmap(b
->memfd_cache
[i
].fd
, b
->memfd_cache
[i
].address
, b
->memfd_cache
[i
].mapped
);
1527 uint64_t request_name_flags_to_kdbus(uint64_t flags
) {
1530 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
1531 f
|= KDBUS_NAME_ALLOW_REPLACEMENT
;
1533 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
1534 f
|= KDBUS_NAME_REPLACE_EXISTING
;
1536 if (flags
& SD_BUS_NAME_QUEUE
)
1537 f
|= KDBUS_NAME_QUEUE
;
1542 uint64_t attach_flags_to_kdbus(uint64_t mask
) {
1545 if (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
|
1546 SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
))
1547 m
|= KDBUS_ATTACH_CREDS
;
1549 if (mask
& (SD_BUS_CREDS_PID
|SD_BUS_CREDS_TID
|SD_BUS_CREDS_PPID
))
1550 m
|= KDBUS_ATTACH_PIDS
;
1552 if (mask
& SD_BUS_CREDS_COMM
)
1553 m
|= KDBUS_ATTACH_PID_COMM
;
1555 if (mask
& SD_BUS_CREDS_TID_COMM
)
1556 m
|= KDBUS_ATTACH_TID_COMM
;
1558 if (mask
& SD_BUS_CREDS_EXE
)
1559 m
|= KDBUS_ATTACH_EXE
;
1561 if (mask
& SD_BUS_CREDS_CMDLINE
)
1562 m
|= KDBUS_ATTACH_CMDLINE
;
1564 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
))
1565 m
|= KDBUS_ATTACH_CGROUP
;
1567 if (mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
))
1568 m
|= KDBUS_ATTACH_CAPS
;
1570 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
)
1571 m
|= KDBUS_ATTACH_SECLABEL
;
1573 if (mask
& (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
))
1574 m
|= KDBUS_ATTACH_AUDIT
;
1576 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
)
1577 m
|= KDBUS_ATTACH_NAMES
;
1579 if (mask
& SD_BUS_CREDS_DESCRIPTION
)
1580 m
|= KDBUS_ATTACH_CONN_DESCRIPTION
;
1582 if (mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
)
1583 m
|= KDBUS_ATTACH_AUXGROUPS
;
1588 int bus_kernel_create_bus(const char *name
, bool world
, char **s
) {
1589 struct kdbus_cmd
*make
;
1590 struct kdbus_item
*n
;
1597 fd
= open("/sys/fs/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1602 make
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1603 ALIGN8(offsetof(struct kdbus_item
, bloom_parameter
) + sizeof(struct kdbus_bloom_parameter
)) +
1604 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)) +
1605 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + l
+ 1),
1608 make
->size
= offsetof(struct kdbus_cmd
, items
);
1610 /* Set the bloom parameters */
1612 n
->size
= offsetof(struct kdbus_item
, bloom_parameter
) +
1613 sizeof(struct kdbus_bloom_parameter
);
1614 n
->type
= KDBUS_ITEM_BLOOM_PARAMETER
;
1615 n
->bloom_parameter
.size
= DEFAULT_BLOOM_SIZE
;
1616 n
->bloom_parameter
.n_hash
= DEFAULT_BLOOM_N_HASH
;
1618 assert_cc(DEFAULT_BLOOM_SIZE
> 0);
1619 assert_cc(DEFAULT_BLOOM_N_HASH
> 0);
1621 make
->size
+= ALIGN8(n
->size
);
1623 /* Provide all metadata via bus-owner queries */
1624 n
= KDBUS_ITEM_NEXT(n
);
1625 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_SEND
;
1626 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1627 n
->data64
[0] = _KDBUS_ATTACH_ANY
;
1628 make
->size
+= ALIGN8(n
->size
);
1630 /* Set the a good name */
1631 n
= KDBUS_ITEM_NEXT(n
);
1632 sprintf(n
->str
, UID_FMT
"-%s", getuid(), name
);
1633 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1634 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1635 make
->size
+= ALIGN8(n
->size
);
1637 make
->flags
= world
? KDBUS_MAKE_ACCESS_WORLD
: 0;
1639 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
1642 /* Major API change? then the ioctls got shuffled around. */
1643 if (errno
== ENOTTY
)
1644 return -ESOCKTNOSUPPORT
;
1652 p
= strjoin("/sys/fs/kdbus/", n
->str
, "/bus");
1664 int bus_kernel_open_bus_fd(const char *bus
, char **path
) {
1671 len
= strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + strlen("/bus") + 1;
1678 p
= newa(char, len
);
1680 sprintf(p
, "/sys/fs/kdbus/" UID_FMT
"-%s/bus", getuid(), bus
);
1682 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1696 int bus_kernel_try_close(sd_bus
*bus
) {
1697 struct kdbus_cmd byebye
= { .size
= sizeof(byebye
) };
1700 assert(bus
->is_kernel
);
1702 if (ioctl(bus
->input_fd
, KDBUS_CMD_BYEBYE
, &byebye
) < 0)
1708 int bus_kernel_drop_one(int fd
) {
1709 struct kdbus_cmd_recv recv
= {
1710 .size
= sizeof(recv
),
1711 .flags
= KDBUS_RECV_DROP
,
1716 if (ioctl(fd
, KDBUS_CMD_RECV
, &recv
) < 0)
1722 int bus_kernel_realize_attach_flags(sd_bus
*bus
) {
1723 struct kdbus_cmd
*update
;
1724 struct kdbus_item
*n
;
1727 assert(bus
->is_kernel
);
1729 update
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1730 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)),
1734 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_RECV
;
1735 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1736 n
->data64
[0] = bus
->attach_flags
;
1739 offsetof(struct kdbus_cmd
, items
) +
1742 if (ioctl(bus
->input_fd
, KDBUS_CMD_UPDATE
, update
) < 0)
1748 int bus_kernel_get_bus_name(sd_bus
*bus
, char **name
) {
1749 struct kdbus_cmd_info cmd
= {
1750 .size
= sizeof(struct kdbus_cmd_info
),
1752 struct kdbus_info
*info
;
1753 struct kdbus_item
*item
;
1759 assert(bus
->is_kernel
);
1761 r
= ioctl(bus
->input_fd
, KDBUS_CMD_BUS_CREATOR_INFO
, &cmd
);
1765 info
= (struct kdbus_info
*) ((uint8_t*) bus
->kdbus_buffer
+ cmd
.offset
);
1767 KDBUS_ITEM_FOREACH(item
, info
, items
)
1768 if (item
->type
== KDBUS_ITEM_MAKE_NAME
) {
1769 r
= free_and_strdup(&n
, item
->str
);
1773 bus_kernel_cmd_free(bus
, cmd
.offset
);