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 "bus-bloom.h"
38 #include "bus-internal.h"
39 #include "bus-kernel.h"
40 #include "bus-label.h"
41 #include "bus-message.h"
43 #include "capability.h"
46 #include "formats-util.h"
47 #include "memfd-util.h"
48 #include "parse-util.h"
49 #include "string-util.h"
53 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
55 int bus_kernel_parse_unique_name(const char *s
, uint64_t *id
) {
61 if (!startswith(s
, ":1."))
64 r
= safe_atou64(s
+ 3, id
);
71 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
77 /* Note that p can be NULL, which encodes a region full of
78 * zeroes, which is useful to optimize certain padding
81 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
82 (*d
)->type
= KDBUS_ITEM_PAYLOAD_VEC
;
83 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
86 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
89 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t start
, size_t sz
) {
95 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
96 (*d
)->type
= KDBUS_ITEM_PAYLOAD_MEMFD
;
97 (*d
)->memfd
.fd
= memfd
;
98 (*d
)->memfd
.start
= start
;
99 (*d
)->memfd
.size
= sz
;
101 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
104 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
110 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
111 (*d
)->type
= KDBUS_ITEM_DST_NAME
;
112 memcpy((*d
)->str
, s
, length
+ 1);
114 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
117 static struct kdbus_bloom_filter
*append_bloom(struct kdbus_item
**d
, size_t length
) {
118 struct kdbus_item
*i
;
124 i
->size
= offsetof(struct kdbus_item
, bloom_filter
) +
125 offsetof(struct kdbus_bloom_filter
, data
) +
127 i
->type
= KDBUS_ITEM_BLOOM_FILTER
;
129 *d
= (struct kdbus_item
*) ((uint8_t*) i
+ i
->size
);
131 return &i
->bloom_filter
;
134 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
140 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
141 (*d
)->type
= KDBUS_ITEM_FDS
;
142 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
144 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
147 static void add_bloom_arg(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
148 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
156 e
= stpcpy(buf
, "arg");
158 *(e
++) = '0' + (char) i
;
160 *(e
++) = '0' + (char) (i
/ 10);
161 *(e
++) = '0' + (char) (i
% 10);
165 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
167 strcpy(e
, "-dot-prefix");
168 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '.');
169 strcpy(e
, "-slash-prefix");
170 bloom_add_prefixes(data
, size
, n_hash
, buf
, t
, '/');
173 static void add_bloom_arg_has(void *data
, size_t size
, unsigned n_hash
, unsigned i
, const char *t
) {
174 char buf
[sizeof("arg")-1 + 2 + sizeof("-has")];
182 e
= stpcpy(buf
, "arg");
184 *(e
++) = '0' + (char) i
;
186 *(e
++) = '0' + (char) (i
/ 10);
187 *(e
++) = '0' + (char) (i
% 10);
191 bloom_add_pair(data
, size
, n_hash
, buf
, t
);
194 static int bus_message_setup_bloom(sd_bus_message
*m
, struct kdbus_bloom_filter
*bloom
) {
203 memzero(data
, m
->bus
->bloom_size
);
204 bloom
->generation
= 0;
206 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "message-type", bus_message_type_to_string(m
->header
->type
));
209 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "interface", m
->interface
);
211 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "member", m
->member
);
213 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path", m
->path
);
214 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
);
215 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
, '/');
218 r
= sd_bus_message_rewind(m
, true);
222 for (i
= 0; i
< 64; i
++) {
223 const char *t
, *contents
;
226 r
= sd_bus_message_peek_type(m
, &type
, &contents
);
230 if (IN_SET(type
, SD_BUS_TYPE_STRING
, SD_BUS_TYPE_OBJECT_PATH
, SD_BUS_TYPE_SIGNATURE
)) {
232 /* The bloom filter includes simple strings of any kind */
233 r
= sd_bus_message_read_basic(m
, type
, &t
);
237 add_bloom_arg(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
240 if (type
== SD_BUS_TYPE_ARRAY
&& STR_IN_SET(contents
, "s", "o", "g")) {
242 /* As well as array of simple strings of any kinds */
243 r
= sd_bus_message_enter_container(m
, type
, contents
);
247 while ((r
= sd_bus_message_read_basic(m
, contents
[0], &t
)) > 0)
248 add_bloom_arg_has(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, i
, t
);
252 r
= sd_bus_message_exit_container(m
);
257 /* Stop adding to bloom filter as soon as we
258 * run into the first argument we cannot add
266 static int bus_message_setup_kmsg(sd_bus
*b
, sd_bus_message
*m
) {
267 struct bus_body_part
*part
;
268 struct kdbus_item
*d
;
269 const char *destination
;
280 /* We put this together only once, if this message is reused
281 * we reuse the earlier-built version */
285 destination
= m
->destination
?: m
->destination_ptr
;
288 r
= bus_kernel_parse_unique_name(destination
, &unique
);
296 sz
= offsetof(struct kdbus_msg
, items
);
298 /* Add in fixed header, fields header and payload */
299 sz
+= (1 + m
->n_body_parts
) * ALIGN8(offsetof(struct kdbus_item
, vec
) +
300 MAX(sizeof(struct kdbus_vec
),
301 sizeof(struct kdbus_memfd
)));
303 /* Add space for bloom filter */
304 sz
+= ALIGN8(offsetof(struct kdbus_item
, bloom_filter
) +
305 offsetof(struct kdbus_bloom_filter
, data
) +
308 /* Add in well-known destination header */
310 dl
= strlen(destination
);
311 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
314 /* Add space for unix fds */
316 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
318 m
->kdbus
= memalign(8, sz
);
324 m
->free_kdbus
= true;
325 memzero(m
->kdbus
, sz
);
328 ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_EXPECT_REPLY
) |
329 ((m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_NO_AUTO_START
: 0) |
330 ((m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) ? KDBUS_MSG_SIGNAL
: 0);
333 /* verify_destination_id will usually be 0, which makes the kernel driver only look
334 * at the provided well-known name. Otherwise, the kernel will make sure the provided
335 * destination id matches the owner of the provided weel-known-name, and fail if they
336 * differ. Currently, this is only needed for bus-proxyd. */
337 m
->kdbus
->dst_id
= m
->verify_destination_id
;
339 m
->kdbus
->dst_id
= destination
? unique
: KDBUS_DST_ID_BROADCAST
;
341 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS
;
342 m
->kdbus
->cookie
= m
->header
->dbus2
.cookie
;
343 m
->kdbus
->priority
= m
->priority
;
345 if (m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
)
346 m
->kdbus
->cookie_reply
= m
->reply_cookie
;
350 assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE
, &now
) == 0);
351 m
->kdbus
->timeout_ns
= now
.tv_sec
* NSEC_PER_SEC
+ now
.tv_nsec
+
352 m
->timeout
* NSEC_PER_USEC
;
358 append_destination(&d
, destination
, dl
);
360 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
362 MESSAGE_FOREACH_PART(part
, i
, m
) {
364 /* If this is padding then simply send a
365 * vector with a NULL data pointer which the
366 * kernel will just pass through. This is the
367 * most efficient way to encode zeroes */
369 append_payload_vec(&d
, NULL
, part
->size
);
373 if (part
->memfd
>= 0 && part
->sealed
&& destination
) {
374 /* Try to send a memfd, if the part is
375 * sealed and this is not a broadcast. Since we can only */
377 append_payload_memfd(&d
, part
->memfd
, part
->memfd_offset
, part
->size
);
381 /* Otherwise, let's send a vector to the actual data.
382 * For that, we need to map it first. */
383 r
= bus_body_part_map(part
);
387 append_payload_vec(&d
, part
->data
, part
->size
);
390 if (m
->header
->type
== SD_BUS_MESSAGE_SIGNAL
) {
391 struct kdbus_bloom_filter
*bloom
;
393 bloom
= append_bloom(&d
, m
->bus
->bloom_size
);
394 r
= bus_message_setup_bloom(m
, bloom
);
400 append_fds(&d
, m
->fds
, m
->n_fds
);
402 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
403 assert(m
->kdbus
->size
<= sz
);
412 static void unset_memfds(struct sd_bus_message
*m
) {
413 struct bus_body_part
*part
;
418 /* Make sure the memfds are not freed twice */
419 MESSAGE_FOREACH_PART(part
, i
, m
)
420 if (part
->memfd
>= 0)
424 static void message_set_timestamp(sd_bus
*bus
, sd_bus_message
*m
, const struct kdbus_timestamp
*ts
) {
431 if (!(bus
->attach_flags
& KDBUS_ATTACH_TIMESTAMP
))
434 m
->realtime
= ts
->realtime_ns
/ NSEC_PER_USEC
;
435 m
->monotonic
= ts
->monotonic_ns
/ NSEC_PER_USEC
;
436 m
->seqnum
= ts
->seqnum
;
439 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
440 sd_bus_message
*m
= NULL
;
441 struct kdbus_item
*d
;
443 _cleanup_free_
int *fds
= NULL
;
444 struct bus_header
*header
= NULL
;
446 size_t header_size
= 0, footer_size
= 0;
447 size_t n_bytes
= 0, idx
= 0;
448 const char *destination
= NULL
, *seclabel
= NULL
;
449 bool last_was_memfd
= false;
454 assert(k
->payload_type
== KDBUS_PAYLOAD_DBUS
);
456 KDBUS_ITEM_FOREACH(d
, k
, items
) {
459 l
= d
->size
- offsetof(struct kdbus_item
, data
);
463 case KDBUS_ITEM_PAYLOAD_OFF
:
465 header
= (struct bus_header
*)((uint8_t*) k
+ d
->vec
.offset
);
466 header_size
= d
->vec
.size
;
469 footer
= (uint8_t*) k
+ d
->vec
.offset
;
470 footer_size
= d
->vec
.size
;
472 n_bytes
+= d
->vec
.size
;
473 last_was_memfd
= false;
476 case KDBUS_ITEM_PAYLOAD_MEMFD
:
477 if (!header
) /* memfd cannot be first part */
480 n_bytes
+= d
->memfd
.size
;
481 last_was_memfd
= true;
484 case KDBUS_ITEM_FDS
: {
489 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
494 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
499 case KDBUS_ITEM_SECLABEL
:
505 if (last_was_memfd
) /* memfd cannot be last part */
511 if (header_size
< sizeof(struct bus_header
))
514 /* on kdbus we only speak native endian gvariant, never dbus1
515 * marshalling or reverse endian */
516 if (header
->version
!= 2 ||
517 header
->endian
!= BUS_NATIVE_ENDIAN
)
520 r
= bus_message_from_header(
530 /* The well-known names list is different from the other
531 credentials. If we asked for it, but nothing is there, this
532 means that the list of well-known names is simply empty, not
533 that we lack any data */
535 m
->creds
.mask
|= (SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
) & bus
->creds_mask
;
537 KDBUS_ITEM_FOREACH(d
, k
, items
) {
540 l
= d
->size
- offsetof(struct kdbus_item
, data
);
544 case KDBUS_ITEM_PAYLOAD_OFF
: {
547 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
549 if (idx
+ d
->vec
.size
> begin_body
) {
550 struct bus_body_part
*part
;
552 /* Contains body material */
554 part
= message_append_part(m
);
560 /* A -1 offset is NUL padding. */
561 part
->is_zero
= d
->vec
.offset
== ~0ULL;
563 if (idx
>= begin_body
) {
565 part
->data
= (uint8_t* )k
+ d
->vec
.offset
;
566 part
->size
= d
->vec
.size
;
569 part
->data
= (uint8_t*) k
+ d
->vec
.offset
+ (begin_body
- idx
);
570 part
->size
= d
->vec
.size
- (begin_body
- idx
);
580 case KDBUS_ITEM_PAYLOAD_MEMFD
: {
581 struct bus_body_part
*part
;
583 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
588 part
= message_append_part(m
);
594 part
->memfd
= d
->memfd
.fd
;
595 part
->memfd_offset
= d
->memfd
.start
;
596 part
->size
= d
->memfd
.size
;
599 idx
+= d
->memfd
.size
;
603 case KDBUS_ITEM_PIDS
:
605 /* The PID/TID might be missing, when the data
606 * is faked by a bus proxy and it lacks that
607 * information about the real client (since
608 * SO_PEERCRED is used for that). Also kernel
609 * namespacing might make some of this data
610 * unavailable when untranslatable. */
612 if (d
->pids
.pid
> 0) {
613 m
->creds
.pid
= (pid_t
) d
->pids
.pid
;
614 m
->creds
.mask
|= SD_BUS_CREDS_PID
& bus
->creds_mask
;
617 if (d
->pids
.tid
> 0) {
618 m
->creds
.tid
= (pid_t
) d
->pids
.tid
;
619 m
->creds
.mask
|= SD_BUS_CREDS_TID
& bus
->creds_mask
;
622 if (d
->pids
.ppid
> 0) {
623 m
->creds
.ppid
= (pid_t
) d
->pids
.ppid
;
624 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
625 } else if (d
->pids
.pid
== 1) {
627 m
->creds
.mask
|= SD_BUS_CREDS_PPID
& bus
->creds_mask
;
632 case KDBUS_ITEM_CREDS
:
634 /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
635 * missing too (see above). */
637 if ((uid_t
) d
->creds
.uid
!= UID_INVALID
) {
638 m
->creds
.uid
= (uid_t
) d
->creds
.uid
;
639 m
->creds
.mask
|= SD_BUS_CREDS_UID
& bus
->creds_mask
;
642 if ((uid_t
) d
->creds
.euid
!= UID_INVALID
) {
643 m
->creds
.euid
= (uid_t
) d
->creds
.euid
;
644 m
->creds
.mask
|= SD_BUS_CREDS_EUID
& bus
->creds_mask
;
647 if ((uid_t
) d
->creds
.suid
!= UID_INVALID
) {
648 m
->creds
.suid
= (uid_t
) d
->creds
.suid
;
649 m
->creds
.mask
|= SD_BUS_CREDS_SUID
& bus
->creds_mask
;
652 if ((uid_t
) d
->creds
.fsuid
!= UID_INVALID
) {
653 m
->creds
.fsuid
= (uid_t
) d
->creds
.fsuid
;
654 m
->creds
.mask
|= SD_BUS_CREDS_FSUID
& bus
->creds_mask
;
657 if ((gid_t
) d
->creds
.gid
!= GID_INVALID
) {
658 m
->creds
.gid
= (gid_t
) d
->creds
.gid
;
659 m
->creds
.mask
|= SD_BUS_CREDS_GID
& bus
->creds_mask
;
662 if ((gid_t
) d
->creds
.egid
!= GID_INVALID
) {
663 m
->creds
.egid
= (gid_t
) d
->creds
.egid
;
664 m
->creds
.mask
|= SD_BUS_CREDS_EGID
& bus
->creds_mask
;
667 if ((gid_t
) d
->creds
.sgid
!= GID_INVALID
) {
668 m
->creds
.sgid
= (gid_t
) d
->creds
.sgid
;
669 m
->creds
.mask
|= SD_BUS_CREDS_SGID
& bus
->creds_mask
;
672 if ((gid_t
) d
->creds
.fsgid
!= GID_INVALID
) {
673 m
->creds
.fsgid
= (gid_t
) d
->creds
.fsgid
;
674 m
->creds
.mask
|= SD_BUS_CREDS_FSGID
& bus
->creds_mask
;
679 case KDBUS_ITEM_TIMESTAMP
:
680 message_set_timestamp(bus
, m
, &d
->timestamp
);
683 case KDBUS_ITEM_PID_COMM
:
684 m
->creds
.comm
= d
->str
;
685 m
->creds
.mask
|= SD_BUS_CREDS_COMM
& bus
->creds_mask
;
688 case KDBUS_ITEM_TID_COMM
:
689 m
->creds
.tid_comm
= d
->str
;
690 m
->creds
.mask
|= SD_BUS_CREDS_TID_COMM
& bus
->creds_mask
;
694 m
->creds
.exe
= d
->str
;
695 m
->creds
.mask
|= SD_BUS_CREDS_EXE
& bus
->creds_mask
;
698 case KDBUS_ITEM_CMDLINE
:
699 m
->creds
.cmdline
= d
->str
;
700 m
->creds
.cmdline_size
= l
;
701 m
->creds
.mask
|= SD_BUS_CREDS_CMDLINE
& bus
->creds_mask
;
704 case KDBUS_ITEM_CGROUP
:
705 m
->creds
.cgroup
= d
->str
;
706 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
;
708 r
= bus_get_root_path(bus
);
712 m
->creds
.cgroup_root
= bus
->cgroup_root
;
715 case KDBUS_ITEM_AUDIT
:
716 m
->creds
.audit_session_id
= (uint32_t) d
->audit
.sessionid
;
717 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
& bus
->creds_mask
;
719 m
->creds
.audit_login_uid
= (uid_t
) d
->audit
.loginuid
;
720 m
->creds
.mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
& bus
->creds_mask
;
723 case KDBUS_ITEM_CAPS
:
724 if (d
->caps
.last_cap
!= cap_last_cap() ||
725 d
->size
- offsetof(struct kdbus_item
, caps
.caps
) < DIV_ROUND_UP(d
->caps
.last_cap
, 32U) * 4 * 4) {
730 m
->creds
.capability
= d
->caps
.caps
;
731 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
;
734 case KDBUS_ITEM_DST_NAME
:
735 if (!service_name_is_valid(d
->str
)) {
740 destination
= d
->str
;
743 case KDBUS_ITEM_OWNED_NAME
:
744 if (!service_name_is_valid(d
->name
.name
)) {
749 if (bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
753 /* We just extend the array here, but
754 * do not allocate the strings inside
755 * of it, instead we just point to our
756 * buffer directly. */
757 n
= strv_length(m
->creds
.well_known_names
);
758 wkn
= realloc(m
->creds
.well_known_names
, (n
+ 2) * sizeof(char*));
764 wkn
[n
] = d
->name
.name
;
766 m
->creds
.well_known_names
= wkn
;
768 m
->creds
.mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
772 case KDBUS_ITEM_CONN_DESCRIPTION
:
773 m
->creds
.description
= d
->str
;
774 m
->creds
.mask
|= SD_BUS_CREDS_DESCRIPTION
& bus
->creds_mask
;
777 case KDBUS_ITEM_AUXGROUPS
:
779 if (bus
->creds_mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
783 n
= (d
->size
- offsetof(struct kdbus_item
, data64
)) / sizeof(uint64_t);
790 for (i
= 0; i
< n
; i
++)
793 m
->creds
.supplementary_gids
= g
;
794 m
->creds
.n_supplementary_gids
= n
;
795 m
->creds
.mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
801 case KDBUS_ITEM_SECLABEL
:
802 case KDBUS_ITEM_BLOOM_FILTER
:
806 log_debug("Got unknown field from kernel %llu", d
->type
);
810 /* If we requested the list of well-known names to be appended
811 * and the sender had none no item for it will be
812 * attached. However, this does *not* mean that the kernel
813 * didn't want to provide this information to us. Hence, let's
814 * explicitly mark this information as available if it was
816 m
->creds
.mask
|= bus
->creds_mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
;
818 r
= bus_message_parse_fields(m
);
822 /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
823 if ((uint64_t) m
->header
->dbus2
.cookie
!= k
->cookie
) {
828 /* Refuse messages where the reply flag doesn't match up */
829 if (!(m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) != !!(k
->flags
& KDBUS_MSG_EXPECT_REPLY
)) {
834 /* Refuse reply messages where the reply cookie doesn't match up */
835 if ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) && m
->reply_cookie
!= k
->cookie_reply
) {
840 /* Refuse messages where the autostart flag doesn't match up */
841 if (!(m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) != !(k
->flags
& KDBUS_MSG_NO_AUTO_START
)) {
846 /* Override information from the user header with data from the kernel */
847 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
848 bus_message_set_sender_driver(bus
, m
);
850 snprintf(m
->sender_buffer
, sizeof(m
->sender_buffer
), ":1.%llu", (unsigned long long) k
->src_id
);
851 m
->sender
= m
->creds
.unique_name
= m
->sender_buffer
;
855 m
->destination
= destination
;
856 else if (k
->dst_id
== KDBUS_DST_ID_BROADCAST
)
857 m
->destination
= NULL
;
858 else if (k
->dst_id
== KDBUS_DST_ID_NAME
)
859 m
->destination
= bus
->unique_name
; /* fill in unique name if the well-known name is missing */
861 snprintf(m
->destination_buffer
, sizeof(m
->destination_buffer
), ":1.%llu", (unsigned long long) k
->dst_id
);
862 m
->destination
= m
->destination_buffer
;
865 /* We take possession of the kmsg struct now */
867 m
->release_kdbus
= true;
871 bus
->rqueue
[bus
->rqueue_size
++] = m
;
877 sd_bus_message_unref(m
);
882 int bus_kernel_take_fd(sd_bus
*b
) {
883 struct kdbus_bloom_parameter
*bloom
= NULL
;
884 struct kdbus_item
*items
, *item
;
885 struct kdbus_cmd_hello
*hello
;
886 _cleanup_free_
char *g
= NULL
;
888 size_t l
= 0, m
= 0, sz
;
898 if (b
->description
) {
899 g
= bus_label_escape(b
->description
);
907 /* If no name is explicitly set, we'll include a hint
908 * indicating the library implementation, a hint which
909 * kind of bus this is and the thread name */
911 assert_se(prctl(PR_GET_NAME
, (unsigned long) pr
) >= 0);
914 name
= b
->is_system
? "sd-system" :
915 b
->is_user
? "sd-user" : "sd";
917 _cleanup_free_
char *e
= NULL
;
919 e
= bus_label_escape(pr
);
923 g
= strappend(b
->is_system
? "sd-system-" :
924 b
->is_user
? "sd-user-" : "sd-",
932 b
->description
= bus_label_unescape(name
);
939 sz
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
)) +
940 ALIGN8(offsetof(struct kdbus_item
, str
) + m
+ 1);
942 if (b
->fake_creds_valid
)
943 sz
+= ALIGN8(offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
));
945 if (b
->fake_pids_valid
)
946 sz
+= ALIGN8(offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
));
949 l
= strlen(b
->fake_label
);
950 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + l
+ 1);
953 hello
= alloca0_align(sz
, 8);
955 hello
->flags
= b
->hello_flags
;
956 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
957 hello
->attach_flags_recv
= b
->attach_flags
;
958 hello
->pool_size
= KDBUS_POOL_SIZE
;
962 item
->size
= offsetof(struct kdbus_item
, str
) + m
+ 1;
963 item
->type
= KDBUS_ITEM_CONN_DESCRIPTION
;
964 memcpy(item
->str
, name
, m
+ 1);
965 item
= KDBUS_ITEM_NEXT(item
);
967 if (b
->fake_creds_valid
) {
968 item
->size
= offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
);
969 item
->type
= KDBUS_ITEM_CREDS
;
970 item
->creds
= b
->fake_creds
;
972 item
= KDBUS_ITEM_NEXT(item
);
975 if (b
->fake_pids_valid
) {
976 item
->size
= offsetof(struct kdbus_item
, pids
) + sizeof(struct kdbus_pids
);
977 item
->type
= KDBUS_ITEM_PIDS
;
978 item
->pids
= b
->fake_pids
;
980 item
= KDBUS_ITEM_NEXT(item
);
984 item
->size
= offsetof(struct kdbus_item
, str
) + l
+ 1;
985 item
->type
= KDBUS_ITEM_SECLABEL
;
986 memcpy(item
->str
, b
->fake_label
, l
+1);
989 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
992 /* If the ioctl is not supported we assume that the
993 * API version changed in a major incompatible way,
994 * let's indicate an API incompatibility in this
996 return -ESOCKTNOSUPPORT
;
1001 if (!b
->kdbus_buffer
) {
1002 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
, MAP_SHARED
, b
->input_fd
, 0);
1003 if (b
->kdbus_buffer
== MAP_FAILED
) {
1004 b
->kdbus_buffer
= NULL
;
1010 /* The higher 32bit of the bus_flags fields are considered
1011 * 'incompatible flags'. Refuse them all for now. */
1012 if (hello
->bus_flags
> 0xFFFFFFFFULL
) {
1013 r
= -ESOCKTNOSUPPORT
;
1017 /* extract bloom parameters from items */
1018 items
= (void*)((uint8_t*)b
->kdbus_buffer
+ hello
->offset
);
1019 KDBUS_FOREACH(item
, items
, hello
->items_size
) {
1020 switch (item
->type
) {
1021 case KDBUS_ITEM_BLOOM_PARAMETER
:
1022 bloom
= &item
->bloom_parameter
;
1027 if (!bloom
|| !bloom_validate_parameters((size_t) bloom
->size
, (unsigned) bloom
->n_hash
)) {
1032 b
->bloom_size
= (size_t) bloom
->size
;
1033 b
->bloom_n_hash
= (unsigned) bloom
->n_hash
;
1035 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0) {
1040 b
->unique_id
= hello
->id
;
1042 b
->is_kernel
= true;
1043 b
->bus_client
= true;
1044 b
->can_fds
= !!(hello
->flags
& KDBUS_HELLO_ACCEPT_FD
);
1045 b
->message_version
= 2;
1046 b
->message_endian
= BUS_NATIVE_ENDIAN
;
1048 /* the kernel told us the UUID of the underlying bus */
1049 memcpy(b
->server_id
.bytes
, hello
->id128
, sizeof(b
->server_id
.bytes
));
1051 /* free returned items */
1052 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1053 return bus_start_running(b
);
1056 (void) bus_kernel_cmd_free(b
, hello
->offset
);
1060 int bus_kernel_connect(sd_bus
*b
) {
1062 assert(b
->input_fd
< 0);
1063 assert(b
->output_fd
< 0);
1069 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1070 if (b
->input_fd
< 0)
1073 b
->output_fd
= b
->input_fd
;
1075 return bus_kernel_take_fd(b
);
1078 int bus_kernel_cmd_free(sd_bus
*bus
, uint64_t offset
) {
1079 struct kdbus_cmd_free cmd
= {
1080 .size
= sizeof(cmd
),
1086 assert(bus
->is_kernel
);
1088 r
= ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &cmd
);
1095 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
1096 struct kdbus_item
*d
;
1101 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1102 if (d
->type
== KDBUS_ITEM_FDS
)
1103 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
1104 else if (d
->type
== KDBUS_ITEM_PAYLOAD_MEMFD
)
1105 safe_close(d
->memfd
.fd
);
1108 bus_kernel_cmd_free(bus
, (uint8_t*) k
- (uint8_t*) bus
->kdbus_buffer
);
1111 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
, bool hint_sync_call
) {
1112 struct kdbus_cmd_send cmd
= { };
1117 assert(bus
->state
== BUS_RUNNING
);
1119 /* If we can't deliver, we want room for the error message */
1120 r
= bus_rqueue_make_room(bus
);
1124 r
= bus_message_setup_kmsg(bus
, m
);
1128 cmd
.size
= sizeof(cmd
);
1129 cmd
.msg_address
= (uintptr_t)m
->kdbus
;
1131 /* If this is a synchronous method call, then let's tell the
1132 * kernel, so that it can pass CPU time/scheduling to the
1133 * destination for the time, if it wants to. If we
1134 * synchronously wait for the result anyway, we won't need CPU
1136 if (hint_sync_call
) {
1137 m
->kdbus
->flags
|= KDBUS_MSG_EXPECT_REPLY
;
1138 cmd
.flags
|= KDBUS_SEND_SYNC_REPLY
;
1141 r
= ioctl(bus
->output_fd
, KDBUS_CMD_SEND
, &cmd
);
1143 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1144 sd_bus_message
*reply
;
1146 if (errno
== EAGAIN
|| errno
== EINTR
)
1148 else if (errno
== ENXIO
|| errno
== ESRCH
) {
1150 /* ENXIO: unique name not known
1151 * ESRCH: well-known name not known */
1153 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1154 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Destination %s not known", m
->destination
);
1156 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m
->destination
);
1160 } else if (errno
== EADDRNOTAVAIL
) {
1162 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
1164 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1165 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Activation of %s not requested", m
->destination
);
1167 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m
->destination
);
1173 r
= bus_message_new_synthetic_error(
1175 BUS_MESSAGE_COOKIE(m
),
1182 r
= bus_seal_synthetic_message(bus
, reply
);
1186 bus
->rqueue
[bus
->rqueue_size
++] = reply
;
1188 } else if (hint_sync_call
) {
1189 struct kdbus_msg
*k
;
1191 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ cmd
.reply
.offset
);
1194 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1196 r
= bus_kernel_make_message(bus
, k
);
1198 close_kdbus_msg(bus
, k
);
1200 /* Anybody can send us invalid messages, let's just drop them. */
1201 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
)
1202 log_debug_errno(r
, "Ignoring invalid synchronous reply: %m");
1207 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1208 close_kdbus_msg(bus
, k
);
1215 static int push_name_owner_changed(
1218 const char *old_owner
,
1219 const char *new_owner
,
1220 const struct kdbus_timestamp
*ts
) {
1222 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1227 r
= sd_bus_message_new_signal(
1230 "/org/freedesktop/DBus",
1231 "org.freedesktop.DBus",
1232 "NameOwnerChanged");
1236 r
= sd_bus_message_append(m
, "sss", name
, old_owner
, new_owner
);
1240 bus_message_set_sender_driver(bus
, m
);
1241 message_set_timestamp(bus
, m
, ts
);
1243 r
= bus_seal_synthetic_message(bus
, m
);
1247 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1253 static int translate_name_change(
1255 const struct kdbus_msg
*k
,
1256 const struct kdbus_item
*d
,
1257 const struct kdbus_timestamp
*ts
) {
1259 char new_owner
[UNIQUE_NAME_MAX
], old_owner
[UNIQUE_NAME_MAX
];
1265 if (d
->type
== KDBUS_ITEM_NAME_ADD
|| (d
->name_change
.old_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
)))
1268 sprintf(old_owner
, ":1.%llu", (unsigned long long) d
->name_change
.old_id
.id
);
1270 if (d
->type
== KDBUS_ITEM_NAME_REMOVE
|| (d
->name_change
.new_id
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
))) {
1272 if (isempty(old_owner
))
1277 sprintf(new_owner
, ":1.%llu", (unsigned long long) d
->name_change
.new_id
.id
);
1279 return push_name_owner_changed(bus
, d
->name_change
.name
, old_owner
, new_owner
, ts
);
1282 static int translate_id_change(
1284 const struct kdbus_msg
*k
,
1285 const struct kdbus_item
*d
,
1286 const struct kdbus_timestamp
*ts
) {
1288 char owner
[UNIQUE_NAME_MAX
];
1294 sprintf(owner
, ":1.%llu", d
->id_change
.id
);
1296 return push_name_owner_changed(
1298 d
->type
== KDBUS_ITEM_ID_ADD
? NULL
: owner
,
1299 d
->type
== KDBUS_ITEM_ID_ADD
? owner
: NULL
,
1303 static int translate_reply(
1305 const struct kdbus_msg
*k
,
1306 const struct kdbus_item
*d
,
1307 const struct kdbus_timestamp
*ts
) {
1309 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1316 r
= bus_message_new_synthetic_error(
1319 d
->type
== KDBUS_ITEM_REPLY_TIMEOUT
?
1320 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call timed out") :
1321 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call peer died"),
1326 message_set_timestamp(bus
, m
, ts
);
1328 r
= bus_seal_synthetic_message(bus
, m
);
1332 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1338 static int bus_kernel_translate_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
1339 static int (* const translate
[])(sd_bus
*bus
, const struct kdbus_msg
*k
, const struct kdbus_item
*d
, const struct kdbus_timestamp
*ts
) = {
1340 [KDBUS_ITEM_NAME_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1341 [KDBUS_ITEM_NAME_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1342 [KDBUS_ITEM_NAME_CHANGE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1344 [KDBUS_ITEM_ID_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1345 [KDBUS_ITEM_ID_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1347 [KDBUS_ITEM_REPLY_TIMEOUT
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1348 [KDBUS_ITEM_REPLY_DEAD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1351 struct kdbus_item
*d
, *found
= NULL
;
1352 struct kdbus_timestamp
*ts
= NULL
;
1356 assert(k
->payload_type
== KDBUS_PAYLOAD_KERNEL
);
1358 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1359 if (d
->type
== KDBUS_ITEM_TIMESTAMP
)
1361 else if (d
->type
>= _KDBUS_ITEM_KERNEL_BASE
&& d
->type
< _KDBUS_ITEM_KERNEL_BASE
+ ELEMENTSOF(translate
)) {
1366 log_debug("Got unknown field from kernel %llu", d
->type
);
1370 log_debug("Didn't find a kernel message to translate.");
1374 return translate
[found
->type
- _KDBUS_ITEM_KERNEL_BASE
](bus
, k
, found
, ts
);
1377 int bus_kernel_read_message(sd_bus
*bus
, bool hint_priority
, int64_t priority
) {
1378 struct kdbus_cmd_recv recv
= { .size
= sizeof(recv
) };
1379 struct kdbus_msg
*k
;
1384 r
= bus_rqueue_make_room(bus
);
1388 if (hint_priority
) {
1389 recv
.flags
|= KDBUS_RECV_USE_PRIORITY
;
1390 recv
.priority
= priority
;
1393 r
= ioctl(bus
->input_fd
, KDBUS_CMD_RECV
, &recv
);
1394 if (recv
.return_flags
& KDBUS_RECV_RETURN_DROPPED_MSGS
)
1395 log_debug("%s: kdbus reports %" PRIu64
" dropped broadcast messages, ignoring.", strna(bus
->description
), (uint64_t) recv
.dropped_msgs
);
1397 if (errno
== EAGAIN
)
1403 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ recv
.msg
.offset
);
1404 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1405 r
= bus_kernel_make_message(bus
, k
);
1407 /* Anybody can send us invalid messages, let's just drop them. */
1408 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
) {
1409 log_debug_errno(r
, "Ignoring invalid message: %m");
1414 close_kdbus_msg(bus
, k
);
1415 } else if (k
->payload_type
== KDBUS_PAYLOAD_KERNEL
) {
1416 r
= bus_kernel_translate_message(bus
, k
);
1417 close_kdbus_msg(bus
, k
);
1419 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1421 close_kdbus_msg(bus
, k
);
1424 return r
< 0 ? r
: 1;
1427 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *mapped
, size_t *allocated
) {
1428 struct memfd_cache
*c
;
1435 if (!bus
|| !bus
->is_kernel
)
1438 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1440 if (bus
->n_memfd_cache
<= 0) {
1443 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1445 r
= memfd_new(bus
->description
);
1455 c
= &bus
->memfd_cache
[--bus
->n_memfd_cache
];
1458 assert(c
->mapped
== 0 || c
->address
);
1460 *address
= c
->address
;
1461 *mapped
= c
->mapped
;
1462 *allocated
= c
->allocated
;
1465 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1470 static void close_and_munmap(int fd
, void *address
, size_t size
) {
1472 assert_se(munmap(address
, PAGE_ALIGN(size
)) >= 0);
1477 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t mapped
, size_t allocated
) {
1478 struct memfd_cache
*c
;
1479 uint64_t max_mapped
= PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX
);
1482 assert(mapped
== 0 || address
);
1484 if (!bus
|| !bus
->is_kernel
) {
1485 close_and_munmap(fd
, address
, mapped
);
1489 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
1491 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
1492 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1494 close_and_munmap(fd
, address
, mapped
);
1498 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
1500 c
->address
= address
;
1502 /* If overly long, let's return a bit to the OS */
1503 if (mapped
> max_mapped
) {
1504 assert_se(memfd_set_size(fd
, max_mapped
) >= 0);
1505 assert_se(munmap((uint8_t*) address
+ max_mapped
, PAGE_ALIGN(mapped
- max_mapped
)) >= 0);
1506 c
->mapped
= c
->allocated
= max_mapped
;
1509 c
->allocated
= allocated
;
1512 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
1515 void bus_kernel_flush_memfd(sd_bus
*b
) {
1520 for (i
= 0; i
< b
->n_memfd_cache
; i
++)
1521 close_and_munmap(b
->memfd_cache
[i
].fd
, b
->memfd_cache
[i
].address
, b
->memfd_cache
[i
].mapped
);
1524 uint64_t request_name_flags_to_kdbus(uint64_t flags
) {
1527 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
1528 f
|= KDBUS_NAME_ALLOW_REPLACEMENT
;
1530 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
1531 f
|= KDBUS_NAME_REPLACE_EXISTING
;
1533 if (flags
& SD_BUS_NAME_QUEUE
)
1534 f
|= KDBUS_NAME_QUEUE
;
1539 uint64_t attach_flags_to_kdbus(uint64_t mask
) {
1542 if (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
|
1543 SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
))
1544 m
|= KDBUS_ATTACH_CREDS
;
1546 if (mask
& (SD_BUS_CREDS_PID
|SD_BUS_CREDS_TID
|SD_BUS_CREDS_PPID
))
1547 m
|= KDBUS_ATTACH_PIDS
;
1549 if (mask
& SD_BUS_CREDS_COMM
)
1550 m
|= KDBUS_ATTACH_PID_COMM
;
1552 if (mask
& SD_BUS_CREDS_TID_COMM
)
1553 m
|= KDBUS_ATTACH_TID_COMM
;
1555 if (mask
& SD_BUS_CREDS_EXE
)
1556 m
|= KDBUS_ATTACH_EXE
;
1558 if (mask
& SD_BUS_CREDS_CMDLINE
)
1559 m
|= KDBUS_ATTACH_CMDLINE
;
1561 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
))
1562 m
|= KDBUS_ATTACH_CGROUP
;
1564 if (mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
))
1565 m
|= KDBUS_ATTACH_CAPS
;
1567 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
)
1568 m
|= KDBUS_ATTACH_SECLABEL
;
1570 if (mask
& (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
))
1571 m
|= KDBUS_ATTACH_AUDIT
;
1573 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
)
1574 m
|= KDBUS_ATTACH_NAMES
;
1576 if (mask
& SD_BUS_CREDS_DESCRIPTION
)
1577 m
|= KDBUS_ATTACH_CONN_DESCRIPTION
;
1579 if (mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
)
1580 m
|= KDBUS_ATTACH_AUXGROUPS
;
1585 int bus_kernel_create_bus(const char *name
, bool world
, char **s
) {
1586 struct kdbus_cmd
*make
;
1587 struct kdbus_item
*n
;
1594 fd
= open("/sys/fs/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1599 make
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1600 ALIGN8(offsetof(struct kdbus_item
, bloom_parameter
) + sizeof(struct kdbus_bloom_parameter
)) +
1601 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)) +
1602 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + l
+ 1),
1605 make
->size
= offsetof(struct kdbus_cmd
, items
);
1607 /* Set the bloom parameters */
1609 n
->size
= offsetof(struct kdbus_item
, bloom_parameter
) +
1610 sizeof(struct kdbus_bloom_parameter
);
1611 n
->type
= KDBUS_ITEM_BLOOM_PARAMETER
;
1612 n
->bloom_parameter
.size
= DEFAULT_BLOOM_SIZE
;
1613 n
->bloom_parameter
.n_hash
= DEFAULT_BLOOM_N_HASH
;
1615 assert_cc(DEFAULT_BLOOM_SIZE
> 0);
1616 assert_cc(DEFAULT_BLOOM_N_HASH
> 0);
1618 make
->size
+= ALIGN8(n
->size
);
1620 /* Provide all metadata via bus-owner queries */
1621 n
= KDBUS_ITEM_NEXT(n
);
1622 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_SEND
;
1623 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1624 n
->data64
[0] = _KDBUS_ATTACH_ANY
;
1625 make
->size
+= ALIGN8(n
->size
);
1627 /* Set the a good name */
1628 n
= KDBUS_ITEM_NEXT(n
);
1629 sprintf(n
->str
, UID_FMT
"-%s", getuid(), name
);
1630 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1631 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1632 make
->size
+= ALIGN8(n
->size
);
1634 make
->flags
= world
? KDBUS_MAKE_ACCESS_WORLD
: 0;
1636 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
1639 /* Major API change? then the ioctls got shuffled around. */
1640 if (errno
== ENOTTY
)
1641 return -ESOCKTNOSUPPORT
;
1649 p
= strjoin("/sys/fs/kdbus/", n
->str
, "/bus", NULL
);
1661 int bus_kernel_open_bus_fd(const char *bus
, char **path
) {
1668 len
= strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + strlen("/bus") + 1;
1675 p
= newa(char, len
);
1677 sprintf(p
, "/sys/fs/kdbus/" UID_FMT
"-%s/bus", getuid(), bus
);
1679 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1693 int bus_kernel_create_endpoint(const char *bus_name
, const char *ep_name
, char **ep_path
) {
1694 _cleanup_free_
char *path
= NULL
;
1695 struct kdbus_cmd
*make
;
1696 struct kdbus_item
*n
;
1700 fd
= bus_kernel_open_bus_fd(bus_name
, &path
);
1704 make
= alloca0_align(ALIGN8(offsetof(struct kdbus_cmd
, items
)) +
1705 ALIGN8(offsetof(struct kdbus_item
, str
) + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(ep_name
) + 1),
1707 make
->size
= ALIGN8(offsetof(struct kdbus_cmd
, items
));
1708 make
->flags
= KDBUS_MAKE_ACCESS_WORLD
;
1711 sprintf(n
->str
, UID_FMT
"-%s", getuid(), ep_name
);
1712 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1713 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1714 make
->size
+= ALIGN8(n
->size
);
1717 if (ioctl(fd
, KDBUS_CMD_ENDPOINT_MAKE
, make
) < 0) {
1725 p
= strjoin(dirname(path
), "/", name
, NULL
);
1737 int bus_kernel_try_close(sd_bus
*bus
) {
1738 struct kdbus_cmd byebye
= { .size
= sizeof(byebye
) };
1741 assert(bus
->is_kernel
);
1743 if (ioctl(bus
->input_fd
, KDBUS_CMD_BYEBYE
, &byebye
) < 0)
1749 int bus_kernel_drop_one(int fd
) {
1750 struct kdbus_cmd_recv recv
= {
1751 .size
= sizeof(recv
),
1752 .flags
= KDBUS_RECV_DROP
,
1757 if (ioctl(fd
, KDBUS_CMD_RECV
, &recv
) < 0)
1763 int bus_kernel_realize_attach_flags(sd_bus
*bus
) {
1764 struct kdbus_cmd
*update
;
1765 struct kdbus_item
*n
;
1768 assert(bus
->is_kernel
);
1770 update
= alloca0_align(offsetof(struct kdbus_cmd
, items
) +
1771 ALIGN8(offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t)),
1775 n
->type
= KDBUS_ITEM_ATTACH_FLAGS_RECV
;
1776 n
->size
= offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t);
1777 n
->data64
[0] = bus
->attach_flags
;
1780 offsetof(struct kdbus_cmd
, items
) +
1783 if (ioctl(bus
->input_fd
, KDBUS_CMD_UPDATE
, update
) < 0)
1789 int bus_kernel_get_bus_name(sd_bus
*bus
, char **name
) {
1790 struct kdbus_cmd_info cmd
= {
1791 .size
= sizeof(struct kdbus_cmd_info
),
1793 struct kdbus_info
*info
;
1794 struct kdbus_item
*item
;
1800 assert(bus
->is_kernel
);
1802 r
= ioctl(bus
->input_fd
, KDBUS_CMD_BUS_CREATOR_INFO
, &cmd
);
1806 info
= (struct kdbus_info
*) ((uint8_t*) bus
->kdbus_buffer
+ cmd
.offset
);
1808 KDBUS_ITEM_FOREACH(item
, info
, items
)
1809 if (item
->type
== KDBUS_ITEM_MAKE_NAME
) {
1810 r
= free_and_strdup(&n
, item
->str
);
1814 bus_kernel_cmd_free(bus
, cmd
.offset
);