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/>.
29 #include "time-util.h"
30 #include "memfd-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
40 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
42 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
47 if (old_base == new_base)
50 if ((uint8_t*) p < (uint8_t*) old_base)
53 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
56 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
59 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
63 if (part->memfd >= 0) {
64 /* If we can reuse the memfd, try that. For that it
65 * can't be sealed yet. */
68 assert(part->memfd_offset == 0);
69 assert(part->data == part->mmap_begin);
70 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
73 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
75 safe_close(part->memfd);
78 } else if (part->munmap_this)
79 munmap(part->mmap_begin, part->mapped);
80 else if (part->free_this)
87 static void message_reset_parts(sd_bus_message *m) {
88 struct bus_body_part *part;
93 while (m->n_body_parts > 0) {
94 struct bus_body_part *next = part->next;
95 message_free_part(m, part);
102 m->cached_rindex_part = NULL;
103 m->cached_rindex_part_begin = 0;
106 static void message_reset_containers(sd_bus_message *m) {
111 for (i = 0; i < m->n_containers; i++) {
112 free(m->containers[i].signature);
113 free(m->containers[i].offsets);
117 m->containers = NULL;
119 m->n_containers = m->containers_allocated = 0;
120 m->root_container.index = 0;
123 static void message_free(sd_bus_message *m) {
129 message_reset_parts(m);
131 if (m->release_kdbus)
132 bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
137 sd_bus_unref(m->bus);
140 close_many(m->fds, m->n_fds);
144 if (m->iovec != m->iovec_fixed)
147 if (m->destination_ptr) {
148 free(m->destination_ptr);
149 m->destination_ptr = NULL;
152 message_reset_containers(m);
153 free(m->root_container.signature);
154 free(m->root_container.offsets);
156 free(m->root_container.peeked_signature);
158 bus_creds_done(&m->creds);
162 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
164 size_t old_size, new_size, start;
171 old_size = sizeof(struct bus_header) + m->fields_size;
172 start = ALIGN_TO(old_size, align);
173 new_size = start + sz;
175 if (new_size < start ||
176 new_size > (size_t) ((uint32_t) -1))
179 if (old_size == new_size)
180 return (uint8_t*) m->header + old_size;
182 if (m->free_header) {
183 np = realloc(m->header, ALIGN8(new_size));
187 /* Initially, the header is allocated as part of of
188 * the sd_bus_message itself, let's replace it by
191 np = malloc(ALIGN8(new_size));
195 memcpy(np, m->header, sizeof(struct bus_header));
198 /* Zero out padding */
199 if (start > old_size)
200 memzero((uint8_t*) np + old_size, start - old_size);
204 m->fields_size = new_size - sizeof(struct bus_header);
206 /* Adjust quick access pointers */
207 m->path = adjust_pointer(m->path, op, old_size, m->header);
208 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
209 m->member = adjust_pointer(m->member, op, old_size, m->header);
210 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
211 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
212 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
214 m->free_header = true;
217 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
220 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
223 return (uint8_t*) np + start;
230 static int message_append_field_string(
242 /* dbus1 only allows 8bit header field ids */
246 /* dbus1 doesn't allow strings over 32bit, let's enforce this
247 * globally, to not risk convertability */
249 if (l > (size_t) (uint32_t) -1)
252 /* Signature "(yv)" where the variant contains "s" */
254 if (BUS_MESSAGE_IS_GVARIANT(m)) {
256 /* (field id 64bit, ((string + NUL) + NUL + signature string 's') */
257 p = message_extend_fields(m, 8, 8 + l + 1 + 1 + 1, true);
261 *((uint64_t*) p) = h;
268 *ret = (char*) p + 8;
271 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
272 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
281 ((uint32_t*) p)[1] = l;
282 memcpy(p + 8, s, l + 1);
285 *ret = (char*) p + 8;
291 static int message_append_field_signature(
302 /* dbus1 only allows 8bit header field ids */
306 /* dbus1 doesn't allow signatures over 8bit, let's enforce
307 * this globally, to not risk convertability */
312 /* Signature "(yv)" where the variant contains "g" */
314 if (BUS_MESSAGE_IS_GVARIANT(m))
315 /* For gvariant the serialization is the same as for normal strings */
316 return message_append_field_string(m, h, 'g', s, ret);
318 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
319 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
325 p[2] = SD_BUS_TYPE_SIGNATURE;
328 memcpy(p + 5, s, l + 1);
331 *ret = (const char*) p + 5;
337 static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x) {
342 /* dbus1 only allows 8bit header field ids */
346 if (BUS_MESSAGE_IS_GVARIANT(m)) {
347 /* (field id 64bit + ((value + NUL + signature string 'u') */
349 p = message_extend_fields(m, 8, 8 + 4 + 1 + 1, true);
353 *((uint64_t*) p) = h;
354 *((uint32_t*) (p + 8)) = x;
358 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
359 p = message_extend_fields(m, 8, 4 + 4, false);
368 ((uint32_t*) p)[1] = x;
374 static int message_append_field_uint64(sd_bus_message *m, uint64_t h, uint64_t x) {
379 /* dbus1 only allows 8bit header field ids */
383 if (BUS_MESSAGE_IS_GVARIANT(m)) {
384 /* (field id 64bit + ((value + NUL + signature string 't') */
386 p = message_extend_fields(m, 8, 8 + 8 + 1 + 1, true);
390 *((uint64_t*) p) = h;
391 *((uint64_t*) (p + 8)) = x;
395 /* (field id byte + (signature length + signature 't' + NUL) + 4 byte padding + value) */
396 p = message_extend_fields(m, 8, 4 + 4 + 8, false);
409 ((uint64_t*) p)[1] = x;
415 static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) {
418 if (BUS_MESSAGE_IS_GVARIANT(m))
419 return message_append_field_uint64(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, cookie);
421 /* 64bit cookies are not supported on dbus1 */
422 if (cookie > 0xffffffffUL)
425 return message_append_field_uint32(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) cookie);
429 int bus_message_from_header(
432 size_t header_accessible,
434 size_t footer_accessible,
438 const struct ucred *ucred,
441 sd_bus_message **ret) {
443 _cleanup_free_ sd_bus_message *m = NULL;
444 struct bus_header *h;
448 assert(header || header_accessible <= 0);
449 assert(footer || footer_accessible <= 0);
450 assert(fds || n_fds <= 0);
453 if (header_accessible < sizeof(struct bus_header))
456 if (header_accessible > message_size)
458 if (footer_accessible > message_size)
462 if (!IN_SET(h->version, 1, 2))
465 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
468 if (!IN_SET(h->endian, BUS_LITTLE_ENDIAN, BUS_BIG_ENDIAN))
471 /* Note that we are happy with unknown flags in the flags header! */
473 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
476 label_sz = strlen(label);
487 m->header_accessible = header_accessible;
489 m->footer_accessible = footer_accessible;
491 if (BUS_MESSAGE_IS_GVARIANT(m)) {
494 if (h->dbus2.cookie == 0)
497 /* dbus2 derives the sizes from the message size and
498 the offset table at the end, since it is formatted as
499 gvariant "yyyyuta{tv}v". Since the message itself is a
500 structure with precisely to variable sized entries,
501 there's only one offset in the table, which marks the
502 end of the fields array. */
504 ws = bus_gvariant_determine_word_size(message_size, 0);
505 if (footer_accessible < ws)
508 m->fields_size = bus_gvariant_read_word_le((uint8_t*) footer + footer_accessible - ws, ws);
509 if (ALIGN8(m->fields_size) > message_size - ws)
511 if (m->fields_size < sizeof(struct bus_header))
514 m->fields_size -= sizeof(struct bus_header);
515 m->body_size = message_size - (sizeof(struct bus_header) + ALIGN8(m->fields_size));
517 if (h->dbus1.serial == 0)
520 /* dbus1 has the sizes in the header */
521 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
522 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
524 if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
532 m->creds.pid = ucred->pid;
533 m->creds.euid = ucred->uid;
534 m->creds.egid = ucred->gid;
536 /* Due to namespace translations some data might be
537 * missing from this ucred record. */
538 if (m->creds.pid > 0)
539 m->creds.mask |= SD_BUS_CREDS_PID;
541 if (m->creds.euid != UID_INVALID)
542 m->creds.mask |= SD_BUS_CREDS_EUID;
544 if (m->creds.egid != GID_INVALID)
545 m->creds.mask |= SD_BUS_CREDS_EGID;
549 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
550 memcpy(m->creds.label, label, label_sz + 1);
552 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
555 m->bus = sd_bus_ref(bus);
562 int bus_message_from_malloc(
568 const struct ucred *ucred,
570 sd_bus_message **ret) {
576 r = bus_message_from_header(
578 buffer, length, /* in this case the initial bytes and the final bytes are the same */
587 sz = length - sizeof(struct bus_header) - ALIGN8(m->fields_size);
590 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(m->fields_size);
592 m->body.sealed = true;
597 m->iovec = m->iovec_fixed;
598 m->iovec[0].iov_base = buffer;
599 m->iovec[0].iov_len = length;
601 r = bus_message_parse_fields(m);
605 /* We take possession of the memory and fds now */
606 m->free_header = true;
617 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
622 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
627 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
628 m->header->endian = BUS_NATIVE_ENDIAN;
629 m->header->type = type;
630 m->header->version = bus ? bus->message_version : 1;
631 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
632 m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
633 m->bus = sd_bus_ref(bus);
635 if (bus->allow_interactive_authorization)
636 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
641 _public_ int sd_bus_message_new_signal(
645 const char *interface,
646 const char *member) {
651 assert_return(bus, -ENOTCONN);
652 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
653 assert_return(object_path_is_valid(path), -EINVAL);
654 assert_return(interface_name_is_valid(interface), -EINVAL);
655 assert_return(member_name_is_valid(member), -EINVAL);
656 assert_return(m, -EINVAL);
658 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
662 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
664 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
667 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
670 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
678 sd_bus_message_unref(t);
682 _public_ int sd_bus_message_new_method_call(
685 const char *destination,
687 const char *interface,
688 const char *member) {
693 assert_return(bus, -ENOTCONN);
694 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
695 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
696 assert_return(object_path_is_valid(path), -EINVAL);
697 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
698 assert_return(member_name_is_valid(member), -EINVAL);
699 assert_return(m, -EINVAL);
701 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
705 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
708 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
713 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
719 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
732 static int message_new_reply(
733 sd_bus_message *call,
735 sd_bus_message **m) {
740 assert_return(call, -EINVAL);
741 assert_return(call->sealed, -EPERM);
742 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
743 assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
744 assert_return(m, -EINVAL);
746 t = message_new(call->bus, type);
750 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
751 t->reply_cookie = BUS_MESSAGE_COOKIE(call);
752 if (t->reply_cookie == 0)
755 r = message_append_reply_cookie(t, t->reply_cookie);
760 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
765 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
766 t->enforced_reply_signature = call->enforced_reply_signature;
776 _public_ int sd_bus_message_new_method_return(
777 sd_bus_message *call,
778 sd_bus_message **m) {
780 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
783 _public_ int sd_bus_message_new_method_error(
784 sd_bus_message *call,
786 const sd_bus_error *e) {
791 assert_return(sd_bus_error_is_set(e), -EINVAL);
792 assert_return(m, -EINVAL);
794 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
798 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
803 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
808 t->error._need_free = -1;
818 _public_ int sd_bus_message_new_method_errorf(
819 sd_bus_message *call,
825 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
828 assert_return(name, -EINVAL);
829 assert_return(m, -EINVAL);
831 va_start(ap, format);
832 bus_error_setfv(&error, name, format, ap);
835 return sd_bus_message_new_method_error(call, m, &error);
838 _public_ int sd_bus_message_new_method_errno(
839 sd_bus_message *call,
842 const sd_bus_error *p) {
844 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
846 if (sd_bus_error_is_set(p))
847 return sd_bus_message_new_method_error(call, m, p);
849 sd_bus_error_set_errno(&berror, error);
851 return sd_bus_message_new_method_error(call, m, &berror);
854 _public_ int sd_bus_message_new_method_errnof(
855 sd_bus_message *call,
861 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
864 va_start(ap, format);
865 sd_bus_error_set_errnofv(&berror, error, format, ap);
868 return sd_bus_message_new_method_error(call, m, &berror);
871 void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
875 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
876 m->creds.well_known_names_local = true;
877 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
880 void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) {
884 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
885 m->creds.well_known_names_driver = true;
886 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
889 int bus_message_new_synthetic_error(
892 const sd_bus_error *e,
893 sd_bus_message **m) {
899 assert(sd_bus_error_is_set(e));
902 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
906 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
907 t->reply_cookie = cookie;
909 r = message_append_reply_cookie(t, t->reply_cookie);
913 if (bus && bus->unique_name) {
914 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
919 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
924 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
929 t->error._need_free = -1;
931 bus_message_set_sender_driver(bus, t);
941 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
942 assert_return(m, NULL);
944 assert(m->n_ref > 0);
950 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
955 assert(m->n_ref > 0);
965 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
966 assert_return(m, -EINVAL);
967 assert_return(type, -EINVAL);
969 *type = m->header->type;
973 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
976 assert_return(m, -EINVAL);
977 assert_return(cookie, -EINVAL);
979 c = BUS_MESSAGE_COOKIE(m);
983 *cookie = BUS_MESSAGE_COOKIE(m);
987 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
988 assert_return(m, -EINVAL);
989 assert_return(cookie, -EINVAL);
991 if (m->reply_cookie == 0)
994 *cookie = m->reply_cookie;
998 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
999 assert_return(m, -EINVAL);
1001 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
1002 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
1005 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
1006 assert_return(m, -EINVAL);
1008 return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
1011 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
1012 assert_return(m, -EINVAL);
1014 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
1015 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
1018 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
1019 assert_return(m, NULL);
1024 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
1025 assert_return(m, NULL);
1027 return m->interface;
1030 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
1031 assert_return(m, NULL);
1036 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
1037 assert_return(m, NULL);
1039 return m->destination;
1042 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
1043 assert_return(m, NULL);
1048 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
1049 assert_return(m, NULL);
1050 assert_return(sd_bus_error_is_set(&m->error), NULL);
1055 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
1056 assert_return(m, -EINVAL);
1057 assert_return(usec, -EINVAL);
1059 if (m->monotonic <= 0)
1062 *usec = m->monotonic;
1066 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
1067 assert_return(m, -EINVAL);
1068 assert_return(usec, -EINVAL);
1070 if (m->realtime <= 0)
1073 *usec = m->realtime;
1077 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
1078 assert_return(m, -EINVAL);
1079 assert_return(seqnum, -EINVAL);
1084 *seqnum = m->seqnum;
1088 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
1089 assert_return(m, NULL);
1091 if (m->creds.mask == 0)
1097 _public_ int sd_bus_message_is_signal(
1099 const char *interface,
1100 const char *member) {
1102 assert_return(m, -EINVAL);
1104 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1107 if (interface && (!m->interface || !streq(m->interface, interface)))
1110 if (member && (!m->member || !streq(m->member, member)))
1116 _public_ int sd_bus_message_is_method_call(
1118 const char *interface,
1119 const char *member) {
1121 assert_return(m, -EINVAL);
1123 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1126 if (interface && (!m->interface || !streq(m->interface, interface)))
1129 if (member && (!m->member || !streq(m->member, member)))
1135 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1136 assert_return(m, -EINVAL);
1138 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1141 if (name && (!m->error.name || !streq(m->error.name, name)))
1147 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1148 assert_return(m, -EINVAL);
1149 assert_return(!m->sealed, -EPERM);
1150 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1153 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
1155 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1160 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1161 assert_return(m, -EINVAL);
1162 assert_return(!m->sealed, -EPERM);
1165 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
1167 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
1172 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1173 assert_return(m, -EINVAL);
1174 assert_return(!m->sealed, -EPERM);
1177 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1179 m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1184 static struct bus_container *message_get_container(sd_bus_message *m) {
1187 if (m->n_containers == 0)
1188 return &m->root_container;
1190 assert(m->containers);
1191 return m->containers + m->n_containers - 1;
1194 struct bus_body_part *message_append_part(sd_bus_message *m) {
1195 struct bus_body_part *part;
1202 if (m->n_body_parts <= 0) {
1206 assert(m->body_end);
1208 part = new0(struct bus_body_part, 1);
1214 m->body_end->next = part;
1224 static void part_zero(struct bus_body_part *part, size_t sz) {
1229 /* All other fields can be left in their defaults */
1230 assert(!part->data);
1231 assert(part->memfd < 0);
1234 part->is_zero = true;
1235 part->sealed = true;
1238 static int part_make_space(
1239 struct sd_bus_message *m,
1240 struct bus_body_part *part,
1249 assert(!part->sealed);
1254 if (!part->data && part->memfd < 0) {
1255 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1256 part->mmap_begin = part->data;
1259 if (part->memfd >= 0) {
1261 if (part->allocated == 0 || sz > part->allocated) {
1262 uint64_t new_allocated;
1264 new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1265 r = memfd_set_size(part->memfd, new_allocated);
1271 part->allocated = new_allocated;
1274 if (!part->data || sz > part->mapped) {
1277 psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1278 if (part->mapped <= 0)
1279 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1281 n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
1283 if (n == MAP_FAILED) {
1288 part->mmap_begin = part->data = n;
1290 part->memfd_offset = 0;
1293 part->munmap_this = true;
1295 if (part->allocated == 0 || sz > part->allocated) {
1296 size_t new_allocated;
1298 new_allocated = sz > 0 ? 2 * sz : 64;
1299 n = realloc(part->data, new_allocated);
1306 part->allocated = new_allocated;
1307 part->free_this = true;
1312 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1318 static int message_add_offset(sd_bus_message *m, size_t offset) {
1319 struct bus_container *c;
1322 assert(BUS_MESSAGE_IS_GVARIANT(m));
1324 /* Add offset to current container, unless this is the first
1325 * item in it, which will have the 0 offset, which we can
1327 c = message_get_container(m);
1329 if (!c->need_offsets)
1332 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1335 c->offsets[c->n_offsets++] = offset;
1339 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1340 struct bus_container *c;
1347 /* Update counters */
1348 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1351 *c->array_size += expand;
1355 static void *message_extend_body(
1360 bool force_inline) {
1362 size_t start_body, end_body, padding, added;
1373 start_body = ALIGN_TO((size_t) m->body_size, align);
1374 end_body = start_body + sz;
1376 padding = start_body - m->body_size;
1377 added = padding + sz;
1379 /* Check for 32bit overflows */
1380 if (end_body > (size_t) ((uint32_t) -1) ||
1381 end_body < start_body) {
1387 struct bus_body_part *part = NULL;
1391 m->n_body_parts <= 0 ||
1392 m->body_end->sealed ||
1393 (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
1394 (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */
1398 part = message_append_part(m);
1402 part_zero(part, padding);
1405 part = message_append_part(m);
1409 r = part_make_space(m, part, sz, &p);
1413 struct bus_container *c;
1415 size_t os, start_part, end_part;
1421 start_part = ALIGN_TO(part->size, align);
1422 end_part = start_part + sz;
1424 r = part_make_space(m, part, end_part, &p);
1429 memzero(p, padding);
1430 p = (uint8_t*) p + padding;
1433 /* Readjust pointers */
1434 for (c = m->containers; c < m->containers + m->n_containers; c++)
1435 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1437 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1440 /* Return something that is not NULL and is aligned */
1441 p = (uint8_t *) NULL + align;
1443 m->body_size = end_body;
1444 message_extend_containers(m, added);
1447 r = message_add_offset(m, end_body);
1457 static int message_push_fd(sd_bus_message *m, int fd) {
1468 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1472 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1480 m->fds[m->n_fds] = copy;
1486 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1487 _cleanup_close_ int fd = -1;
1488 struct bus_container *c;
1492 assert_return(m, -EINVAL);
1493 assert_return(!m->sealed, -EPERM);
1494 assert_return(bus_type_is_basic(type), -EINVAL);
1495 assert_return(!m->poisoned, -ESTALE);
1497 c = message_get_container(m);
1499 if (c->signature && c->signature[c->index]) {
1500 /* Container signature is already set */
1502 if (c->signature[c->index] != type)
1507 /* Maybe we can append to the signature? But only if this is the top-level container */
1508 if (c->enclosing != 0)
1511 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1518 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1524 case SD_BUS_TYPE_SIGNATURE:
1525 case SD_BUS_TYPE_STRING:
1528 /* Fall through... */
1529 case SD_BUS_TYPE_OBJECT_PATH:
1537 case SD_BUS_TYPE_BOOLEAN:
1539 u8 = p && *(int*) p;
1545 case SD_BUS_TYPE_UNIX_FD:
1550 fd = message_push_fd(m, *(int*) p);
1561 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1562 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1569 a = message_extend_body(m, align, sz, true, false);
1576 *stored = (const uint8_t*) a;
1583 case SD_BUS_TYPE_STRING:
1584 /* To make things easy we'll serialize a NULL string
1585 * into the empty string */
1588 /* Fall through... */
1589 case SD_BUS_TYPE_OBJECT_PATH:
1595 sz = 4 + strlen(p) + 1;
1598 case SD_BUS_TYPE_SIGNATURE:
1603 sz = 1 + strlen(p) + 1;
1606 case SD_BUS_TYPE_BOOLEAN:
1608 u32 = p && *(int*) p;
1614 case SD_BUS_TYPE_UNIX_FD:
1619 fd = message_push_fd(m, *(int*) p);
1630 align = bus_type_get_alignment(type);
1631 sz = bus_type_get_size(type);
1638 a = message_extend_body(m, align, sz, false, false);
1642 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1643 *(uint32_t*) a = sz - 5;
1644 memcpy((uint8_t*) a + 4, p, sz - 4);
1647 *stored = (const uint8_t*) a + 4;
1649 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1650 *(uint8_t*) a = sz - 2;
1651 memcpy((uint8_t*) a + 1, p, sz - 1);
1654 *stored = (const uint8_t*) a + 1;
1663 if (type == SD_BUS_TYPE_UNIX_FD)
1666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1673 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1674 return message_append_basic(m, type, p, NULL);
1677 _public_ int sd_bus_message_append_string_space(
1682 struct bus_container *c;
1685 assert_return(m, -EINVAL);
1686 assert_return(s, -EINVAL);
1687 assert_return(!m->sealed, -EPERM);
1688 assert_return(!m->poisoned, -ESTALE);
1690 c = message_get_container(m);
1692 if (c->signature && c->signature[c->index]) {
1693 /* Container signature is already set */
1695 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1700 /* Maybe we can append to the signature? But only if this is the top-level container */
1701 if (c->enclosing != 0)
1704 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1711 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1712 a = message_extend_body(m, 1, size + 1, true, false);
1718 a = message_extend_body(m, 4, 4 + size + 1, false, false);
1722 *(uint32_t*) a = size;
1728 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1734 _public_ int sd_bus_message_append_string_iovec(
1736 const struct iovec *iov,
1744 assert_return(m, -EINVAL);
1745 assert_return(!m->sealed, -EPERM);
1746 assert_return(iov || n == 0, -EINVAL);
1747 assert_return(!m->poisoned, -ESTALE);
1749 size = IOVEC_TOTAL_SIZE(iov, n);
1751 r = sd_bus_message_append_string_space(m, size, &p);
1755 for (i = 0; i < n; i++) {
1757 if (iov[i].iov_base)
1758 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1760 memset(p, ' ', iov[i].iov_len);
1762 p += iov[i].iov_len;
1768 static int bus_message_open_array(
1770 struct bus_container *c,
1771 const char *contents,
1772 uint32_t **array_size,
1774 bool *need_offsets) {
1784 assert(need_offsets);
1786 if (!signature_is_single(contents, true))
1789 if (c->signature && c->signature[c->index]) {
1791 /* Verify the existing signature */
1793 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1796 if (!startswith(c->signature + c->index + 1, contents))
1799 nindex = c->index + 1 + strlen(contents);
1803 if (c->enclosing != 0)
1806 /* Extend the existing signature */
1808 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1814 nindex = e - c->signature;
1817 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1818 alignment = bus_gvariant_get_alignment(contents);
1822 /* Add alignment padding and add to offset list */
1823 if (!message_extend_body(m, alignment, 0, false, false))
1826 r = bus_gvariant_is_fixed_size(contents);
1830 *begin = m->body_size;
1831 *need_offsets = r == 0;
1835 struct bus_body_part *o;
1837 alignment = bus_type_get_alignment(contents[0]);
1841 a = message_extend_body(m, 4, 4, false, false);
1846 op = m->body_end->data;
1847 os = m->body_end->size;
1849 /* Add alignment between size and first element */
1850 if (!message_extend_body(m, alignment, 0, false, false))
1853 /* location of array size might have changed so let's readjust a */
1854 if (o == m->body_end)
1855 a = adjust_pointer(a, op, os, m->body_end->data);
1861 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1867 static int bus_message_open_variant(
1869 struct bus_container *c,
1870 const char *contents) {
1876 if (!signature_is_single(contents, false))
1879 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1882 if (c->signature && c->signature[c->index]) {
1884 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1890 if (c->enclosing != 0)
1893 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1900 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1901 /* Variants are always aligned to 8 */
1903 if (!message_extend_body(m, 8, 0, false, false))
1910 l = strlen(contents);
1911 a = message_extend_body(m, 1, 1 + l + 1, false, false);
1916 memcpy((uint8_t*) a + 1, contents, l + 1);
1919 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1925 static int bus_message_open_struct(
1927 struct bus_container *c,
1928 const char *contents,
1930 bool *need_offsets) {
1939 assert(need_offsets);
1941 if (!signature_is_valid(contents, false))
1944 if (c->signature && c->signature[c->index]) {
1947 l = strlen(contents);
1949 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1950 !startswith(c->signature + c->index + 1, contents) ||
1951 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1954 nindex = c->index + 1 + l + 1;
1958 if (c->enclosing != 0)
1961 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1967 nindex = e - c->signature;
1970 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1973 alignment = bus_gvariant_get_alignment(contents);
1977 if (!message_extend_body(m, alignment, 0, false, false))
1980 r = bus_gvariant_is_fixed_size(contents);
1984 *begin = m->body_size;
1985 *need_offsets = r == 0;
1987 /* Align contents to 8 byte boundary */
1988 if (!message_extend_body(m, 8, 0, false, false))
1992 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1998 static int bus_message_open_dict_entry(
2000 struct bus_container *c,
2001 const char *contents,
2003 bool *need_offsets) {
2011 assert(need_offsets);
2013 if (!signature_is_pair(contents))
2016 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2019 if (c->signature && c->signature[c->index]) {
2022 l = strlen(contents);
2024 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2025 !startswith(c->signature + c->index + 1, contents) ||
2026 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2031 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2034 alignment = bus_gvariant_get_alignment(contents);
2038 if (!message_extend_body(m, alignment, 0, false, false))
2041 r = bus_gvariant_is_fixed_size(contents);
2045 *begin = m->body_size;
2046 *need_offsets = r == 0;
2048 /* Align contents to 8 byte boundary */
2049 if (!message_extend_body(m, 8, 0, false, false))
2056 _public_ int sd_bus_message_open_container(
2059 const char *contents) {
2061 struct bus_container *c, *w;
2062 uint32_t *array_size = NULL;
2064 size_t before, begin = 0;
2065 bool need_offsets = false;
2068 assert_return(m, -EINVAL);
2069 assert_return(!m->sealed, -EPERM);
2070 assert_return(contents, -EINVAL);
2071 assert_return(!m->poisoned, -ESTALE);
2073 /* Make sure we have space for one more container */
2074 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
2079 c = message_get_container(m);
2081 signature = strdup(contents);
2087 /* Save old index in the parent container, in case we have to
2088 * abort this container */
2089 c->saved_index = c->index;
2090 before = m->body_size;
2092 if (type == SD_BUS_TYPE_ARRAY)
2093 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
2094 else if (type == SD_BUS_TYPE_VARIANT)
2095 r = bus_message_open_variant(m, c, contents);
2096 else if (type == SD_BUS_TYPE_STRUCT)
2097 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
2098 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2099 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
2108 /* OK, let's fill it in */
2109 w = m->containers + m->n_containers++;
2110 w->enclosing = type;
2111 w->signature = signature;
2113 w->array_size = array_size;
2116 w->n_offsets = w->offsets_allocated = 0;
2118 w->need_offsets = need_offsets;
2123 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2128 if (!BUS_MESSAGE_IS_GVARIANT(m))
2131 if (c->need_offsets) {
2132 size_t payload, sz, i;
2135 /* Variable-width arrays */
2137 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2138 sz = bus_gvariant_determine_word_size(payload, c->n_offsets);
2140 a = message_extend_body(m, 1, sz * c->n_offsets, true, false);
2144 for (i = 0; i < c->n_offsets; i++)
2145 bus_gvariant_write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2149 /* Fixed-width or empty arrays */
2151 a = message_extend_body(m, 1, 0, true, false); /* let's add offset to parent */
2159 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2165 assert(c->signature);
2167 if (!BUS_MESSAGE_IS_GVARIANT(m))
2170 l = strlen(c->signature);
2172 a = message_extend_body(m, 1, 1 + l, true, false);
2177 memcpy(a+1, c->signature, l);
2182 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2183 size_t n_variable = 0;
2192 if (!BUS_MESSAGE_IS_GVARIANT(m))
2195 p = strempty(c->signature);
2199 r = signature_element_length(p, &n);
2208 r = bus_gvariant_is_fixed_size(t);
2213 assert(!c->need_offsets || i <= c->n_offsets);
2215 /* We need to add an offset for each item that has a
2216 * variable size and that is not the last one in the
2218 if (r == 0 && p[n] != 0)
2225 assert(!c->need_offsets || i == c->n_offsets);
2226 assert(c->need_offsets || n_variable == 0);
2228 if (n_variable <= 0) {
2229 a = message_extend_body(m, 1, 0, add_offset, false);
2236 assert(c->offsets[c->n_offsets-1] == m->body_size);
2238 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2240 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2244 p = strempty(c->signature);
2245 for (i = 0, j = 0; i < c->n_offsets; i++) {
2249 r = signature_element_length(p, &n);
2260 r = bus_gvariant_is_fixed_size(t);
2263 if (r > 0 || p[0] == 0)
2267 k = n_variable - 1 - j;
2269 bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2278 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2279 struct bus_container *c;
2282 assert_return(m, -EINVAL);
2283 assert_return(!m->sealed, -EPERM);
2284 assert_return(m->n_containers > 0, -EINVAL);
2285 assert_return(!m->poisoned, -ESTALE);
2287 c = message_get_container(m);
2289 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2290 if (c->signature && c->signature[c->index] != 0)
2295 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2296 r = bus_message_close_array(m, c);
2297 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2298 r = bus_message_close_variant(m, c);
2299 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2300 r = bus_message_close_struct(m, c, true);
2302 assert_not_reached("Unknown container type");
2316 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2323 stack[*i].types = types;
2324 stack[*i].n_struct = n_struct;
2325 stack[*i].n_array = n_array;
2331 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2342 *types = stack[*i].types;
2343 *n_struct = stack[*i].n_struct;
2344 *n_array = stack[*i].n_array;
2349 int bus_message_append_ap(
2354 unsigned n_array, n_struct;
2355 TypeStack stack[BUS_CONTAINER_DEPTH];
2356 unsigned stack_ptr = 0;
2364 n_array = (unsigned) -1;
2365 n_struct = strlen(types);
2370 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2371 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2377 r = sd_bus_message_close_container(m);
2385 if (n_array != (unsigned) -1)
2394 case SD_BUS_TYPE_BYTE: {
2397 x = (uint8_t) va_arg(ap, int);
2398 r = sd_bus_message_append_basic(m, *t, &x);
2402 case SD_BUS_TYPE_BOOLEAN:
2403 case SD_BUS_TYPE_INT32:
2404 case SD_BUS_TYPE_UINT32:
2405 case SD_BUS_TYPE_UNIX_FD: {
2408 /* We assume a boolean is the same as int32_t */
2409 assert_cc(sizeof(int32_t) == sizeof(int));
2411 x = va_arg(ap, uint32_t);
2412 r = sd_bus_message_append_basic(m, *t, &x);
2416 case SD_BUS_TYPE_INT16:
2417 case SD_BUS_TYPE_UINT16: {
2420 x = (uint16_t) va_arg(ap, int);
2421 r = sd_bus_message_append_basic(m, *t, &x);
2425 case SD_BUS_TYPE_INT64:
2426 case SD_BUS_TYPE_UINT64: {
2429 x = va_arg(ap, uint64_t);
2430 r = sd_bus_message_append_basic(m, *t, &x);
2434 case SD_BUS_TYPE_DOUBLE: {
2437 x = va_arg(ap, double);
2438 r = sd_bus_message_append_basic(m, *t, &x);
2442 case SD_BUS_TYPE_STRING:
2443 case SD_BUS_TYPE_OBJECT_PATH:
2444 case SD_BUS_TYPE_SIGNATURE: {
2447 x = va_arg(ap, const char*);
2448 r = sd_bus_message_append_basic(m, *t, x);
2452 case SD_BUS_TYPE_ARRAY: {
2455 r = signature_element_length(t + 1, &k);
2461 memcpy(s, t + 1, k);
2464 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2469 if (n_array == (unsigned) -1) {
2474 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2480 n_array = va_arg(ap, unsigned);
2485 case SD_BUS_TYPE_VARIANT: {
2488 s = va_arg(ap, const char*);
2492 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2496 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2501 n_struct = strlen(s);
2502 n_array = (unsigned) -1;
2507 case SD_BUS_TYPE_STRUCT_BEGIN:
2508 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2511 r = signature_element_length(t, &k);
2518 memcpy(s, t + 1, k - 2);
2521 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2526 if (n_array == (unsigned) -1) {
2531 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2537 n_array = (unsigned) -1;
2553 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2557 assert_return(m, -EINVAL);
2558 assert_return(types, -EINVAL);
2559 assert_return(!m->sealed, -EPERM);
2560 assert_return(!m->poisoned, -ESTALE);
2562 va_start(ap, types);
2563 r = bus_message_append_ap(m, types, ap);
2569 _public_ int sd_bus_message_append_array_space(
2579 assert_return(m, -EINVAL);
2580 assert_return(!m->sealed, -EPERM);
2581 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2582 assert_return(ptr || size == 0, -EINVAL);
2583 assert_return(!m->poisoned, -ESTALE);
2585 /* alignment and size of the trivial types (except bool) is
2586 * identical for gvariant and dbus1 marshalling */
2587 align = bus_type_get_alignment(type);
2588 sz = bus_type_get_size(type);
2590 assert_se(align > 0);
2596 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2600 a = message_extend_body(m, align, size, false, false);
2604 r = sd_bus_message_close_container(m);
2612 _public_ int sd_bus_message_append_array(
2620 assert_return(m, -EINVAL);
2621 assert_return(!m->sealed, -EPERM);
2622 assert_return(bus_type_is_trivial(type), -EINVAL);
2623 assert_return(ptr || size == 0, -EINVAL);
2624 assert_return(!m->poisoned, -ESTALE);
2626 r = sd_bus_message_append_array_space(m, type, size, &p);
2631 memcpy(p, ptr, size);
2636 _public_ int sd_bus_message_append_array_iovec(
2639 const struct iovec *iov,
2647 assert_return(m, -EINVAL);
2648 assert_return(!m->sealed, -EPERM);
2649 assert_return(bus_type_is_trivial(type), -EINVAL);
2650 assert_return(iov || n == 0, -EINVAL);
2651 assert_return(!m->poisoned, -ESTALE);
2653 size = IOVEC_TOTAL_SIZE(iov, n);
2655 r = sd_bus_message_append_array_space(m, type, size, &p);
2659 for (i = 0; i < n; i++) {
2661 if (iov[i].iov_base)
2662 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2664 memzero(p, iov[i].iov_len);
2666 p = (uint8_t*) p + iov[i].iov_len;
2672 _public_ int sd_bus_message_append_array_memfd(
2679 _cleanup_close_ int copy_fd = -1;
2680 struct bus_body_part *part;
2686 assert_return(m, -EINVAL);
2687 assert_return(memfd >= 0, -EINVAL);
2688 assert_return(bus_type_is_trivial(type), -EINVAL);
2689 assert_return(size > 0, -EINVAL);
2690 assert_return(!m->sealed, -EPERM);
2691 assert_return(!m->poisoned, -ESTALE);
2693 r = memfd_set_sealed(memfd);
2697 copy_fd = dup(memfd);
2701 r = memfd_get_size(memfd, &real_size);
2705 if (offset == 0 && size == (uint64_t) -1)
2707 else if (offset + size > real_size)
2710 align = bus_type_get_alignment(type);
2711 sz = bus_type_get_size(type);
2713 assert_se(align > 0);
2716 if (offset % align != 0)
2722 if (size > (uint64_t) (uint32_t) -1)
2725 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2729 a = message_extend_body(m, align, 0, false, false);
2733 part = message_append_part(m);
2737 part->memfd = copy_fd;
2738 part->memfd_offset = offset;
2739 part->sealed = true;
2743 m->body_size += size;
2744 message_extend_containers(m, size);
2746 return sd_bus_message_close_container(m);
2749 _public_ int sd_bus_message_append_string_memfd(
2755 _cleanup_close_ int copy_fd = -1;
2756 struct bus_body_part *part;
2757 struct bus_container *c;
2762 assert_return(m, -EINVAL);
2763 assert_return(memfd >= 0, -EINVAL);
2764 assert_return(size > 0, -EINVAL);
2765 assert_return(!m->sealed, -EPERM);
2766 assert_return(!m->poisoned, -ESTALE);
2768 r = memfd_set_sealed(memfd);
2772 copy_fd = dup(memfd);
2776 r = memfd_get_size(memfd, &real_size);
2780 if (offset == 0 && size == (uint64_t) -1)
2782 else if (offset + size > real_size)
2785 /* We require this to be NUL terminated */
2789 if (size > (uint64_t) (uint32_t) -1)
2792 c = message_get_container(m);
2793 if (c->signature && c->signature[c->index]) {
2794 /* Container signature is already set */
2796 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2801 /* Maybe we can append to the signature? But only if this is the top-level container */
2802 if (c->enclosing != 0)
2805 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2812 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2813 a = message_extend_body(m, 4, 4, false, false);
2817 *(uint32_t*) a = size - 1;
2820 part = message_append_part(m);
2824 part->memfd = copy_fd;
2825 part->memfd_offset = offset;
2826 part->sealed = true;
2830 m->body_size += size;
2831 message_extend_containers(m, size);
2833 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2834 r = message_add_offset(m, m->body_size);
2841 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2847 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2851 assert_return(m, -EINVAL);
2852 assert_return(!m->sealed, -EPERM);
2853 assert_return(!m->poisoned, -ESTALE);
2855 r = sd_bus_message_open_container(m, 'a', "s");
2859 STRV_FOREACH(i, l) {
2860 r = sd_bus_message_append_basic(m, 's', *i);
2865 return sd_bus_message_close_container(m);
2868 static int bus_message_close_header(sd_bus_message *m) {
2872 /* The actual user data is finished now, we just complete the
2873 variant and struct now (at least on gvariant). Remember
2874 this position, so that during parsing we know where to to
2875 put the outer container end. */
2876 m->user_body_size = m->body_size;
2878 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2879 const char *signature;
2883 /* Add offset table to end of fields array */
2884 if (m->n_header_offsets >= 1) {
2888 assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2890 sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2891 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2895 for (i = 0; i < m->n_header_offsets; i++)
2896 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2899 /* Add gvariant NUL byte plus signature to the end of
2900 * the body, followed by the final offset pointing to
2901 * the end of the fields array */
2903 signature = strempty(m->root_container.signature);
2904 l = strlen(signature);
2906 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l, 1);
2907 d = message_extend_body(m, 1, 1 + l + sz, false, true);
2912 memcpy((uint8_t*) d + 1, signature, l);
2914 bus_gvariant_write_word_le((uint8_t*) d + 1 + l, sz, sizeof(struct bus_header) + m->fields_size);
2917 m->footer_accessible = 1 + l + sz;
2919 m->header->dbus1.fields_size = m->fields_size;
2920 m->header->dbus1.body_size = m->body_size;
2926 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2927 struct bus_body_part *part;
2937 if (m->n_containers > 0)
2943 if (cookie > 0xffffffffULL &&
2944 !BUS_MESSAGE_IS_GVARIANT(m))
2947 /* In vtables the return signature of method calls is listed,
2948 * let's check if they match if this is a response */
2949 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2950 m->enforced_reply_signature &&
2951 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2954 /* If gvariant marshalling is used we need to close the body structure */
2955 r = bus_message_close_struct(m, &m->root_container, false);
2959 /* If there's a non-trivial signature set, then add it in
2960 * here, but only on dbus1 */
2961 if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2962 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2968 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2973 r = bus_message_close_header(m);
2977 if (BUS_MESSAGE_IS_GVARIANT(m))
2978 m->header->dbus2.cookie = cookie;
2980 m->header->dbus1.serial = (uint32_t) cookie;
2982 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2984 /* Add padding at the end of the fields part, since we know
2985 * the body needs to start at an 8 byte alignment. We made
2986 * sure we allocated enough space for this, so all we need to
2987 * do here is to zero it out. */
2988 a = ALIGN8(m->fields_size) - m->fields_size;
2990 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2992 /* If this is something we can send as memfd, then let's seal
2993 the memfd now. Note that we can send memfds as payload only
2994 for directed messages, and not for broadcasts. */
2995 if (m->destination && m->bus->use_memfd) {
2996 MESSAGE_FOREACH_PART(part, i, m)
2997 if (part->memfd >= 0 &&
2999 (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
3000 part != m->body_end) { /* The last part may never be sent as memfd */
3003 /* Try to seal it if that makes
3004 * sense. First, unmap our own map to
3005 * make sure we don't keep it busy. */
3006 bus_body_part_unmap(part);
3008 /* Then, sync up real memfd size */
3010 r = memfd_set_size(part->memfd, sz);
3014 /* Finally, try to seal */
3015 if (memfd_set_sealed(part->memfd) >= 0)
3016 part->sealed = true;
3020 m->root_container.end = m->user_body_size;
3021 m->root_container.index = 0;
3022 m->root_container.offset_index = 0;
3023 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3030 int bus_body_part_map(struct bus_body_part *part) {
3039 if (part->size <= 0)
3042 /* For smaller zero parts (as used for padding) we don't need to map anything... */
3043 if (part->memfd < 0 && part->is_zero && part->size < 8) {
3044 static const uint8_t zeroes[7] = { };
3045 part->data = (void*) zeroes;
3049 shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3050 psz = PAGE_ALIGN(part->size + shift);
3052 if (part->memfd >= 0)
3053 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3054 else if (part->is_zero)
3055 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3059 if (p == MAP_FAILED)
3063 part->mmap_begin = p;
3064 part->data = (uint8_t*) p + shift;
3065 part->munmap_this = true;
3070 void bus_body_part_unmap(struct bus_body_part *part) {
3074 if (part->memfd < 0)
3077 if (!part->mmap_begin)
3080 if (!part->munmap_this)
3083 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3085 part->mmap_begin = NULL;
3088 part->munmap_this = false;
3093 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3094 size_t k, start, end;
3099 start = ALIGN_TO((size_t) *rindex, align);
3100 end = start + nbytes;
3105 /* Verify that padding is 0 */
3106 for (k = *rindex; k < start; k++)
3107 if (((const uint8_t*) p)[k] != 0)
3111 *r = (uint8_t*) p + start;
3118 static bool message_end_of_signature(sd_bus_message *m) {
3119 struct bus_container *c;
3123 c = message_get_container(m);
3124 return !c->signature || c->signature[c->index] == 0;
3127 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3128 struct bus_container *c;
3132 c = message_get_container(m);
3133 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3136 if (BUS_MESSAGE_IS_GVARIANT(m))
3137 return index >= c->end;
3139 assert(c->array_size);
3140 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3144 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3145 assert_return(m, -EINVAL);
3146 assert_return(m->sealed, -EPERM);
3148 if (complete && m->n_containers > 0)
3151 if (message_end_of_signature(m))
3154 if (message_end_of_array(m, m->rindex))
3160 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3161 struct bus_body_part *part;
3167 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3168 part = m->cached_rindex_part;
3169 begin = m->cached_rindex_part_begin;
3179 if (index + sz <= begin + part->size) {
3181 r = bus_body_part_map(part);
3186 *p = (uint8_t*) part->data + index - begin;
3188 m->cached_rindex_part = part;
3189 m->cached_rindex_part_begin = begin;
3194 begin += part->size;
3201 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3208 if (!BUS_MESSAGE_IS_GVARIANT(m))
3211 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3214 sz = bus_gvariant_get_size(c->signature);
3218 if (c->offset_index+1 >= c->n_offsets)
3221 /* Variable-size array */
3223 alignment = bus_gvariant_get_alignment(c->signature);
3224 assert(alignment > 0);
3226 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3227 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3230 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3233 /* Fixed-size array */
3234 *rindex = c->begin + (c->offset_index+1) * sz;
3240 } else if (c->enclosing == 0 ||
3241 c->enclosing == SD_BUS_TYPE_STRUCT ||
3242 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3247 if (c->offset_index+1 >= c->n_offsets)
3250 r = signature_element_length(c->signature + c->index, &n);
3254 r = signature_element_length(c->signature + c->index + n, &j);
3259 memcpy(t, c->signature + c->index + n, j);
3262 alignment = bus_gvariant_get_alignment(t);
3265 assert(alignment > 0);
3267 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3268 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3272 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3275 assert_not_reached("Unknown container type");
3280 /* Reached the end */
3287 static int message_peek_body(
3294 size_t k, start, end, padding;
3295 struct bus_body_part *part;
3302 start = ALIGN_TO((size_t) *rindex, align);
3303 padding = start - *rindex;
3304 end = start + nbytes;
3306 if (end > m->user_body_size)
3309 part = find_part(m, *rindex, padding, (void**) &q);
3314 /* Verify padding */
3315 for (k = 0; k < padding; k++)
3320 part = find_part(m, start, nbytes, (void**) &q);
3321 if (!part || (nbytes > 0 && !q))
3332 static bool validate_nul(const char *s, size_t l) {
3334 /* Check for NUL chars in the string */
3335 if (memchr(s, 0, l))
3338 /* Check for NUL termination */
3345 static bool validate_string(const char *s, size_t l) {
3347 if (!validate_nul(s, l))
3350 /* Check if valid UTF8 */
3351 if (!utf8_is_valid(s))
3357 static bool validate_signature(const char *s, size_t l) {
3359 if (!validate_nul(s, l))
3362 /* Check if valid signature */
3363 if (!signature_is_valid(s, true))
3369 static bool validate_object_path(const char *s, size_t l) {
3371 if (!validate_nul(s, l))
3374 if (!object_path_is_valid(s))
3380 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3381 struct bus_container *c;
3386 assert_return(m, -EINVAL);
3387 assert_return(m->sealed, -EPERM);
3388 assert_return(bus_type_is_basic(type), -EINVAL);
3390 if (message_end_of_signature(m))
3393 if (message_end_of_array(m, m->rindex))
3396 c = message_get_container(m);
3397 if (c->signature[c->index] != type)
3402 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3404 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3407 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3411 if (type == SD_BUS_TYPE_STRING)
3412 ok = validate_string(q, c->item_size-1);
3413 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3414 ok = validate_object_path(q, c->item_size-1);
3416 ok = validate_signature(q, c->item_size-1);
3422 *(const char**) p = q;
3426 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3428 if ((size_t) sz != c->item_size)
3431 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3434 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3440 case SD_BUS_TYPE_BYTE:
3442 *(uint8_t*) p = *(uint8_t*) q;
3445 case SD_BUS_TYPE_BOOLEAN:
3447 *(int*) p = !!*(uint8_t*) q;
3450 case SD_BUS_TYPE_INT16:
3451 case SD_BUS_TYPE_UINT16:
3453 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3456 case SD_BUS_TYPE_INT32:
3457 case SD_BUS_TYPE_UINT32:
3459 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3462 case SD_BUS_TYPE_INT64:
3463 case SD_BUS_TYPE_UINT64:
3464 case SD_BUS_TYPE_DOUBLE:
3466 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3469 case SD_BUS_TYPE_UNIX_FD: {
3472 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3477 *(int*) p = m->fds[j];
3483 assert_not_reached("unexpected type");
3487 r = container_next_item(m, c, &rindex);
3492 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3496 r = message_peek_body(m, &rindex, 4, 4, &q);
3500 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3501 r = message_peek_body(m, &rindex, 1, l+1, &q);
3505 if (type == SD_BUS_TYPE_OBJECT_PATH)
3506 ok = validate_object_path(q, l);
3508 ok = validate_string(q, l);
3513 *(const char**) p = q;
3515 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3518 r = message_peek_body(m, &rindex, 1, 1, &q);
3523 r = message_peek_body(m, &rindex, 1, l+1, &q);
3527 if (!validate_signature(q, l))
3531 *(const char**) p = q;
3536 align = bus_type_get_alignment(type);
3539 sz = bus_type_get_size(type);
3542 r = message_peek_body(m, &rindex, align, sz, &q);
3548 case SD_BUS_TYPE_BYTE:
3550 *(uint8_t*) p = *(uint8_t*) q;
3553 case SD_BUS_TYPE_BOOLEAN:
3555 *(int*) p = !!*(uint32_t*) q;
3558 case SD_BUS_TYPE_INT16:
3559 case SD_BUS_TYPE_UINT16:
3561 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3564 case SD_BUS_TYPE_INT32:
3565 case SD_BUS_TYPE_UINT32:
3567 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3570 case SD_BUS_TYPE_INT64:
3571 case SD_BUS_TYPE_UINT64:
3572 case SD_BUS_TYPE_DOUBLE:
3574 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3577 case SD_BUS_TYPE_UNIX_FD: {
3580 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3585 *(int*) p = m->fds[j];
3590 assert_not_reached("Unknown basic type...");
3597 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3603 static int bus_message_enter_array(
3605 struct bus_container *c,
3606 const char *contents,
3607 uint32_t **array_size,
3610 size_t *n_offsets) {
3624 if (!signature_is_single(contents, true))
3627 if (!c->signature || c->signature[c->index] == 0)
3630 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3633 if (!startswith(c->signature + c->index + 1, contents))
3638 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3641 r = message_peek_body(m, &rindex, 4, 4, &q);
3645 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3648 alignment = bus_type_get_alignment(contents[0]);