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>
34 #include "bus-internal.h"
35 #include "bus-message.h"
36 #include "bus-kernel.h"
37 #include "bus-bloom.h"
39 #include "cgroup-util.h"
41 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
43 int bus_kernel_parse_unique_name(const char *s
, uint64_t *id
) {
49 if (!startswith(s
, ":1."))
52 r
= safe_atou64(s
+ 3, id
);
59 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
65 /* Note that p can be NULL, which encodes a region full of
66 * zeroes, which is useful to optimize certain padding
69 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
70 (*d
)->type
= KDBUS_ITEM_PAYLOAD_VEC
;
71 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
74 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
77 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t sz
) {
83 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
84 (*d
)->type
= KDBUS_ITEM_PAYLOAD_MEMFD
;
85 (*d
)->memfd
.fd
= memfd
;
86 (*d
)->memfd
.size
= sz
;
88 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
91 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
97 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
98 (*d
)->type
= KDBUS_ITEM_DST_NAME
;
99 memcpy((*d
)->str
, s
, length
+ 1);
101 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
104 static struct kdbus_bloom_filter
*append_bloom(struct kdbus_item
**d
, size_t length
) {
105 struct kdbus_item
*i
;
111 i
->size
= offsetof(struct kdbus_item
, bloom_filter
) +
112 offsetof(struct kdbus_bloom_filter
, data
) +
114 i
->type
= KDBUS_ITEM_BLOOM_FILTER
;
116 *d
= (struct kdbus_item
*) ((uint8_t*) i
+ i
->size
);
118 return &i
->bloom_filter
;
121 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
127 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
128 (*d
)->type
= KDBUS_ITEM_FDS
;
129 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
131 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
134 static int bus_message_setup_bloom(sd_bus_message
*m
, struct kdbus_bloom_filter
*bloom
) {
143 memzero(data
, m
->bus
->bloom_size
);
144 bloom
->generation
= 0;
146 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "message-type", bus_message_type_to_string(m
->header
->type
));
149 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "interface", m
->interface
);
151 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "member", m
->member
);
153 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path", m
->path
);
154 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
);
155 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, "path-slash-prefix", m
->path
, '/');
158 r
= sd_bus_message_rewind(m
, true);
162 for (i
= 0; i
< 64; i
++) {
165 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
168 r
= sd_bus_message_peek_type(m
, &type
, NULL
);
172 if (type
!= SD_BUS_TYPE_STRING
&&
173 type
!= SD_BUS_TYPE_OBJECT_PATH
&&
174 type
!= SD_BUS_TYPE_SIGNATURE
)
177 r
= sd_bus_message_read_basic(m
, type
, &t
);
181 e
= stpcpy(buf
, "arg");
183 *(e
++) = '0' + (char) i
;
185 *(e
++) = '0' + (char) (i
/ 10);
186 *(e
++) = '0' + (char) (i
% 10);
190 bloom_add_pair(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, buf
, t
);
192 strcpy(e
, "-dot-prefix");
193 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, buf
, t
, '.');
194 strcpy(e
, "-slash-prefix");
195 bloom_add_prefixes(data
, m
->bus
->bloom_size
, m
->bus
->bloom_n_hash
, buf
, t
, '/');
201 static int bus_message_setup_kmsg(sd_bus
*b
, sd_bus_message
*m
) {
202 struct bus_body_part
*part
;
203 struct kdbus_item
*d
;
214 /* We put this together only once, if this message is reused
215 * we reuse the earlier-built version */
219 if (m
->destination
) {
220 r
= bus_kernel_parse_unique_name(m
->destination
, &unique
);
228 sz
= offsetof(struct kdbus_msg
, items
);
230 assert_cc(ALIGN8(offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
)) ==
231 ALIGN8(offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
)));
233 /* Add in fixed header, fields header and payload */
234 sz
+= (1 + m
->n_body_parts
) *
235 ALIGN8(offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
));
237 /* Add space for bloom filter */
238 sz
+= ALIGN8(offsetof(struct kdbus_item
, bloom_filter
) +
239 offsetof(struct kdbus_bloom_filter
, data
) +
242 /* Add in well-known destination header */
244 dl
= strlen(m
->destination
);
245 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
248 /* Add space for unix fds */
250 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
252 m
->kdbus
= memalign(8, sz
);
258 m
->free_kdbus
= true;
259 memzero(m
->kdbus
, sz
);
262 ((m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY
) |
263 ((m
->header
->flags
& BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_FLAGS_NO_AUTO_START
: 0);
266 m
->destination
? unique
: KDBUS_DST_ID_BROADCAST
;
267 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS
;
268 m
->kdbus
->cookie
= m
->header
->serial
;
269 m
->kdbus
->priority
= m
->priority
;
271 if (m
->header
->flags
& BUS_MESSAGE_NO_REPLY_EXPECTED
)
272 m
->kdbus
->cookie_reply
= m
->reply_cookie
;
274 m
->kdbus
->timeout_ns
= m
->timeout
* NSEC_PER_USEC
;
279 append_destination(&d
, m
->destination
, dl
);
281 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
283 MESSAGE_FOREACH_PART(part
, i
, m
) {
285 /* If this is padding then simply send a
286 * vector with a NULL data pointer which the
287 * kernel will just pass through. This is the
288 * most efficient way to encode zeroes */
290 append_payload_vec(&d
, NULL
, part
->size
);
294 if (part
->memfd
>= 0 && part
->sealed
&& m
->destination
) {
295 /* Try to send a memfd, if the part is
296 * sealed and this is not a broadcast. Since we can only */
298 append_payload_memfd(&d
, part
->memfd
, part
->size
);
302 /* Otherwise, let's send a vector to the actual data.
303 * For that, we need to map it first. */
304 r
= bus_body_part_map(part
);
308 append_payload_vec(&d
, part
->data
, part
->size
);
311 if (m
->kdbus
->dst_id
== KDBUS_DST_ID_BROADCAST
) {
312 struct kdbus_bloom_filter
*bloom
;
314 bloom
= append_bloom(&d
, m
->bus
->bloom_size
);
315 r
= bus_message_setup_bloom(m
, bloom
);
321 append_fds(&d
, m
->fds
, m
->n_fds
);
323 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
324 assert(m
->kdbus
->size
<= sz
);
333 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
334 sd_bus_message
*m
= NULL
;
335 struct kdbus_item
*d
;
337 _cleanup_free_
int *fds
= NULL
;
338 struct bus_header
*h
= NULL
;
339 size_t total
, n_bytes
= 0, idx
= 0;
340 const char *destination
= NULL
, *seclabel
= NULL
;
345 assert(k
->payload_type
== KDBUS_PAYLOAD_DBUS
);
347 KDBUS_ITEM_FOREACH(d
, k
, items
) {
350 l
= d
->size
- offsetof(struct kdbus_item
, data
);
354 case KDBUS_ITEM_PAYLOAD_OFF
:
356 h
= (struct bus_header
*)((uint8_t *)k
+ d
->vec
.offset
);
358 if (!bus_header_is_complete(h
, d
->vec
.size
))
362 n_bytes
+= d
->vec
.size
;
365 case KDBUS_ITEM_PAYLOAD_MEMFD
:
369 n_bytes
+= d
->memfd
.size
;
372 case KDBUS_ITEM_FDS
: {
377 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
382 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
387 case KDBUS_ITEM_SECLABEL
:
396 r
= bus_header_message_size(h
, &total
);
400 if (n_bytes
!= total
)
403 /* on kdbus we only speak native endian gvariant, never dbus1
404 * marshalling or reverse endian */
405 if (h
->version
!= 2 ||
406 h
->endian
!= BUS_NATIVE_ENDIAN
)
409 r
= bus_message_from_header(bus
, h
, sizeof(struct bus_header
), fds
, n_fds
, NULL
, seclabel
, 0, &m
);
413 /* The well-known names list is different from the other
414 credentials. If we asked for it, but nothing is there, this
415 means that the list of well-known names is simply empty, not
416 that we lack any data */
418 m
->creds
.mask
|= (SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
) & bus
->creds_mask
;
420 KDBUS_ITEM_FOREACH(d
, k
, items
) {
423 l
= d
->size
- offsetof(struct kdbus_item
, data
);
427 case KDBUS_ITEM_PAYLOAD_OFF
: {
430 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
432 if (idx
+ d
->vec
.size
> begin_body
) {
433 struct bus_body_part
*part
;
435 /* Contains body material */
437 part
= message_append_part(m
);
443 /* A -1 offset is NUL padding. */
444 part
->is_zero
= d
->vec
.offset
== ~0ULL;
446 if (idx
>= begin_body
) {
448 part
->data
= (uint8_t *)k
+ d
->vec
.offset
;
449 part
->size
= d
->vec
.size
;
452 part
->data
= (uint8_t *)k
+ d
->vec
.offset
+ (begin_body
- idx
);
453 part
->size
= d
->vec
.size
- (begin_body
- idx
);
463 case KDBUS_ITEM_PAYLOAD_MEMFD
: {
464 struct bus_body_part
*part
;
466 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
471 part
= message_append_part(m
);
477 part
->memfd
= d
->memfd
.fd
;
478 part
->size
= d
->memfd
.size
;
481 idx
+= d
->memfd
.size
;
485 case KDBUS_ITEM_CREDS
:
486 /* UID/GID/PID are always valid */
487 m
->creds
.uid
= (uid_t
) d
->creds
.uid
;
488 m
->creds
.gid
= (gid_t
) d
->creds
.gid
;
489 m
->creds
.pid
= (pid_t
) d
->creds
.pid
;
490 m
->creds
.mask
|= (SD_BUS_CREDS_UID
|SD_BUS_CREDS_GID
|SD_BUS_CREDS_PID
) & bus
->creds_mask
;
492 /* The PID starttime/TID might be missing
493 * however, when the data is faked by some
494 * data bus proxy and it lacks that
495 * information about the real client since
496 * SO_PEERCRED is used for that */
498 if (d
->creds
.starttime
> 0) {
499 m
->creds
.pid_starttime
= d
->creds
.starttime
/ NSEC_PER_USEC
;
500 m
->creds
.mask
|= SD_BUS_CREDS_PID_STARTTIME
& bus
->creds_mask
;
503 if (d
->creds
.tid
> 0) {
504 m
->creds
.tid
= (pid_t
) d
->creds
.tid
;
505 m
->creds
.mask
|= SD_BUS_CREDS_TID
& bus
->creds_mask
;
509 case KDBUS_ITEM_TIMESTAMP
:
511 if (bus
->attach_flags
& KDBUS_ATTACH_TIMESTAMP
) {
512 m
->realtime
= d
->timestamp
.realtime_ns
/ NSEC_PER_USEC
;
513 m
->monotonic
= d
->timestamp
.monotonic_ns
/ NSEC_PER_USEC
;
514 m
->seqnum
= d
->timestamp
.seqnum
;
519 case KDBUS_ITEM_PID_COMM
:
520 m
->creds
.comm
= d
->str
;
521 m
->creds
.mask
|= SD_BUS_CREDS_COMM
& bus
->creds_mask
;
524 case KDBUS_ITEM_TID_COMM
:
525 m
->creds
.tid_comm
= d
->str
;
526 m
->creds
.mask
|= SD_BUS_CREDS_TID_COMM
& bus
->creds_mask
;
530 m
->creds
.exe
= d
->str
;
531 m
->creds
.mask
|= SD_BUS_CREDS_EXE
& bus
->creds_mask
;
534 case KDBUS_ITEM_CMDLINE
:
535 m
->creds
.cmdline
= d
->str
;
536 m
->creds
.cmdline_size
= l
;
537 m
->creds
.mask
|= SD_BUS_CREDS_CMDLINE
& bus
->creds_mask
;
540 case KDBUS_ITEM_CGROUP
:
541 m
->creds
.cgroup
= d
->str
;
542 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
;
544 if (!bus
->cgroup_root
) {
545 r
= cg_get_root_path(&bus
->cgroup_root
);
550 m
->creds
.cgroup_root
= bus
->cgroup_root
;
554 case KDBUS_ITEM_AUDIT
:
555 m
->creds
.audit_session_id
= (uint32_t) d
->audit
.sessionid
;
556 m
->creds
.audit_login_uid
= (uid_t
) d
->audit
.loginuid
;
557 m
->creds
.mask
|= (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
) & bus
->creds_mask
;
560 case KDBUS_ITEM_CAPS
:
561 m
->creds
.capability
= d
->data
;
562 m
->creds
.capability_size
= l
;
563 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
;
566 case KDBUS_ITEM_DST_NAME
:
567 if (!service_name_is_valid(d
->str
))
570 destination
= d
->str
;
573 case KDBUS_ITEM_NAME
:
574 if (!service_name_is_valid(d
->name
.name
))
577 r
= strv_extend(&m
->creds
.well_known_names
, d
->name
.name
);
582 case KDBUS_ITEM_CONN_NAME
:
583 m
->creds
.conn_name
= d
->str
;
584 m
->creds
.mask
|= SD_BUS_CREDS_CONNECTION_NAME
& bus
->creds_mask
;
588 case KDBUS_ITEM_SECLABEL
:
592 log_debug("Got unknown field from kernel %llu", d
->type
);
596 r
= bus_message_parse_fields(m
);
600 /* Override information from the user header with data from the kernel */
601 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
602 m
->sender
= m
->creds
.unique_name
= (char*) "org.freedesktop.DBus";
604 snprintf(m
->sender_buffer
, sizeof(m
->sender_buffer
), ":1.%llu", (unsigned long long) k
->src_id
);
605 m
->sender
= m
->creds
.unique_name
= m
->sender_buffer
;
609 m
->destination
= destination
;
610 else if (k
->dst_id
== KDBUS_DST_ID_BROADCAST
)
611 m
->destination
= NULL
;
612 else if (k
->dst_id
== KDBUS_DST_ID_NAME
)
613 m
->destination
= bus
->unique_name
; /* fill in unique name if the well-known name is missing */
615 snprintf(m
->destination_buffer
, sizeof(m
->destination_buffer
), ":1.%llu", (unsigned long long) k
->dst_id
);
616 m
->destination
= m
->destination_buffer
;
619 /* We take possession of the kmsg struct now */
621 m
->release_kdbus
= true;
625 bus
->rqueue
[bus
->rqueue_size
++] = m
;
631 struct bus_body_part
*part
;
634 /* Make sure the memfds are not freed twice */
635 MESSAGE_FOREACH_PART(part
, i
, m
)
636 if (part
->memfd
>= 0)
639 sd_bus_message_unref(m
);
645 int bus_kernel_take_fd(sd_bus
*b
) {
646 struct kdbus_cmd_hello
*hello
;
647 struct kdbus_item
*item
;
648 _cleanup_free_
char *g
= NULL
;
650 size_t l
= 0, m
= 0, sz
;
660 if (b
->connection_name
) {
661 g
= sd_bus_label_escape(b
->connection_name
);
669 /* If no name is explicitly set, we'll include a hint
670 * indicating the library implementation, a hint which
671 * kind of bus this is and the thread name */
673 assert_se(prctl(PR_GET_NAME
, (unsigned long) pr
) >= 0);
676 name
= b
->is_system
? "sd-system" :
677 b
->is_user
? "sd-user" : "sd";
679 _cleanup_free_
char *e
= NULL
;
681 e
= sd_bus_label_escape(pr
);
685 g
= strappend(b
->is_system
? "sd-system-" :
686 b
->is_user
? "sd-user-" : "sd-",
694 b
->connection_name
= sd_bus_label_unescape(name
);
695 if (!b
->connection_name
)
701 sz
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
)) +
702 ALIGN8(offsetof(struct kdbus_item
, str
) + m
+ 1);
704 if (b
->fake_creds_valid
)
705 sz
+= ALIGN8(offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
));
708 l
= strlen(b
->fake_label
);
709 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + l
+ 1);
714 hello
->conn_flags
= b
->hello_flags
;
715 hello
->attach_flags
= b
->attach_flags
;
716 hello
->pool_size
= KDBUS_POOL_SIZE
;
720 item
->size
= offsetof(struct kdbus_item
, str
) + m
+ 1;
721 item
->type
= KDBUS_ITEM_CONN_NAME
;
722 memcpy(item
->str
, name
, m
+ 1);
723 item
= KDBUS_ITEM_NEXT(item
);
725 if (b
->fake_creds_valid
) {
726 item
->size
= offsetof(struct kdbus_item
, creds
) + sizeof(struct kdbus_creds
);
727 item
->type
= KDBUS_ITEM_CREDS
;
728 item
->creds
= b
->fake_creds
;
730 item
= KDBUS_ITEM_NEXT(item
);
734 item
->size
= offsetof(struct kdbus_item
, str
) + l
+ 1;
735 item
->type
= KDBUS_ITEM_SECLABEL
;
736 memcpy(item
->str
, b
->fake_label
, l
+1);
739 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
743 if (!b
->kdbus_buffer
) {
744 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
, MAP_SHARED
, b
->input_fd
, 0);
745 if (b
->kdbus_buffer
== MAP_FAILED
) {
746 b
->kdbus_buffer
= NULL
;
751 /* The higher 32bit of both flags fields are considered
752 * 'incompatible flags'. Refuse them all for now. */
753 if (hello
->bus_flags
> 0xFFFFFFFFULL
||
754 hello
->conn_flags
> 0xFFFFFFFFULL
)
757 if (!bloom_validate_parameters((size_t) hello
->bloom
.size
, (unsigned) hello
->bloom
.n_hash
))
760 b
->bloom_size
= (size_t) hello
->bloom
.size
;
761 b
->bloom_n_hash
= (unsigned) hello
->bloom
.n_hash
;
763 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0)
766 b
->unique_id
= hello
->id
;
769 b
->bus_client
= true;
770 b
->can_fds
= !!(hello
->conn_flags
& KDBUS_HELLO_ACCEPT_FD
);
771 b
->message_version
= 2;
772 b
->message_endian
= BUS_NATIVE_ENDIAN
;
774 /* the kernel told us the UUID of the underlying bus */
775 memcpy(b
->server_id
.bytes
, hello
->id128
, sizeof(b
->server_id
.bytes
));
777 return bus_start_running(b
);
780 int bus_kernel_connect(sd_bus
*b
) {
782 assert(b
->input_fd
< 0);
783 assert(b
->output_fd
< 0);
789 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
793 b
->output_fd
= b
->input_fd
;
795 return bus_kernel_take_fd(b
);
798 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
800 struct kdbus_item
*d
;
805 off
= (uint8_t *)k
- (uint8_t *)bus
->kdbus_buffer
;
806 ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &off
);
808 KDBUS_ITEM_FOREACH(d
, k
, items
) {
810 if (d
->type
== KDBUS_ITEM_FDS
)
811 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
812 else if (d
->type
== KDBUS_ITEM_PAYLOAD_MEMFD
)
813 close_nointr_nofail(d
->memfd
.fd
);
817 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
, bool hint_sync_call
) {
822 assert(bus
->state
== BUS_RUNNING
);
824 /* If we can't deliver, we want room for the error message */
825 r
= bus_rqueue_make_room(bus
);
829 r
= bus_message_setup_kmsg(bus
, m
);
833 /* If this is a synchronous method call, then let's tell the
834 * kernel, so that it can pass CPU time/scheduling to the
835 * destination for the time, if it wants to. If we
836 * synchronously wait for the result anyway, we won't need CPU
839 m
->kdbus
->flags
|= KDBUS_MSG_FLAGS_EXPECT_REPLY
|KDBUS_MSG_FLAGS_SYNC_REPLY
;
841 r
= ioctl(bus
->output_fd
, KDBUS_CMD_MSG_SEND
, m
->kdbus
);
843 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
844 sd_bus_message
*reply
;
846 if (errno
== EAGAIN
|| errno
== EINTR
)
848 else if (errno
== ENXIO
|| errno
== ESRCH
) {
850 /* ENXIO: unique name not known
851 * ESRCH: well-known name not known */
853 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
854 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Destination %s not known", m
->destination
);
856 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m
->destination
);
860 } else if (errno
== EADDRNOTAVAIL
) {
862 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
864 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
865 sd_bus_error_setf(&error
, SD_BUS_ERROR_SERVICE_UNKNOWN
, "Activation of %s not requested", m
->destination
);
867 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m
->destination
);
873 r
= bus_message_new_synthetic_error(
875 BUS_MESSAGE_COOKIE(m
),
882 r
= bus_seal_synthetic_message(bus
, reply
);
886 bus
->rqueue
[bus
->rqueue_size
++] = reply
;
888 } else if (hint_sync_call
) {
891 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ m
->kdbus
->offset_reply
);
894 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
896 r
= bus_kernel_make_message(bus
, k
);
898 close_kdbus_msg(bus
, k
);
900 /* Anybody can send us invalid messages, let's just drop them. */
901 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
)
902 log_debug("Ignoring invalid message: %s", strerror(-r
));
907 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
908 close_kdbus_msg(bus
, k
);
915 static int push_name_owner_changed(sd_bus
*bus
, const char *name
, const char *old_owner
, const char *new_owner
) {
916 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
921 r
= sd_bus_message_new_signal(
923 "/org/freedesktop/DBus",
924 "org.freedesktop.DBus",
930 r
= sd_bus_message_append(m
, "sss", name
, old_owner
, new_owner
);
934 m
->sender
= "org.freedesktop.DBus";
936 r
= bus_seal_synthetic_message(bus
, m
);
940 bus
->rqueue
[bus
->rqueue_size
++] = m
;
946 static int translate_name_change(sd_bus
*bus
, struct kdbus_msg
*k
, struct kdbus_item
*d
) {
947 char new_owner
[UNIQUE_NAME_MAX
], old_owner
[UNIQUE_NAME_MAX
];
953 if (d
->type
== KDBUS_ITEM_NAME_ADD
|| (d
->name_change
.old
.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
)))
956 sprintf(old_owner
, ":1.%llu", (unsigned long long) d
->name_change
.old
.id
);
958 if (d
->type
== KDBUS_ITEM_NAME_REMOVE
|| (d
->name_change
.new.flags
& (KDBUS_NAME_IN_QUEUE
|KDBUS_NAME_ACTIVATOR
))) {
960 if (isempty(old_owner
))
965 sprintf(new_owner
, ":1.%llu", (unsigned long long) d
->name_change
.new.id
);
967 return push_name_owner_changed(bus
, d
->name_change
.name
, old_owner
, new_owner
);
970 static int translate_id_change(sd_bus
*bus
, struct kdbus_msg
*k
, struct kdbus_item
*d
) {
971 char owner
[UNIQUE_NAME_MAX
];
977 sprintf(owner
, ":1.%llu", d
->id_change
.id
);
979 return push_name_owner_changed(
981 d
->type
== KDBUS_ITEM_ID_ADD
? NULL
: owner
,
982 d
->type
== KDBUS_ITEM_ID_ADD
? owner
: NULL
);
985 static int translate_reply(sd_bus
*bus
, struct kdbus_msg
*k
, struct kdbus_item
*d
) {
986 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
993 r
= bus_message_new_synthetic_error(
996 d
->type
== KDBUS_ITEM_REPLY_TIMEOUT
?
997 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call timed out") :
998 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY
, "Method call peer died"),
1003 m
->sender
= "org.freedesktop.DBus";
1005 r
= bus_seal_synthetic_message(bus
, m
);
1009 bus
->rqueue
[bus
->rqueue_size
++] = m
;
1015 static int bus_kernel_translate_message(sd_bus
*bus
, struct kdbus_msg
*k
) {
1016 struct kdbus_item
*d
, *found
= NULL
;
1018 static int (* const translate
[])(sd_bus
*bus
, struct kdbus_msg
*k
, struct kdbus_item
*d
) = {
1019 [KDBUS_ITEM_NAME_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1020 [KDBUS_ITEM_NAME_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1021 [KDBUS_ITEM_NAME_CHANGE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_name_change
,
1023 [KDBUS_ITEM_ID_ADD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1024 [KDBUS_ITEM_ID_REMOVE
- _KDBUS_ITEM_KERNEL_BASE
] = translate_id_change
,
1026 [KDBUS_ITEM_REPLY_TIMEOUT
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1027 [KDBUS_ITEM_REPLY_DEAD
- _KDBUS_ITEM_KERNEL_BASE
] = translate_reply
,
1032 assert(k
->payload_type
== KDBUS_PAYLOAD_KERNEL
);
1034 KDBUS_ITEM_FOREACH(d
, k
, items
) {
1035 if (d
->type
>= _KDBUS_ITEM_KERNEL_BASE
&& d
->type
< _KDBUS_ITEM_KERNEL_BASE
+ ELEMENTSOF(translate
)) {
1040 log_debug("Got unknown field from kernel %llu", d
->type
);
1044 log_debug("Didn't find a kernel message to translate.");
1048 return translate
[found
->type
- _KDBUS_ITEM_KERNEL_BASE
](bus
, k
, found
);
1051 int bus_kernel_read_message(sd_bus
*bus
, bool hint_priority
, int64_t priority
) {
1052 struct kdbus_cmd_recv recv
= {};
1053 struct kdbus_msg
*k
;
1058 r
= bus_rqueue_make_room(bus
);
1062 if (hint_priority
) {
1063 recv
.flags
|= KDBUS_RECV_USE_PRIORITY
;
1064 recv
.priority
= priority
;
1067 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MSG_RECV
, &recv
);
1069 if (errno
== EAGAIN
)
1075 k
= (struct kdbus_msg
*)((uint8_t *)bus
->kdbus_buffer
+ recv
.offset
);
1076 if (k
->payload_type
== KDBUS_PAYLOAD_DBUS
) {
1077 r
= bus_kernel_make_message(bus
, k
);
1079 /* Anybody can send us invalid messages, let's just drop them. */
1080 if (r
== -EBADMSG
|| r
== -EPROTOTYPE
) {
1081 log_debug("Ignoring invalid message: %s", strerror(-r
));
1085 } else if (k
->payload_type
== KDBUS_PAYLOAD_KERNEL
)
1086 r
= bus_kernel_translate_message(bus
, k
);
1088 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k
->payload_type
);
1093 close_kdbus_msg(bus
, k
);
1095 return r
< 0 ? r
: 1;
1098 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *mapped
, size_t *allocated
) {
1099 struct memfd_cache
*c
;
1106 if (!bus
|| !bus
->is_kernel
)
1109 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) >= 0);
1111 if (bus
->n_memfd_cache
<= 0) {
1112 _cleanup_free_
char *g
= NULL
;
1113 struct kdbus_cmd_memfd_make
*cmd
;
1114 struct kdbus_item
*item
;
1118 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) >= 0);
1120 assert(bus
->connection_name
);
1122 g
= sd_bus_label_escape(bus
->connection_name
);
1127 sz
= ALIGN8(offsetof(struct kdbus_cmd_memfd_make
, items
)) +
1128 ALIGN8(offsetof(struct kdbus_item
, str
)) +
1134 item
->size
= ALIGN8(offsetof(struct kdbus_item
, str
)) + l
+ 1;
1135 item
->type
= KDBUS_ITEM_MEMFD_NAME
;
1136 memcpy(item
->str
, g
, l
+ 1);
1138 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MEMFD_NEW
, cmd
);
1148 c
= &bus
->memfd_cache
[--bus
->n_memfd_cache
];
1151 assert(c
->mapped
== 0 || c
->address
);
1153 *address
= c
->address
;
1154 *mapped
= c
->mapped
;
1155 *allocated
= c
->allocated
;
1158 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) >= 0);
1163 static void close_and_munmap(int fd
, void *address
, size_t size
) {
1165 assert_se(munmap(address
, PAGE_ALIGN(size
)) >= 0);
1167 close_nointr_nofail(fd
);
1170 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t mapped
, size_t allocated
) {
1171 struct memfd_cache
*c
;
1172 uint64_t max_mapped
= PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX
);
1175 assert(mapped
== 0 || address
);
1177 if (!bus
|| !bus
->is_kernel
) {
1178 close_and_munmap(fd
, address
, mapped
);
1182 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) >= 0);
1184 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
1185 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) >= 0);
1187 close_and_munmap(fd
, address
, mapped
);
1191 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
1193 c
->address
= address
;
1195 /* If overly long, let's return a bit to the OS */
1196 if (mapped
> max_mapped
) {
1197 assert_se(ioctl(fd
, KDBUS_CMD_MEMFD_SIZE_SET
, &max_mapped
) >= 0);
1198 assert_se(munmap((uint8_t*) address
+ max_mapped
, PAGE_ALIGN(mapped
- max_mapped
)) >= 0);
1199 c
->mapped
= c
->allocated
= max_mapped
;
1202 c
->allocated
= allocated
;
1205 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) >= 0);
1208 void bus_kernel_flush_memfd(sd_bus
*b
) {
1213 for (i
= 0; i
< b
->n_memfd_cache
; i
++)
1214 close_and_munmap(b
->memfd_cache
[i
].fd
, b
->memfd_cache
[i
].address
, b
->memfd_cache
[i
].mapped
);
1217 int kdbus_translate_request_name_flags(uint64_t flags
, uint64_t *kdbus_flags
) {
1220 assert(kdbus_flags
);
1222 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
1223 f
|= KDBUS_NAME_ALLOW_REPLACEMENT
;
1225 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
1226 f
|= KDBUS_NAME_REPLACE_EXISTING
;
1228 if (flags
& SD_BUS_NAME_QUEUE
)
1229 f
|= KDBUS_NAME_QUEUE
;
1235 int kdbus_translate_attach_flags(uint64_t mask
, uint64_t *kdbus_mask
) {
1240 if (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_GID
|SD_BUS_CREDS_PID
|SD_BUS_CREDS_PID_STARTTIME
|SD_BUS_CREDS_TID
))
1241 m
|= KDBUS_ATTACH_CREDS
;
1243 if (mask
& (SD_BUS_CREDS_COMM
|SD_BUS_CREDS_TID_COMM
))
1244 m
|= KDBUS_ATTACH_COMM
;
1246 if (mask
& SD_BUS_CREDS_EXE
)
1247 m
|= KDBUS_ATTACH_EXE
;
1249 if (mask
& SD_BUS_CREDS_CMDLINE
)
1250 m
|= KDBUS_ATTACH_CMDLINE
;
1252 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
))
1253 m
|= KDBUS_ATTACH_CGROUP
;
1255 if (mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
))
1256 m
|= KDBUS_ATTACH_CAPS
;
1258 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
)
1259 m
|= KDBUS_ATTACH_SECLABEL
;
1261 if (mask
& (SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
))
1262 m
|= KDBUS_ATTACH_AUDIT
;
1264 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
)
1265 m
|= KDBUS_ATTACH_NAMES
;
1267 if (mask
& SD_BUS_CREDS_CONNECTION_NAME
)
1268 m
|= KDBUS_ATTACH_CONN_NAME
;
1274 int bus_kernel_create_bus(const char *name
, bool world
, char **s
) {
1275 struct kdbus_cmd_make
*make
;
1276 struct kdbus_item
*n
;
1282 fd
= open("/dev/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1286 make
= alloca0(ALIGN8(offsetof(struct kdbus_cmd_make
, items
) +
1287 offsetof(struct kdbus_item
, data64
) + sizeof(uint64_t) +
1288 offsetof(struct kdbus_item
, str
) +
1289 DECIMAL_STR_MAX(uid_t
) + 1 + strlen(name
) + 1));
1291 make
->size
= offsetof(struct kdbus_cmd_make
, items
);
1294 n
->size
= offsetof(struct kdbus_item
, bloom_parameter
) +
1295 sizeof(struct kdbus_bloom_parameter
);
1296 n
->type
= KDBUS_ITEM_BLOOM_PARAMETER
;
1298 n
->bloom_parameter
.size
= DEFAULT_BLOOM_SIZE
;
1299 n
->bloom_parameter
.n_hash
= DEFAULT_BLOOM_N_HASH
;
1301 assert_cc(DEFAULT_BLOOM_SIZE
> 0);
1302 assert_cc(DEFAULT_BLOOM_N_HASH
> 0);
1304 make
->size
+= ALIGN8(n
->size
);
1306 n
= KDBUS_ITEM_NEXT(n
);
1307 sprintf(n
->str
, "%lu-%s", (unsigned long) getuid(), name
);
1308 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1309 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1310 make
->size
+= ALIGN8(n
->size
);
1312 make
->flags
= KDBUS_MAKE_POLICY_OPEN
| (world
? KDBUS_MAKE_ACCESS_WORLD
: 0);
1314 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
1315 close_nointr_nofail(fd
);
1319 /* The higher 32bit of the flags field are considered
1320 * 'incompatible flags'. Refuse them all for now. */
1321 if (make
->flags
> 0xFFFFFFFFULL
) {
1322 close_nointr_nofail(fd
);
1329 p
= strjoin("/dev/kdbus/", n
->str
, "/bus", NULL
);
1331 close_nointr_nofail(fd
);
1341 int bus_kernel_create_starter(const char *bus
, const char *name
) {
1342 struct kdbus_cmd_hello
*hello
;
1343 struct kdbus_item
*n
;
1350 p
= alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + sizeof("/bus"));
1351 sprintf(p
, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus
);
1353 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1357 hello
= alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello
, items
) +
1358 offsetof(struct kdbus_item
, str
) +
1362 strcpy(n
->str
, name
);
1363 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1364 n
->type
= KDBUS_ITEM_NAME
;
1366 hello
->size
= ALIGN8(offsetof(struct kdbus_cmd_hello
, items
) + n
->size
);
1367 hello
->conn_flags
= KDBUS_HELLO_ACTIVATOR
;
1368 hello
->pool_size
= KDBUS_POOL_SIZE
;
1370 if (ioctl(fd
, KDBUS_CMD_HELLO
, hello
) < 0) {
1371 close_nointr_nofail(fd
);
1375 /* The higher 32bit of both flags fields are considered
1376 * 'incompatible flags'. Refuse them all for now. */
1377 if (hello
->bus_flags
> 0xFFFFFFFFULL
||
1378 hello
->conn_flags
> 0xFFFFFFFFULL
) {
1379 close_nointr_nofail(fd
);
1383 if (!bloom_validate_parameters((size_t) hello
->bloom
.size
, (unsigned) hello
->bloom
.n_hash
)) {
1384 close_nointr_nofail(fd
);
1391 int bus_kernel_create_domain(const char *name
, char **s
) {
1392 struct kdbus_cmd_make
*make
;
1393 struct kdbus_item
*n
;
1399 fd
= open("/dev/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1403 make
= alloca0(ALIGN8(offsetof(struct kdbus_cmd_make
, items
) +
1404 offsetof(struct kdbus_item
, str
) +
1408 strcpy(n
->str
, name
);
1409 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
1410 n
->type
= KDBUS_ITEM_MAKE_NAME
;
1412 make
->size
= ALIGN8(offsetof(struct kdbus_cmd_make
, items
) + n
->size
);
1413 make
->flags
= KDBUS_MAKE_POLICY_OPEN
| KDBUS_MAKE_ACCESS_WORLD
;
1415 if (ioctl(fd
, KDBUS_CMD_DOMAIN_MAKE
, make
) < 0) {
1416 close_nointr_nofail(fd
);
1420 /* The higher 32bit of the flags field are considered
1421 * 'incompatible flags'. Refuse them all for now. */
1422 if (make
->flags
> 0xFFFFFFFFULL
) {
1423 close_nointr_nofail(fd
);
1430 p
= strappend("/dev/kdbus/domain/", name
);
1432 close_nointr_nofail(fd
);
1442 int bus_kernel_create_monitor(const char *bus
) {
1443 struct kdbus_cmd_hello
*hello
;
1449 p
= alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t
) + 1 + strlen(bus
) + sizeof("/bus"));
1450 sprintf(p
, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus
);
1452 fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
1456 hello
= alloca0(sizeof(struct kdbus_cmd_hello
));
1457 hello
->size
= sizeof(struct kdbus_cmd_hello
);
1458 hello
->conn_flags
= KDBUS_HELLO_ACTIVATOR
;
1459 hello
->pool_size
= KDBUS_POOL_SIZE
;
1461 if (ioctl(fd
, KDBUS_CMD_HELLO
, hello
) < 0) {
1462 close_nointr_nofail(fd
);
1466 /* The higher 32bit of both flags fields are considered
1467 * 'incompatible flags'. Refuse them all for now. */
1468 if (hello
->bus_flags
> 0xFFFFFFFFULL
||
1469 hello
->conn_flags
> 0xFFFFFFFFULL
) {
1470 close_nointr_nofail(fd
);
1477 int bus_kernel_try_close(sd_bus
*bus
) {
1479 assert(bus
->is_kernel
);
1481 if (ioctl(bus
->input_fd
, KDBUS_CMD_BYEBYE
) < 0)
1487 int bus_kernel_drop_one(int fd
) {
1488 struct kdbus_cmd_recv recv
= {
1489 .flags
= KDBUS_RECV_DROP
1494 if (ioctl(fd
, KDBUS_CMD_MSG_RECV
, &recv
) < 0)