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 "stdio-util.h"
51 #include "string-util.h"
53 #include "user-util.h"
56 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
58 int bus_kernel_parse_unique_name(const char *s
, uint64_t *id
) {
64 if (!startswith(s
, ":1."))
67 r
= safe_atou64(s
+ 3, id
);
74 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
80 /* Note that p can be NULL, which encodes a region full of
81 * zeroes, which is useful to optimize certain padding
84 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
85 (*d
)->type
= KDBUS_ITEM_PAYLOAD_VEC
;
86 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
89 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
92 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t start
, size_t sz
) {
98 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
99 (*d
)->type
= KDBUS_ITEM_PAYLOAD_MEMFD
;
100 (*d
)->memfd
.fd
= memfd
;
101 (*d
)->memfd
.start
= start
;
102 (*d
)->memfd
.size
= sz
;
104 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
107 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
113 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
114 (*d
)->type
= KDBUS_ITEM_DST_NAME
;
115 memcpy((*d
)->str
, s
, length
+ 1);
117 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
120 static struct kdbus_bloom_filter
*append_bloom(struct kdbus_item
**d
, size_t length
) {
121 struct kdbus_item
*i
;
127 i
->size
= offsetof(struct kdbus_item
, bloom_filter
) +
128 offsetof(struct kdbus_bloom_filter
, data
) +
130 i
->type
= KDBUS_ITEM_BLOOM_FILTER
;
132 *d
= (struct kdbus_item
*) ((uint8_t*) i
+ i
->size
);
134 return &i
->bloom_filter
;
137 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
143 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
144 (*d
)->type
= KDBUS_ITEM_FDS
;
145 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
147 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
150 static void add_bloom_arg(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
151 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
159 e
= stpcpy(buf
, "arg");
161 *(e
++) = '0' + (char) i
;
163 *(e
++) = '0' + (char) (i
/ 10);
164 *(e
++) = '0' + (char) (i
% 10);
168 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
170 strcpy(e
, "-dot-prefix");
171 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '.');
172 strcpy(e
, "-slash-prefix");
173 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '/');
176 static void add_bloom_arg_has(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
177 char buf
[sizeof("arg")-1 + 2 + sizeof("-has")];
185 e
= stpcpy(buf
, "arg");
187 *(e
++) = '0' + (char) i
;
189 *(e
++) = '0' + (char) (i
/ 10);
190 *(e
++) = '0' + (char) (i
% 10);
194 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
197 static int bus_message_setup_bloom(sd_bus_message
*m
, struct kdbus_bloom_filter
*bloom
) {
206 memzero(data
, m
->bus
->bloom_size
);
207 bloom
->generation
= 0;
209 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "message-type", bus_message_type_to_string(m
->header
->type
));
212 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "interface", m
->interface
);
214 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "member", m
->member
);
216 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path", m
->path
);
217 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
);
218 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
, '/');
221 r
= sd_bus_message_rewind(m
, true);
225 for (i
= 0; i
< 64; i
++) {
226 const char *t
, *contents
;
229 r
= sd_bus_message_peek_type(m
, &type
, &contents
);
233 if (IN_SET(type
, SD_BUS_TYPE_STRING
, SD_BUS_TYPE_OBJECT_PATH
, SD_BUS_TYPE_SIGNATURE
)) {
235 /* The bloom filter includes simple strings of any kind */
236 r
= sd_bus_message_read_basic(m
, type
, &t
);
240 add_bloom_arg(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
243 if (type
== SD_BUS_TYPE_ARRAY
&& STR_IN_SET(contents
, "s", "o", "g")) {
245 /* As well as array of simple strings of any kinds */
246 r
= sd_bus_message_enter_container(m
, type
, contents
);
250 while ((r
= sd_bus_message_read_basic(m
, contents
[0], &t
)) > 0)
251 add_bloom_arg_has(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
255 r
= sd_bus_message_exit_container(m
);
260 /* Stop adding to bloom filter as soon as we
261 * run into the first argument we cannot add
269 static int bus_message_setup_kmsg(sd_bus
*b
, sd_bus_message
*m
) {
270 struct bus_body_part
*part
;
271 struct kdbus_item
*d
;
272 const char *destination
;
273 bool well_known
= false;
283 /* We put this together only once, if this message is reused
284 * we reuse the earlier-built version */
288 destination
= m
->destination
?: m
->destination_ptr
;
291 r
= bus_kernel_parse_unique_name(destination
, &dst_id
);
297 /* verify_destination_id will usually be 0, which makes the kernel
298 * driver only look at the provided well-known name. Otherwise,
299 * the kernel will make sure the provided destination id matches
300 * the owner of the provided well-known-name, and fail if they
301 * differ. Currently, this is only needed for bus-proxyd. */
302 dst_id
= m
->verify_destination_id
;
305 dst_id
= KDBUS_DST_ID_BROADCAST
;
307 sz
= offsetof(struct kdbus_msg
, items
);
309 /* Add in fixed header, fields header and payload */
310 sz
+= (1 + m
->n_body_parts
) * ALIGN8(offsetof(struct kdbus_item
, vec
) +
311 MAX(sizeof(struct kdbus_vec
),
312 sizeof(struct kdbus_memfd
)));
314 /* Add space for bloom filter */
315 sz
+= ALIGN8(offsetof(struct kdbus_item
, bloom_filter
) +
316 offsetof(struct kdbus_bloom_filter
, data
) +
319 /* Add in well-known destination header */
321 dl
= strlen(destination
);
322 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
325 /* Add space for unix fds */
327 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
329 m
->kdbus
= memalign(8, sz
);
335 m
->free_kdbus
= true;
336 memzero(m
->kdbus
, sz
);
339 ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_EXPECT_REPLY
) |
340 ((m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_NO_AUTO_START
: 0) |
341 ((m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) ? KDBUS_MSG_SIGNAL
: 0);
343 m
->kdbus
->dst_id
= dst_id
;
344 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS
;
345 m
->kdbus
->cookie
= m
->header
->dbus2
.cookie
;
346 m
->kdbus
->priority
= m
->priority
;
348 if (m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
)
349 m
->kdbus
->cookie_reply
= m
->reply_cookie
;
353 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE
, &now
) == 0);
354 m
->kdbus
->timeout_ns
= now
.tv_sec
* NSEC_PER_SEC
+ now
.tv_nsec
+
355 m
->timeout
* NSEC_PER_USEC
;
361 append_destination(&d
, destination
, dl
);
363 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
365 MESSAGE_FOREACH_PART(part
, i
, m
) {
367 /* If this is padding then simply send a
368 * vector with a NULL data pointer which the
369 * kernel will just pass through. This is the
370 * most efficient way to encode zeroes */
372 append_payload_vec(&d
, NULL
, part
->size
);
376 if (part
->memfd
>= 0 && part
->sealed
&& destination
) {
377 /* Try to send a memfd, if the part is
378 * sealed and this is not a broadcast. Since we can only */
380 append_payload_memfd(&d
, part
->memfd
, part
->memfd_offset
, part
->size
);
384 /* Otherwise, let's send a vector to the actual data.
385 * For that, we need to map it first. */
386 r
= bus_body_part_map(part
);
390 append_payload_vec(&d
, part
->data
, part
->size
);
393 if (m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) {
394 struct kdbus_bloom_filter
*bloom
;
396 bloom
= append_bloom(&d
, m
->bus
->bloom_size
);
397 r
= bus_message_setup_bloom(m
, bloom
);
403 append_fds(&d
, m
->fds
, m
->n_fds
);
405 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
406 assert(m
->kdbus
->size
<= sz
);
415 static void unset_memfds(struct sd_bus_message
*m
) {
416 struct bus_body_part
*part
;
421 /* Make sure the memfds are not freed twice */
422 MESSAGE_FOREACH_PART(part
, i
, m
)
423 if (part
->memfd
>= 0)
427 static void message_set_timestamp(sd_bus
*bus
, sd_bus_message
*m
, const struct kdbus_timestamp
*ts
) {
434 if (!(bus
->attach_flags
& KDBUS_ATTACH_TIMESTAMP
))
437 m
->realtime
= ts
->realtime_ns
/ NSEC_PER_USEC
;
438 m
->monotonic
= ts
->monotonic_ns
/ NSEC_PER_USEC
;
439 m
->seqnum
= ts
->seqnum
;
442 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
443 sd_bus_message
*m
= NULL
;
444 struct kdbus_item
*d
;
446 _cleanup_free_
int *fds
= NULL
;
447 struct bus_header
*header
= NULL
;
449 size_t header_size
= 0, footer_size
= 0;
450 size_t n_bytes
= 0, idx
= 0;
451 const char *destination
= NULL
, *seclabel
= NULL
;
452 bool last_was_memfd
= false;
457 assert(k
->payload_type
== KDBUS_PAYLOAD_DBUS
);
459 KDBUS_ITEM_FOREACH(d
, k
, items
) {
462 l
= d
->size
- offsetof(struct kdbus_item
, data
);
466 case KDBUS_ITEM_PAYLOAD_OFF
:
468 header
= (struct bus_header
*)((uint8_t*) k
+ d
->vec
.offset
);
469 header_size
= d
->vec
.size
;
472 footer
= (uint8_t*) k
+ d
->vec
.offset
;
473 footer_size
= d
->vec
.size
;
475 n_bytes
+= d
->vec
.size
;
476 last_was_memfd
= false;
479 case KDBUS_ITEM_PAYLOAD_MEMFD
:
480 if (!header
) /* memfd cannot be first part */
483 n_bytes
+= d
->memfd
.size
;
484 last_was_memfd
= true;
487 case KDBUS_ITEM_FDS
: {
492 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
497 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
502 case KDBUS_ITEM_SECLABEL
:
508 if (last_was_memfd
) /* memfd cannot be last part */
514 if (header_size
< sizeof(struct bus_header
))
517 /* on kdbus we only speak native endian gvariant, never dbus1
518 * marshalling or reverse endian */
519 if (header
->version
!= 2 ||
520 header
->endian
!= BUS_NATIVE_ENDIAN
)
523 r
= bus_message_from_header(
533 /* The well-known names list is different from the other
534 credentials. If we asked for it, but nothing is there, this
535 means that the list of well-known names is simply empty, not
536 that we lack any data */
538 m
->creds
.mask
|= (SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
) & bus
->creds_mask
;
540 KDBUS_ITEM_FOREACH(d
, k
, items
) {
543 l
= d
->size
- offsetof(struct kdbus_item
, data
);
547 case KDBUS_ITEM_PAYLOAD_OFF
: {
550 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
552 if (idx
+ d
->vec
.size
> begin_body
) {
553 struct bus_body_part
*part
;
555 /* Contains body material */
557 part
= message_append_part(m
);
563 /* A -1 offset is NUL padding. */
564 part
->is_zero
= d
->vec
.offset
== ~0ULL;
566 if (idx
>= begin_body
) {
568 part
->data
= (uint8_t* )k
+ d
->vec
.offset
;
569 part
->size
= d
->vec
.size
;
572 part
->data
= (uint8_t*) k
+ d
->vec
.offset
+ (begin_body
- idx
);
573 part
->size
= d
->vec
.size
- (begin_body
- idx
);
583 case KDBUS_ITEM_PAYLOAD_MEMFD
: {
584 struct bus_body_part
*part
;
586 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
591 part
= message_append_part(m
);
597 part
->memfd
= d
->memfd
.fd
;
598 part
->memfd_offset
= d
->memfd
.start
;
599 part
->size
= d
->memfd
.size
;
602 idx
+= d
->memfd
.size
;
606 case KDBUS_ITEM_PIDS
:
608 /* The PID/TID might be missing, when the data
609 * is faked by a bus proxy and it lacks that
610 * information about the real client (since
611 * SO_PEERCRED is used for that). Also kernel
612 * namespacing might make some of this data
613 * unavailable when untranslatable. */
615 if (d
->pids
.pid
> 0) {
616 m
->creds
.pid
= (pid_t
) d
->pids
.pid
;
617 m
->creds
.mask
|= SD_BUS_CREDS_PID
& bus
->creds_mask
;
620 if (d
->pids
.tid
> 0) {
621 m
->creds
.tid
= (pid_t
) d
->pids
.tid
;
622 m
->creds
.mask
|= SD_BUS_CREDS_TID
& bus
->creds_mask
;
625 if (d
->pids
.ppid
> 0) {
626 m
->creds
.ppid
= (pid_t
) d
->pids
.ppid
;
627 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
628 } else if (d
->pids
.pid
== 1) {
630 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
635 case KDBUS_ITEM_CREDS
:
637 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
638 * missing too (see above). */
640 if ((uid_t
) d
->creds
.uid
!= UID_INVALID
) {
641 m
->creds
.uid
= (uid_t
) d
->creds
.uid
;
642 m
->creds
.mask
|= SD_BUS_CREDS_UID
& bus
->creds_mask
;
645 if ((uid_t
) d
->creds
.euid
!= UID_INVALID
) {
646 m
->creds
.euid
= (uid_t
) d
->creds
.euid
;
647 m
->creds
.mask
|= SD_BUS_CREDS_EUID
& bus
->creds_mask
;
650 if ((uid_t
) d
->creds
.suid
!= UID_INVALID
) {
651 m
->creds
.suid
= (uid_t
) d
->creds
.suid
;
652 m
->creds
.mask
|= SD_BUS_CREDS_SUID
& bus
->creds_mask
;
655 if ((uid_t
) d
->creds
.fsuid
!= UID_INVALID
) {
656 m
->creds
.fsuid
= (uid_t
) d
->creds
.fsuid
;
657 m
->creds
.mask
|= SD_BUS_CREDS_FSUID
& bus
->creds_mask
;
660 if ((gid_t
) d
->creds
.gid
!= GID_INVALID
) {
661 m
->creds
.gid
= (gid_t
) d
->creds
.gid
;
662 m
->creds
.mask
|= SD_BUS_CREDS_GID
& bus
->creds_mask
;
665 if ((gid_t
) d
->creds
.egid
!= GID_INVALID
) {
666 m
->creds
.egid
= (gid_t
) d
->creds
.egid
;
667 m
->creds
.mask
|= SD_BUS_CREDS_EGID
& bus
->creds_mask
;
670 if ((gid_t
) d
->creds
.sgid
!= GID_INVALID
) {
671 m
->creds
.sgid
= (gid_t
) d
->creds
.sgid
;
672 m
->creds
.mask
|= SD_BUS_CREDS_SGID
& bus
->creds_mask
;
675 if ((gid_t
) d
->creds
.fsgid
!= GID_INVALID
) {
676 m
->creds
.fsgid
= (gid_t
) d
->creds
.fsgid
;
677 m
->creds
.mask
|= SD_BUS_CREDS_FSGID
& bus
->creds_mask
;
682 case KDBUS_ITEM_TIMESTAMP
:
683 message_set_timestamp(bus
, m
, &d
->timestamp
);
686 case KDBUS_ITEM_PID_COMM
:
687 m
->creds
.comm
= d
->str
;
688 m
->creds
.mask
|= SD_BUS_CREDS_COMM
& bus
->creds_mask
;
691 case KDBUS_ITEM_TID_COMM
:
692 m
->creds
.tid_comm
= d
->str
;
693 m
->creds
.mask
|= SD_BUS_CREDS_TID_COMM
& bus
->creds_mask
;
697 m
->creds
.exe
= d
->str
;
698 m
->creds
.mask
|= SD_BUS_CREDS_EXE
& bus
->creds_mask
;
701 case KDBUS_ITEM_CMDLINE
:
702 m
->creds
.cmdline
= d
->str
;
703 m
->creds
.cmdline_size
= l
;
704 m
->creds
.mask
|= SD_BUS_CREDS_CMDLINE
& bus
->creds_mask
;
707 case KDBUS_ITEM_CGROUP
:
708 m
->creds
.cgroup
= d
->str
;
709 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
;
711 r
= bus_get_root_path(bus
);
715 m
->creds
.cgroup_root
= bus
->cgroup_root
;
718 case KDBUS_ITEM_AUDIT
:
719 m
->creds
.audit_session_id
= (uint32_t) d
->audit
.sessionid
;
720 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
& bus
->creds_mask
;
722 m
->creds
.audit_login_uid
= (uid_t
) d
->audit
.loginuid
;
723 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
& bus
->creds_mask
;
726 case KDBUS_ITEM_CAPS
:
727 if (d
->caps
.last_cap
!= cap_last_cap() ||
728 d
->size
- offsetof(struct kdbus_item
, caps
.caps
) < DIV_ROUND_UP(d
->caps
.last_cap
, 32U) * 4 * 4) {
733 m
->creds
.capability
= d
->caps
.caps
;
734 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
;
737 case KDBUS_ITEM_DST_NAME
:
738 if (!service_name_is_valid(d
->str
)) {
743 destination
= d
->str
;
746 case KDBUS_ITEM_OWNED_NAME
:
747 if (!service_name_is_valid(d
->name
.name
)) {
752 if (bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
756 /* We just extend the array here, but
757 * do not allocate the strings inside
758 * of it, instead we just point to our
759 * buffer directly. */
760 n
= strv_length(m
->creds
.well_known_names
);
761 wkn
= realloc(m
->creds
.well_known_names
, (n
+ 2) * sizeof(char*));
767 wkn
[n
] = d
->name
.name
;
769 m
->creds
.well_known_names
= wkn
;
771 m
->creds
.mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
775 case KDBUS_ITEM_CONN_DESCRIPTION
:
776 m
->creds
.description
= d
->str
;
777 m
->creds
.mask
|= SD_BUS_CREDS_DESCRIPTION
& bus
->creds_mask
;
780 case KDBUS_ITEM_AUXGROUPS
:
782 if (bus
->creds_mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
786 n
= (d
->size
- offsetof(struct kdbus_item
, data64
)) / sizeof(uint64_t);
793 for (i
= 0; i
< n
; i
++)
796 m
->creds
.supplementary_gids
= g
;
797 m
->creds
.n_supplementary_gids
= n
;
798 m
->creds
.mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
804 case KDBUS_ITEM_SECLABEL
:
805 case KDBUS_ITEM_BLOOM_FILTER
:
809 log_debug("Got unknown field from kernel %llu", d
->type
);
813 /* If we requested the list of well-known names to be appended
814 * and the sender had none no item for it will be
815 * attached. However, this does *not* mean that the kernel
816 * didn't want to provide this information to us. Hence, let's
817 * explicitly mark this information as available if it was
819 m
->creds
.mask
|= bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
;
821 r
= bus_message_parse_fields(m
);
825 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
826 if ((uint64_t) m
->header
->dbus2
.cookie
!= k
->cookie
) {
831 /* Refuse messages where the reply flag doesn't match up */
832 if (!(m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) != !!(k
->flags
& KDBUS_MSG_EXPECT_REPLY
)) {
837 /* Refuse reply messages where the reply cookie doesn't match up */
838 if ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) && m
->reply_cookie
!= k
->cookie_reply
) {
843 /* Refuse messages where the autostart flag doesn't match up */
844 if (!(m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) != !(k
->flags
& KDBUS_MSG_NO_AUTO_START
)) {
849 /* Override information from the user header with data from the kernel */
850 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
851 bus_message_set_sender_driver(bus
, m
);
853 xsprintf(m
->sender_buffer
, ":1.%llu",
854 (unsigned long long)k
->src_id
);
855 m
->sender
= m
->creds
.unique_name
= m
->sender_buffer
;
859 m
->destination
= destination
;
860 else if (k
->dst_id
== KDBUS_DST_ID_BROADCAST
)
861 m
->destination
= NULL
;
862 else if (k
->dst_id
== KDBUS_DST_ID_NAME
)
863 m
->destination
= bus
->unique_name
; /* fill in unique name if the well-known name is missing */
865 xsprintf(m
->destination_buffer
, ":1.%llu",
866 (unsigned long long)k
->dst_id
);
867 m
->destination
= m
->destination_buffer
;
870 /* We take possession of the kmsg struct now */
872 m
->release_kdbus
= true;
876 bus
->rqueue
[bus
->rqueue_size
++] = m
;
882 sd_bus_message_unref(m
);
887 int bus_kernel_take_fd(sd_bus
*b
) {
888 struct kdbus_bloom_parameter
*bloom
= NULL
;
889 struct kdbus_item
*items
, *item
;
890 struct kdbus_cmd_hello
*hello
;
891 _cleanup_free_
char *g
= NULL
;
893 size_t l
= 0, m
= 0, sz
;
903 if (b
->description
) {
904 g
= bus_label_escape(b
->description
);
912 /* If no name is explicitly set, we'll include a hint
913 * indicating the library implementation, a hint which
914 * kind of bus this is and the thread name */
916 assert_se(prctl(PR_GET_NAME
, (unsigned long) pr
) >= 0);
919 name
= b
->is_system
? "sd-system" :
920 b
->is_user
? "sd-user" : "sd";
922 _cleanup_free_
char *e
= NULL
;
924 e
= bus_label_escape(pr
);
928 g
= strappend(b
->is_system
? "sd-system-" :
929 b
->is_user
? "sd-user-" : "sd-",
937 b
->description
= bus_label_unescape(name
);
944 sz
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
)) +
945 ALIGN8(offsetof(struct kdbus_item
, str
) + m
+ 1);
947 if (b
->fake_creds_valid
)
948 sz
+= ALIGN8(offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
));
950 if (b
->fake_pids_valid
)
951 sz
+= ALIGN8(offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
));
954 l
= strlen(b
->fake_label
);
955 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + l
+ 1);
958 hello
= alloca0_align(sz
, 8);
960 hello
->flags
= b
->hello_flags
;
961 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
962 hello
->attach_flags_recv
= b
->attach_flags
;
963 hello
->pool_size
= KDBUS_POOL_SIZE
;
967 item
->size
= offsetof(struct kdbus_item
, str
) + m
+ 1;
968 item
->type
= KDBUS_ITEM_CONN_DESCRIPTION
;
969 memcpy(item
->str
, name
, m
+ 1);
970 item
= KDBUS_ITEM_NEXT(item
);
972 if (b
->fake_creds_valid
) {
973 item
->size
= offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
);
974 item
->type
= KDBUS_ITEM_CREDS
;
975 item
->creds
= b
->fake_creds
;
977 item
= KDBUS_ITEM_NEXT(item
);
980 if (b
->fake_pids_valid
) {
981 item
->size
= offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
);
982 item
->type
= KDBUS_ITEM_PIDS
;
983 item
->pids
= b
->fake_pids
;
985 item
= KDBUS_ITEM_NEXT(item
);
989 item
->size
= offsetof(struct kdbus_item
, str
) + l
+ 1;
990 item
->type
= KDBUS_ITEM_SECLABEL
;
991 memcpy(item
->str
, b
->fake_label
, l
+1);
994 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
997 /* If the ioctl is not supported we assume that the
998 * API version changed in a major incompatible way,
999 * let's indicate an API incompatibility in this
1001 return -ESOCKTNOSUPPORT
;
1006 if (!b
->kdbus_buffer
) {
1007 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
, MAP_SHARED
, b
->input_fd
, 0);
1008 if (b
->kdbus_buffer
== MAP_FAILED
) {
1009 b
->kdbus_buffer
= NULL
;
1015 /* The higher 32bit of the bus_flags fields are considered
1016 * 'incompatible flags'. Refuse them all for now. */
1017 if (hello
->bus_flags
> 0xFFFFFFFFULL
) {
1018 r
= -ESOCKTNOSUPPORT
;
1022 /* extract bloom parameters from items */
1023 items
= (void*)((uint8_t*)b
->kdbus_buffer
+ hello
->offset
);
1024 KDBUS_FOREACH(item
, items
, hello
->items_size
) {
1025 switch (item
->type
) {
1026 case KDBUS_ITEM_BLOOM_PARAMETER
:
1027 bloom
= &item
->bloom_parameter
;
1032 if (!bloom
|| !bloom_validate_parameters((size_t) bloom
->size
, (unsigned) bloom
->n_hash
)) {
1037 b
->bloom_size
= (size_t) bloom
->size
;
1038 b
->bloom_n_hash
= (unsigned) bloom
->n_hash
;
1040 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0) {
1045 b
->unique_id
= hello
->id
;
1047 b
->is_kernel
= true;
1048 b
->bus_client
= true;
1049 b
->can_fds
= !!(hello
->flags
& KDBUS_HELLO_ACCEPT_FD
);
1050 b
->message_version
= 2;
1051 b
->message_endian
= BUS_NATIVE_ENDIAN
;
1053 /* the kernel told us the UUID of the underlying bus */
1054 memcpy(b
->server_id
.bytes
, hello
->id128
, sizeof(b
->server_id
.bytes
));
1056 /* free returned items */
1057 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1058 return bus_start_running(b
);
1061 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1065 int bus_kernel_connect(sd_bus
*b
) {
1067 assert(b
->input_fd
< 0);
1068 assert(b
->output_fd
< 0);
1074 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1075 if (b
->input_fd
< 0)
1078 b
->output_fd
= b
->input_fd
;
1080 return bus_kernel_take_fd(b
);
1083 int bus_kernel_cmd_free(sd_bus
*bus
, uint64_t offset
) {
1084 struct kdbus_cmd_free cmd
= {
1085 .size
= sizeof(cmd
),
1091 assert(bus
->is_kernel
);
1093 r
= ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &cmd
);
1100 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
1101 struct kdbus_item
*d
;
1106 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1107 if (d
->type
== KDBUS_ITEM_FDS
)
1108 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
1109 else if (d
->type
== KDBUS_ITEM_PAYLOAD_MEMFD
)
1110 safe_close(d
->memfd
.fd
);
1113 bus_kernel_cmd_free(bus
, (uint8_t*) k
- (uint8_t*) bus
->kdbus_buffer
);
1116 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
, bool hint_sync_call
) {
1117 struct kdbus_cmd_send cmd
= { };
1122 assert(bus
->state
== BUS_RUNNING
);
1124 /* If we can't deliver, we want room for the error message */
1125 r
= bus_rqueue_make_room(bus
);
1129 r
= bus_message_setup_kmsg(bus
, m
);
1133 cmd
.size
= sizeof(cmd
);
1134 cmd
.msg_address
= (uintptr_t)m
->kdbus
;
1136 /* If this is a synchronous method call, then let's tell the
1137 * kernel, so that it can pass CPU time/scheduling to the
1138 * destination for the time, if it wants to. If we
1139 * synchronously wait for the result anyway, we won't need CPU
1141 if (hint_sync_call
) {
1142 m
->kdbus
->flags
|= KDBUS_MSG_EXPECT_REPLY
;
1143 cmd
.flags
|= KDBUS_SEND_SYNC_REPLY
;
1146 r
= ioctl(bus
->output_fd
, KDBUS_CMD_SEND
, &cmd
);
1148 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1149 sd_bus_message
*reply
;
1151 if (errno
== EAGAIN
|| errno
== EINTR
)
1153 else if (errno
== ENXIO
|| errno
== ESRCH
) {
1155 /* ENXIO: unique name not known
1156 * ESRCH: well-known name not known */
1158 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1159 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Destination %s not known", m
->destination
);
1161 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m
->destination
);
1165 } else if (errno
== EADDRNOTAVAIL
) {
1167 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1169 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1170 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Activation of %s not requested", m
->destination
);
1172 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m
->destination
);
1178 r
= bus_message_new_synthetic_error(
1180 BUS_MESSAGE_COOKIE(m
),
1187 r
= bus_seal_synthetic_message(bus
, reply
);
1191 bus
->rqueue
[bus
->rqueue_size
++] = reply
;
1193 } else if (hint_sync_call
) {
1194 struct kdbus_msg
*k
;
1196 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ cmd
.reply
.offset
);
1199 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1201 r
= bus_kernel_make_message(bus
, k
);
1203 close_kdbus_msg(bus
, k
);
1205 /* Anybody can send us invalid messages, let's just drop them. */
1206 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
)
1207 log_debug_errno(r
, "Ignoring invalid synchronous reply: %m");
1212 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1213 close_kdbus_msg(bus
, k
);
1220 static int push_name_owner_changed(
1223 const char *old_owner
,
1224 const char *new_owner
,
1225 const struct kdbus_timestamp
*ts
) {
1227 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1232 r
= sd_bus_message_new_signal(
1235 "/org/freedesktop/DBus",
1236 "org.freedesktop.DBus",
1237 "NameOwnerChanged");
1241 r
= sd_bus_message_append(m
, "sss", name
, old_owner
, new_owner
);
1245 bus_message_set_sender_driver(bus
, m
);
1246 message_set_timestamp(bus
, m
, ts
);
1248 r
= bus_seal_synthetic_message(bus
, m
);
1252 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1258 static int translate_name_change(
1260 const struct kdbus_msg
*k
,
1261 const struct kdbus_item
*d
,
1262 const struct kdbus_timestamp
*ts
) {
1264 char new_owner
[UNIQUE_NAME_MAX
], old_owner
[UNIQUE_NAME_MAX
];
1270 if (d
->type
== KDBUS_ITEM_NAME_ADD
|| (d
->name_change
.old_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
)))
1273 sprintf(old_owner
, ":1.%llu", (unsigned long long) d
->name_change
.old_id
.id
);
1275 if (d
->type
== KDBUS_ITEM_NAME_REMOVE
|| (d
->name_change
.new_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
))) {
1277 if (isempty(old_owner
))
1282 sprintf(new_owner
, ":1.%llu", (unsigned long long) d
->name_change
.new_id
.id
);
1284 return push_name_owner_changed(bus
, d
->name_change
.name
, old_owner
, new_owner
, ts
);
1287 static int translate_id_change(
1289 const struct kdbus_msg
*k
,
1290 const struct kdbus_item
*d
,
1291 const struct kdbus_timestamp
*ts
) {
1293 char owner
[UNIQUE_NAME_MAX
];
1299 sprintf(owner
, ":1.%llu", d
->id_change
.id
);
1301 return push_name_owner_changed(
1303 d
->type
== KDBUS_ITEM_ID_ADD
? NULL
: owner
,
1304 d
->type
== KDBUS_ITEM_ID_ADD
? owner
: NULL
,
1308 static int translate_reply(
1310 const struct kdbus_msg
*k
,
1311 const struct kdbus_item
*d
,
1312 const struct kdbus_timestamp
*ts
) {
1314 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1321 r
= bus_message_new_synthetic_error(
1324 d
->type
== KDBUS_ITEM_REPLY_TIMEOUT
?
1325 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call timed out") :
1326 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call peer died"),
1331 message_set_timestamp(bus
, m
, ts
);
1333 r
= bus_seal_synthetic_message(bus
, m
);
1337 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1343 static int bus_kernel_translate_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
1344 static int (* const translate
[])(sd_bus
*bus
, const struct kdbus_msg
*k
, const struct kdbus_item
*d
, const struct kdbus_timestamp
*ts
) = {
1345 [KDBUS_ITEM_NAME_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1346 [KDBUS_ITEM_NAME_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1347 [KDBUS_ITEM_NAME_CHANGE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1349 [KDBUS_ITEM_ID_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1350 [KDBUS_ITEM_ID_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1352 [KDBUS_ITEM_REPLY_TIMEOUT
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1353 [KDBUS_ITEM_REPLY_DEAD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1356 struct kdbus_item
*d
, *found
= NULL
;
1357 struct kdbus_timestamp
*ts
= NULL
;
1361 assert(k
->payload_type
== KDBUS_PAYLOAD_KERNEL
);
1363 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1364 if (d
->type
== KDBUS_ITEM_TIMESTAMP
)
1366 else if (d
->type
>= _KDBUS_ITEM_KERNEL_BASE
&& d
->type
< _KDBUS_ITEM_KERNEL_BASE
+ ELEMENTSOF(translate
)) {
1371 log_debug("Got unknown field from kernel %llu", d
->type
);
1375 log_debug("Didn't find a kernel message to translate.");
1379 return translate
[found
->type
- _KDBUS_ITEM_KERNEL_BASE
](bus
, k
, found
, ts
);
1382 int bus_kernel_read_message(sd_bus
*bus
, bool hint_priority
, int64_t priority
) {
1383 struct kdbus_cmd_recv recv
= { .size
= sizeof(recv
) };
1384 struct kdbus_msg
*k
;
1389 r
= bus_rqueue_make_room(bus
);
1393 if (hint_priority
) {
1394 recv
.flags
|= KDBUS_RECV_USE_PRIORITY
;
1395 recv
.priority
= priority
;
1398 r
= ioctl(bus
->input_fd
, KDBUS_CMD_RECV
, &recv
);
1399 if (recv
.return_flags
& KDBUS_RECV_RETURN_DROPPED_MSGS
)
1400 log_debug("%s: kdbus reports %" PRIu64
" dropped broadcast messages, ignoring.", strna(bus
->description
), (uint64_t) recv
.dropped_msgs
);
1402 if (errno
== EAGAIN
)
1408 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ recv
.msg
.offset
);
1409 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1410 r
= bus_kernel_make_message(bus
, k
);
1412 /* Anybody can send us invalid messages, let's just drop them. */
1413 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
) {
1414 log_debug_errno(r
, "Ignoring invalid message: %m");
1419 close_kdbus_msg(bus
, k
);
1420 } else if (k
->payload_type
== KDBUS_PAYLOAD_KERNEL
) {
1421 r
= bus_kernel_translate_message(bus
, k
);
1422 close_kdbus_msg(bus
, k
);
1424 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1426 close_kdbus_msg(bus
, k
);
1429 return r
< 0 ? r
: 1;
1432 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *mapped
, size_t *allocated
) {
1433 struct memfd_cache
*c
;
1440 if (!bus
|| !bus
->is_kernel
)
1443 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1445 if (bus
->n_memfd_cache
<= 0) {
1448 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1450 r
= memfd_new(bus
->description
);
1460 c
= &bus
->memfd_cache
[--bus
->n_memfd_cache
];
1463 assert(c
->mapped
== 0 || c
->address
);
1465 *address
= c
->address
;
1466 *mapped
= c
->mapped
;
1467 *allocated
= c
->allocated
;
1470 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1475 static void close_and_munmap(int fd
, void *address
, size_t size
) {
1477 assert_se(munmap(address
, PAGE_ALIGN(size
)) >= 0);
1482 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t mapped
, size_t allocated
) {
1483 struct memfd_cache
*c
;
1484 uint64_t max_mapped
= PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX
);
1487 assert(mapped
== 0 || address
);
1489 if (!bus
|| !bus
->is_kernel
) {
1490 close_and_munmap(fd
, address
, mapped
);
1494 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1496 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
1497 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1499 close_and_munmap(fd
, address
, mapped
);
1503 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
1505 c
->address
= address
;
1507 /* If overly long, let's return a bit to the OS */
1508 if (mapped
> max_mapped
) {
1509 assert_se(memfd_set_size(fd
, max_mapped
) >= 0);
1510 assert_se(munmap((uint8_t*) address
+ max_mapped
, PAGE_ALIGN(mapped
- max_mapped
)) >= 0);
1511 c
->mapped
= c
->allocated
= max_mapped
;
1514 c
->allocated
= allocated
;
1517 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1520 void bus_kernel_flush_memfd(sd_bus
*b
) {
1525 for (i
= 0; i
< b
->n_memfd_cache
; i
++)
1526 close_and_munmap(b
->memfd_cache
[i
].fd
, b
->memfd_cache
[i
].address
, b
->memfd_cache
[i
].mapped
);
1529 uint64_t request_name_flags_to_kdbus(uint64_t flags
) {
1532 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
1533 f
|= KDBUS_NAME_ALLOW_REPLACEMENT
;
1535 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
1536 f
|= KDBUS_NAME_REPLACE_EXISTING
;
1538 if (flags
& SD_BUS_NAME_QUEUE
)
1539 f
|= KDBUS_NAME_QUEUE
;
1544 uint64_t attach_flags_to_kdbus(uint64_t mask
) {
1547 if (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
|
1548 SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
))
1549 m
|= KDBUS_ATTACH_CREDS
;
1551 if (mask
& (SD_BUS_CREDS_PID
|SD_BUS_CREDS_TID
|SD_BUS_CREDS_PPID
))
1552 m
|= KDBUS_ATTACH_PIDS
;
1554 if (mask
& SD_BUS_CREDS_COMM
)
1555 m
|= KDBUS_ATTACH_PID_COMM
;
1557 if (mask
& SD_BUS_CREDS_TID_COMM
)
1558 m
|= KDBUS_ATTACH_TID_COMM
;
1560 if (mask
& SD_BUS_CREDS_EXE
)
1561 m
|= KDBUS_ATTACH_EXE
;
1563 if (mask
& SD_BUS_CREDS_CMDLINE
)
1564 m
|= KDBUS_ATTACH_CMDLINE
;
1566 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
))
1567 m
|= KDBUS_ATTACH_CGROUP
;
1569 if (mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
))
1570 m
|= KDBUS_ATTACH_CAPS
;
1572 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
)
1573 m
|= KDBUS_ATTACH_SECLABEL
;
1575 if (mask
& (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
))
1576 m
|= KDBUS_ATTACH_AUDIT
;
1578 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
)
1579 m
|= KDBUS_ATTACH_NAMES
;
1581 if (mask
& SD_BUS_CREDS_DESCRIPTION
)
1582 m
|= KDBUS_ATTACH_CONN_DESCRIPTION
;
1584 if (mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
)
1585 m
|= KDBUS_ATTACH_AUXGROUPS
;
1590 int bus_kernel_create_bus(const char *name
, bool world
, char **s
) {
1591 struct kdbus_cmd
*make
;
1592 struct kdbus_item
*n
;
1599 fd
= open("/sys/fs/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1604 make
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1605 ALIGN8(offsetof(struct kdbus_item
, bloom_parameter
) + sizeof(struct kdbus_bloom_parameter
)) +
1606 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)) +
1607 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + l
+ 1),
1610 make
->size
= offsetof(struct kdbus_cmd
, items
);
1612 /* Set the bloom parameters */
1614 n
->size
= offsetof(struct kdbus_item
, bloom_parameter
) +
1615 sizeof(struct kdbus_bloom_parameter
);
1616 n
->type
= KDBUS_ITEM_BLOOM_PARAMETER
;
1617 n
->bloom_parameter
.size
= DEFAULT_BLOOM_SIZE
;
1618 n
->bloom_parameter
.n_hash
= DEFAULT_BLOOM_N_HASH
;
1620 assert_cc(DEFAULT_BLOOM_SIZE
> 0);
1621 assert_cc(DEFAULT_BLOOM_N_HASH
> 0);
1623 make
->size
+= ALIGN8(n
->size
);
1625 /* Provide all metadata via bus-owner queries */
1626 n
= KDBUS_ITEM_NEXT(n
);
1627 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_SEND
;
1628 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1629 n
->data64
[0] = _KDBUS_ATTACH_ANY
;
1630 make
->size
+= ALIGN8(n
->size
);
1632 /* Set the a good name */
1633 n
= KDBUS_ITEM_NEXT(n
);
1634 sprintf(n
->str
, UID_FMT
"-%s", getuid(), name
);
1635 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1636 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1637 make
->size
+= ALIGN8(n
->size
);
1639 make
->flags
= world
? KDBUS_MAKE_ACCESS_WORLD
: 0;
1641 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
1644 /* Major API change? then the ioctls got shuffled around. */
1645 if (errno
== ENOTTY
)
1646 return -ESOCKTNOSUPPORT
;
1654 p
= strjoin("/sys/fs/kdbus/", n
->str
, "/bus", NULL
);
1666 int bus_kernel_open_bus_fd(const char *bus
, char **path
) {
1673 len
= strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + strlen("/bus") + 1;
1680 p
= newa(char, len
);
1682 sprintf(p
, "/sys/fs/kdbus/" UID_FMT
"-%s/bus", getuid(), bus
);
1684 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1698 int bus_kernel_create_endpoint(const char *bus_name
, const char *ep_name
, char **ep_path
) {
1699 _cleanup_free_
char *path
= NULL
;
1700 struct kdbus_cmd
*make
;
1701 struct kdbus_item
*n
;
1705 fd
= bus_kernel_open_bus_fd(bus_name
, &path
);
1709 make
= alloca0_align(ALIGN8(offsetof(struct kdbus_cmd
, items
)) +
1710 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(ep_name
) + 1),
1712 make
->size
= ALIGN8(offsetof(struct kdbus_cmd
, items
));
1713 make
->flags
= KDBUS_MAKE_ACCESS_WORLD
;
1716 sprintf(n
->str
, UID_FMT
"-%s", getuid(), ep_name
);
1717 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1718 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1719 make
->size
+= ALIGN8(n
->size
);
1722 if (ioctl(fd
, KDBUS_CMD_ENDPOINT_MAKE
, make
) < 0) {
1730 p
= strjoin(dirname(path
), "/", name
, NULL
);
1742 int bus_kernel_try_close(sd_bus
*bus
) {
1743 struct kdbus_cmd byebye
= { .size
= sizeof(byebye
) };
1746 assert(bus
->is_kernel
);
1748 if (ioctl(bus
->input_fd
, KDBUS_CMD_BYEBYE
, &byebye
) < 0)
1754 int bus_kernel_drop_one(int fd
) {
1755 struct kdbus_cmd_recv recv
= {
1756 .size
= sizeof(recv
),
1757 .flags
= KDBUS_RECV_DROP
,
1762 if (ioctl(fd
, KDBUS_CMD_RECV
, &recv
) < 0)
1768 int bus_kernel_realize_attach_flags(sd_bus
*bus
) {
1769 struct kdbus_cmd
*update
;
1770 struct kdbus_item
*n
;
1773 assert(bus
->is_kernel
);
1775 update
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1776 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)),
1780 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_RECV
;
1781 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1782 n
->data64
[0] = bus
->attach_flags
;
1785 offsetof(struct kdbus_cmd
, items
) +
1788 if (ioctl(bus
->input_fd
, KDBUS_CMD_UPDATE
, update
) < 0)
1794 int bus_kernel_get_bus_name(sd_bus
*bus
, char **name
) {
1795 struct kdbus_cmd_info cmd
= {
1796 .size
= sizeof(struct kdbus_cmd_info
),
1798 struct kdbus_info
*info
;
1799 struct kdbus_item
*item
;
1805 assert(bus
->is_kernel
);
1807 r
= ioctl(bus
->input_fd
, KDBUS_CMD_BUS_CREATOR_INFO
, &cmd
);
1811 info
= (struct kdbus_info
*) ((uint8_t*) bus
->kdbus_buffer
+ cmd
.offset
);
1813 KDBUS_ITEM_FOREACH(item
, info
, items
)
1814 if (item
->type
== KDBUS_ITEM_MAKE_NAME
) {
1815 r
= free_and_strdup(&n
, item
->str
);
1819 bus_kernel_cmd_free(bus
, cmd
.offset
);