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>
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-kernel.h"
35 #include "bus-bloom.h"
37 #define KDBUS_ITEM_NEXT(item) \
38 (typeof(item))(((uint8_t *)item) + ALIGN8((item)->size))
40 #define KDBUS_ITEM_FOREACH(item, head) \
41 for (item = (head)->items; \
42 (uint8_t *)(item) < (uint8_t *)(head) + (head)->size; \
43 item = KDBUS_ITEM_NEXT(item))
45 #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
46 #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
48 static int parse_unique_name(const char *s
, uint64_t *id
) {
54 if (!startswith(s
, ":1."))
57 r
= safe_atou64(s
+ 3, id
);
64 static void append_payload_vec(struct kdbus_item
**d
, const void *p
, size_t sz
) {
70 /* Note that p can be NULL, which encodes a region full of
71 * zeroes, which is useful to optimize certain padding
74 (*d
)->size
= offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
);
75 (*d
)->type
= KDBUS_MSG_PAYLOAD_VEC
;
76 (*d
)->vec
.address
= PTR_TO_UINT64(p
);
79 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
82 static void append_payload_memfd(struct kdbus_item
**d
, int memfd
, size_t sz
) {
88 (*d
)->size
= offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
);
89 (*d
)->type
= KDBUS_MSG_PAYLOAD_MEMFD
;
90 (*d
)->memfd
.fd
= memfd
;
91 (*d
)->memfd
.size
= sz
;
93 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
96 static void append_destination(struct kdbus_item
**d
, const char *s
, size_t length
) {
102 (*d
)->size
= offsetof(struct kdbus_item
, str
) + length
+ 1;
103 (*d
)->type
= KDBUS_MSG_DST_NAME
;
104 memcpy((*d
)->str
, s
, length
+ 1);
106 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
109 static void* append_bloom(struct kdbus_item
**d
, size_t length
) {
116 (*d
)->size
= offsetof(struct kdbus_item
, data
) + length
;
117 (*d
)->type
= KDBUS_MSG_BLOOM
;
120 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
125 static void append_fds(struct kdbus_item
**d
, const int fds
[], unsigned n_fds
) {
131 (*d
)->size
= offsetof(struct kdbus_item
, fds
) + sizeof(int) * n_fds
;
132 (*d
)->type
= KDBUS_MSG_FDS
;
133 memcpy((*d
)->fds
, fds
, sizeof(int) * n_fds
);
135 *d
= (struct kdbus_item
*) ((uint8_t*) *d
+ (*d
)->size
);
138 static int bus_message_setup_bloom(sd_bus_message
*m
, void *bloom
) {
145 memset(bloom
, 0, BLOOM_SIZE
);
147 bloom_add_pair(bloom
, "message-type", bus_message_type_to_string(m
->header
->type
));
150 bloom_add_pair(bloom
, "interface", m
->interface
);
152 bloom_add_pair(bloom
, "member", m
->member
);
154 bloom_add_pair(bloom
, "path", m
->path
);
155 bloom_add_prefixes(bloom
, "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");
185 *(e
++) = '0' + (i
/ 10);
186 *(e
++) = '0' + (i
% 10);
190 bloom_add_pair(bloom
, buf
, t
);
192 strcpy(e
, "-dot-prefix");
193 bloom_add_prefixes(bloom
, buf
, t
, '.');
194 strcpy(e
, "-slash-prefix");
195 bloom_add_prefixes(bloom
, 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
;
217 if (m
->destination
) {
218 r
= parse_unique_name(m
->destination
, &unique
);
226 sz
= offsetof(struct kdbus_msg
, items
);
228 assert_cc(ALIGN8(offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
)) ==
229 ALIGN8(offsetof(struct kdbus_item
, memfd
) + sizeof(struct kdbus_memfd
)));
231 /* Add in fixed header, fields header and payload */
232 sz
+= (1 + m
->n_body_parts
) *
233 ALIGN8(offsetof(struct kdbus_item
, vec
) + sizeof(struct kdbus_vec
));
235 /* Add space for bloom filter */
236 sz
+= ALIGN8(offsetof(struct kdbus_item
, data
) + BLOOM_SIZE
);
238 /* Add in well-known destination header */
240 dl
= strlen(m
->destination
);
241 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + dl
+ 1);
244 /* Add space for unix fds */
246 sz
+= ALIGN8(offsetof(struct kdbus_item
, fds
) + sizeof(int)*m
->n_fds
);
248 m
->kdbus
= memalign(8, sz
);
254 m
->free_kdbus
= true;
255 memset(m
->kdbus
, 0, sz
);
258 ((m
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY
) |
259 ((m
->header
->flags
& SD_BUS_MESSAGE_NO_AUTO_START
) ? KDBUS_MSG_FLAGS_NO_AUTO_START
: 0);
262 m
->destination
? unique
: KDBUS_DST_ID_BROADCAST
;
263 m
->kdbus
->payload_type
= KDBUS_PAYLOAD_DBUS1
;
264 m
->kdbus
->cookie
= m
->header
->serial
;
266 m
->kdbus
->timeout_ns
= m
->timeout
* NSEC_PER_USEC
;
271 append_destination(&d
, m
->destination
, dl
);
273 append_payload_vec(&d
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
275 MESSAGE_FOREACH_PART(part
, i
, m
) {
277 /* If this is padding then simply send a
278 * vector with a NULL data pointer which the
279 * kernel will just pass through. This is the
280 * most efficient way to encode zeroes */
282 append_payload_vec(&d
, NULL
, part
->size
);
286 if (part
->memfd
>= 0 && part
->sealed
&& m
->destination
) {
287 /* Try to send a memfd, if the part is
288 * sealed and this is not a broadcast. Since we can only */
290 append_payload_memfd(&d
, part
->memfd
, part
->size
);
294 /* Otherwise let's send a vector to the actual data,
295 * for that we need to map it first. */
296 r
= bus_body_part_map(part
);
300 append_payload_vec(&d
, part
->data
, part
->size
);
303 if (m
->kdbus
->dst_id
== KDBUS_DST_ID_BROADCAST
) {
306 p
= append_bloom(&d
, BLOOM_SIZE
);
307 r
= bus_message_setup_bloom(m
, p
);
313 append_fds(&d
, m
->fds
, m
->n_fds
);
315 m
->kdbus
->size
= (uint8_t*) d
- (uint8_t*) m
->kdbus
;
316 assert(m
->kdbus
->size
<= sz
);
325 int bus_kernel_take_fd(sd_bus
*b
) {
326 uint8_t h
[ALIGN8(sizeof(struct kdbus_cmd_hello
)) +
327 ALIGN8(KDBUS_ITEM_HEADER_SIZE
) +
328 ALIGN8(sizeof(struct kdbus_vec
))] = {};
330 struct kdbus_cmd_hello
*hello
= (struct kdbus_cmd_hello
*) h
;
339 if (!b
->kdbus_buffer
) {
340 b
->kdbus_buffer
= mmap(NULL
, KDBUS_POOL_SIZE
, PROT_READ
|PROT_WRITE
, MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
341 if (b
->kdbus_buffer
== MAP_FAILED
) {
342 b
->kdbus_buffer
= NULL
;
347 hello
->size
= sizeof(h
);
349 KDBUS_HELLO_ACCEPT_FD
|
350 KDBUS_HELLO_ATTACH_COMM
|
351 KDBUS_HELLO_ATTACH_EXE
|
352 KDBUS_HELLO_ATTACH_CMDLINE
|
353 KDBUS_HELLO_ATTACH_CGROUP
|
354 KDBUS_HELLO_ATTACH_CAPS
|
355 KDBUS_HELLO_ATTACH_SECLABEL
|
356 KDBUS_HELLO_ATTACH_AUDIT
;
358 hello
->items
[0].type
= KDBUS_HELLO_POOL
;
359 hello
->items
[0].size
= KDBUS_ITEM_HEADER_SIZE
+ sizeof(struct kdbus_vec
);
360 hello
->items
[0].vec
.address
= (uint64_t) b
->kdbus_buffer
;
361 hello
->items
[0].vec
.size
= KDBUS_POOL_SIZE
;
363 r
= ioctl(b
->input_fd
, KDBUS_CMD_HELLO
, hello
);
367 /* The higher 32bit of both flags fields are considered
368 * 'incompatible flags'. Refuse them all for now. */
369 if (hello
->bus_flags
> 0xFFFFFFFFULL
||
370 hello
->conn_flags
> 0xFFFFFFFFULL
)
373 if (hello
->bloom_size
!= BLOOM_SIZE
)
376 if (asprintf(&b
->unique_name
, ":1.%llu", (unsigned long long) hello
->id
) < 0)
380 b
->bus_client
= true;
383 r
= bus_start_running(b
);
390 int bus_kernel_connect(sd_bus
*b
) {
392 assert(b
->input_fd
< 0);
393 assert(b
->output_fd
< 0);
399 b
->input_fd
= open(b
->kernel
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
403 b
->output_fd
= b
->input_fd
;
405 return bus_kernel_take_fd(b
);
408 int bus_kernel_write_message(sd_bus
*bus
, sd_bus_message
*m
) {
413 assert(bus
->state
== BUS_RUNNING
);
415 r
= bus_message_setup_kmsg(bus
, m
);
419 r
= ioctl(bus
->output_fd
, KDBUS_CMD_MSG_SEND
, m
->kdbus
);
421 return errno
== EAGAIN
? 0 : -errno
;
426 static void close_kdbus_msg(sd_bus
*bus
, struct kdbus_msg
*k
) {
427 struct kdbus_item
*d
;
432 ioctl(bus
->input_fd
, KDBUS_CMD_MSG_RELEASE
, k
);
434 KDBUS_ITEM_FOREACH(d
, k
) {
436 if (d
->type
== KDBUS_MSG_FDS
)
437 close_many(d
->fds
, (d
->size
- offsetof(struct kdbus_item
, fds
)) / sizeof(int));
438 else if (d
->type
== KDBUS_MSG_PAYLOAD_MEMFD
)
439 close_nointr_nofail(d
->memfd
.fd
);
443 static int bus_kernel_make_message(sd_bus
*bus
, struct kdbus_msg
*k
, sd_bus_message
**ret
) {
444 sd_bus_message
*m
= NULL
;
445 struct kdbus_item
*d
;
447 _cleanup_free_
int *fds
= NULL
;
448 struct bus_header
*h
= NULL
;
449 size_t total
, n_bytes
= 0, idx
= 0;
450 const char *destination
= NULL
, *seclabel
= NULL
;
457 if (k
->payload_type
!= KDBUS_PAYLOAD_DBUS1
)
460 KDBUS_ITEM_FOREACH(d
, k
) {
463 l
= d
->size
- offsetof(struct kdbus_item
, data
);
465 if (d
->type
== KDBUS_MSG_PAYLOAD_VEC
) {
468 h
= UINT64_TO_PTR(d
->vec
.address
);
470 if (!bus_header_is_complete(h
, d
->vec
.size
))
474 n_bytes
+= d
->vec
.size
;
476 } else if (d
->type
== KDBUS_MSG_PAYLOAD_MEMFD
) {
481 n_bytes
+= d
->memfd
.size
;
483 } else if (d
->type
== KDBUS_MSG_FDS
) {
488 f
= realloc(fds
, sizeof(int) * (n_fds
+ j
));
493 memcpy(fds
+ n_fds
, d
->fds
, sizeof(int) * j
);
496 } else if (d
->type
== KDBUS_MSG_SRC_SECLABEL
)
503 r
= bus_header_message_size(h
, &total
);
507 if (n_bytes
!= total
)
510 r
= bus_message_from_header(h
, sizeof(struct bus_header
), fds
, n_fds
, NULL
, seclabel
, 0, &m
);
514 KDBUS_ITEM_FOREACH(d
, k
) {
517 l
= d
->size
- offsetof(struct kdbus_item
, data
);
519 if (d
->type
== KDBUS_MSG_PAYLOAD_VEC
) {
522 begin_body
= BUS_MESSAGE_BODY_BEGIN(m
);
524 if (idx
+ d
->vec
.size
> begin_body
) {
525 struct bus_body_part
*part
;
527 /* Contains body material */
529 part
= message_append_part(m
);
535 if (idx
>= begin_body
) {
536 part
->data
= UINT64_TO_PTR(d
->vec
.address
);
537 part
->size
= d
->vec
.size
;
539 part
->data
= d
->vec
.address
!= 0 ? (uint8_t*) UINT64_TO_PTR(d
->vec
.address
) + (begin_body
- idx
) : NULL
;
540 part
->size
= d
->vec
.size
- (begin_body
- idx
);
543 part
->is_zero
= d
->vec
.address
== 0;
548 } else if (d
->type
== KDBUS_MSG_PAYLOAD_MEMFD
) {
549 struct bus_body_part
*part
;
551 if (idx
< BUS_MESSAGE_BODY_BEGIN(m
)) {
556 part
= message_append_part(m
);
562 part
->memfd
= d
->memfd
.fd
;
563 part
->size
= d
->memfd
.size
;
566 idx
+= d
->memfd
.size
;
568 } else if (d
->type
== KDBUS_MSG_SRC_CREDS
) {
569 m
->pid_starttime
= d
->creds
.starttime
/ NSEC_PER_USEC
;
570 m
->uid
= d
->creds
.uid
;
571 m
->gid
= d
->creds
.gid
;
572 m
->pid
= d
->creds
.pid
;
573 m
->tid
= d
->creds
.tid
;
574 m
->uid_valid
= m
->gid_valid
= true;
575 } else if (d
->type
== KDBUS_MSG_TIMESTAMP
) {
576 m
->realtime
= d
->timestamp
.realtime_ns
/ NSEC_PER_USEC
;
577 m
->monotonic
= d
->timestamp
.monotonic_ns
/ NSEC_PER_USEC
;
578 } else if (d
->type
== KDBUS_MSG_SRC_PID_COMM
)
580 else if (d
->type
== KDBUS_MSG_SRC_TID_COMM
)
581 m
->tid_comm
= d
->str
;
582 else if (d
->type
== KDBUS_MSG_SRC_EXE
)
584 else if (d
->type
== KDBUS_MSG_SRC_CMDLINE
) {
586 m
->cmdline_length
= l
;
587 } else if (d
->type
== KDBUS_MSG_SRC_CGROUP
)
589 else if (d
->type
== KDBUS_MSG_SRC_AUDIT
)
590 m
->audit
= &d
->audit
;
591 else if (d
->type
== KDBUS_MSG_SRC_CAPS
) {
592 m
->capability
= d
->data
;
593 m
->capability_size
= l
;
594 } else if (d
->type
== KDBUS_MSG_DST_NAME
)
595 destination
= d
->str
;
596 else if (d
->type
!= KDBUS_MSG_FDS
&&
597 d
->type
!= KDBUS_MSG_SRC_SECLABEL
)
598 log_debug("Got unknown field from kernel %llu", d
->type
);
601 r
= bus_message_parse_fields(m
);
605 if (k
->src_id
== KDBUS_SRC_ID_KERNEL
)
606 m
->sender
= "org.freedesktop.DBus";
608 snprintf(m
->sender_buffer
, sizeof(m
->sender_buffer
), ":1.%llu", (unsigned long long) k
->src_id
);
609 m
->sender
= m
->sender_buffer
;
612 if (!m
->destination
) {
614 m
->destination
= destination
;
615 else if (k
->dst_id
!= KDBUS_DST_ID_WELL_KNOWN_NAME
&&
616 k
->dst_id
!= KDBUS_DST_ID_BROADCAST
) {
617 snprintf(m
->destination_buffer
, sizeof(m
->destination_buffer
), ":1.%llu", (unsigned long long) k
->dst_id
);
618 m
->destination
= m
->destination_buffer
;
622 /* We take possession of the kmsg struct now */
624 m
->bus
= sd_bus_ref(bus
);
625 m
->release_kdbus
= true;
635 struct bus_body_part
*part
;
638 /* Make sure the memfds are not freed twice */
639 MESSAGE_FOREACH_PART(part
, i
, m
)
640 if (part
->memfd
>= 0)
643 sd_bus_message_unref(m
);
649 int bus_kernel_read_message(sd_bus
*bus
, sd_bus_message
**m
) {
656 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MSG_RECV
, &k
);
664 r
= bus_kernel_make_message(bus
, k
, m
);
666 close_kdbus_msg(bus
, k
);
668 return r
< 0 ? r
: 1;
671 int bus_kernel_create(const char *name
, char **s
) {
672 struct kdbus_cmd_bus_make
*make
;
673 struct kdbus_item
*n
, *cg
;
681 fd
= open("/dev/kdbus/control", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
686 make
= alloca0(offsetof(struct kdbus_cmd_bus_make
, items
) +
687 KDBUS_ITEM_HEADER_SIZE
+ sizeof(uint64_t) +
688 KDBUS_ITEM_HEADER_SIZE
+ DECIMAL_STR_MAX(uid_t
) + 1 + l
+ 1);
691 cg
->type
= KDBUS_MAKE_CGROUP
;
693 cg
->size
= KDBUS_ITEM_HEADER_SIZE
+ sizeof(uint64_t);
695 n
= KDBUS_ITEM_NEXT(cg
);
696 n
->type
= KDBUS_MAKE_NAME
;
697 sprintf(n
->str
, "%lu-%s", (unsigned long) getuid(), name
);
698 n
->size
= KDBUS_ITEM_HEADER_SIZE
+ strlen(n
->str
) + 1;
700 make
->size
= offsetof(struct kdbus_cmd_bus_make
, items
) + cg
->size
+ n
->size
;
701 make
->flags
= KDBUS_MAKE_POLICY_OPEN
;
703 make
->bloom_size
= BLOOM_SIZE
;
704 assert_cc(BLOOM_SIZE
% 8 == 0);
706 p
= strjoin("/dev/kdbus/", n
->str
, "/bus", NULL
);
710 if (ioctl(fd
, KDBUS_CMD_BUS_MAKE
, make
) < 0) {
711 close_nointr_nofail(fd
);
722 int bus_kernel_pop_memfd(sd_bus
*bus
, void **address
, size_t *size
) {
723 struct memfd_cache
*c
;
729 if (!bus
|| !bus
->is_kernel
)
732 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
734 if (bus
->n_memfd_cache
<= 0) {
737 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
739 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MEMFD_NEW
, &fd
);
748 c
= &bus
->memfd_cache
[-- bus
->n_memfd_cache
];
751 assert(c
->size
== 0 || c
->address
);
753 *address
= c
->address
;
757 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
762 static void close_and_munmap(int fd
, void *address
, size_t size
) {
764 assert_se(munmap(address
, PAGE_ALIGN(size
)) == 0);
766 close_nointr_nofail(fd
);
769 void bus_kernel_push_memfd(sd_bus
*bus
, int fd
, void *address
, size_t size
) {
770 struct memfd_cache
*c
;
773 assert(size
== 0 || address
);
775 if (!bus
|| !bus
->is_kernel
) {
776 close_and_munmap(fd
, address
, size
);
780 assert_se(pthread_mutex_lock(&bus
->memfd_cache_mutex
) == 0);
782 if (bus
->n_memfd_cache
>= ELEMENTSOF(bus
->memfd_cache
)) {
783 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
785 close_and_munmap(fd
, address
, size
);
789 c
= &bus
->memfd_cache
[bus
->n_memfd_cache
++];
791 c
->address
= address
;
793 /* If overly long, let's return a bit to the OS */
794 if (size
> MEMFD_CACHE_ITEM_SIZE_MAX
) {
795 uint64_t sz
= MEMFD_CACHE_ITEM_SIZE_MAX
;
797 ioctl(bus
->input_fd
, KDBUS_CMD_MEMFD_SIZE_SET
, &sz
);
799 c
->size
= MEMFD_CACHE_ITEM_SIZE_MAX
;
803 assert_se(pthread_mutex_unlock(&bus
->memfd_cache_mutex
) == 0);
806 void bus_kernel_flush_memfd(sd_bus
*b
) {
811 for (i
= 0; i
< b
->n_memfd_cache
; i
++) {
812 if (b
->memfd_cache
[i
].size
> 0)
813 assert_se(munmap(b
->memfd_cache
[i
].address
, PAGE_ALIGN(b
->memfd_cache
[i
].size
)) == 0);
815 close_nointr_nofail(b
->memfd_cache
[i
].fd
);