chiark / gitweb /
295930303306704daff28a3c50cfb91d836d4045
[elogind.git] / src / libsystemd / sd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31 #include "memfd-util.h"
32
33 #include "sd-bus.h"
34 #include "bus-message.h"
35 #include "bus-internal.h"
36 #include "bus-type.h"
37 #include "bus-signature.h"
38 #include "bus-gvariant.h"
39 #include "bus-util.h"
40
41 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
42
43 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
44
45         if (p == NULL)
46                 return NULL;
47
48         if (old_base == new_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p < (uint8_t*) old_base)
52                 return (void*) p;
53
54         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
55                 return (void*) p;
56
57         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
58 }
59
60 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61         assert(m);
62         assert(part);
63
64         if (part->memfd >= 0) {
65                 /* If we can reuse the memfd, try that. For that it
66                  * can't be sealed yet. */
67
68                 if (!part->sealed) {
69                         assert(part->memfd_offset == 0);
70                         assert(part->data == part->mmap_begin);
71                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
72                 } else {
73                         if (part->mapped > 0)
74                                 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
75
76                         safe_close(part->memfd);
77                 }
78
79         } else if (part->munmap_this)
80                 munmap(part->mmap_begin, part->mapped);
81         else if (part->free_this)
82                 free(part->data);
83
84         if (part != &m->body)
85                 free(part);
86 }
87
88 static void message_reset_parts(sd_bus_message *m) {
89         struct bus_body_part *part;
90
91         assert(m);
92
93         part = &m->body;
94         while (m->n_body_parts > 0) {
95                 struct bus_body_part *next = part->next;
96                 message_free_part(m, part);
97                 part = next;
98                 m->n_body_parts--;
99         }
100
101         m->body_end = NULL;
102
103         m->cached_rindex_part = NULL;
104         m->cached_rindex_part_begin = 0;
105 }
106
107 static void message_reset_containers(sd_bus_message *m) {
108         unsigned i;
109
110         assert(m);
111
112         for (i = 0; i < m->n_containers; i++) {
113                 free(m->containers[i].signature);
114                 free(m->containers[i].offsets);
115         }
116
117         free(m->containers);
118         m->containers = NULL;
119
120         m->n_containers = m->containers_allocated = 0;
121         m->root_container.index = 0;
122 }
123
124 static void message_free(sd_bus_message *m) {
125         assert(m);
126
127         if (m->free_header)
128                 free(m->header);
129
130         message_reset_parts(m);
131
132         if (m->release_kdbus)
133                 bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
134
135         if (m->free_kdbus)
136                 free(m->kdbus);
137
138         sd_bus_unref(m->bus);
139
140         if (m->free_fds) {
141                 close_many(m->fds, m->n_fds);
142                 free(m->fds);
143         }
144
145         if (m->iovec != m->iovec_fixed)
146                 free(m->iovec);
147
148         if (m->destination_ptr) {
149                 free(m->destination_ptr);
150                 m->destination_ptr = NULL;
151         }
152
153         message_reset_containers(m);
154         free(m->root_container.signature);
155         free(m->root_container.offsets);
156
157         free(m->root_container.peeked_signature);
158
159         bus_creds_done(&m->creds);
160         free(m);
161 }
162
163 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
164         void *op, *np;
165         size_t old_size, new_size, start;
166
167         assert(m);
168
169         if (m->poisoned)
170                 return NULL;
171
172         old_size = sizeof(struct bus_header) + m->fields_size;
173         start = ALIGN_TO(old_size, align);
174         new_size = start + sz;
175
176         if (new_size < start ||
177             new_size > (size_t) ((uint32_t) -1))
178                 goto poison;
179
180         if (old_size == new_size)
181                 return (uint8_t*) m->header + old_size;
182
183         if (m->free_header) {
184                 np = realloc(m->header, ALIGN8(new_size));
185                 if (!np)
186                         goto poison;
187         } else {
188                 /* Initially, the header is allocated as part of of
189                  * the sd_bus_message itself, let's replace it by
190                  * dynamic data */
191
192                 np = malloc(ALIGN8(new_size));
193                 if (!np)
194                         goto poison;
195
196                 memcpy(np, m->header, sizeof(struct bus_header));
197         }
198
199         /* Zero out padding */
200         if (start > old_size)
201                 memzero((uint8_t*) np + old_size, start - old_size);
202
203         op = m->header;
204         m->header = np;
205         m->fields_size = new_size - sizeof(struct bus_header);
206
207         /* Adjust quick access pointers */
208         m->path = adjust_pointer(m->path, op, old_size, m->header);
209         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
210         m->member = adjust_pointer(m->member, op, old_size, m->header);
211         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
212         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
213         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
214
215         m->free_header = true;
216
217         if (add_offset) {
218                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
219                         goto poison;
220
221                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
222         }
223
224         return (uint8_t*) np + start;
225
226 poison:
227         m->poisoned = true;
228         return NULL;
229 }
230
231 static int message_append_field_string(
232                 sd_bus_message *m,
233                 uint64_t h,
234                 char type,
235                 const char *s,
236                 const char **ret) {
237
238         size_t l;
239         uint8_t *p;
240
241         assert(m);
242
243         /* dbus1 only allows 8bit header field ids */
244         if (h > 0xFF)
245                 return -EINVAL;
246
247         /* dbus1 doesn't allow strings over 32bit, let's enforce this
248          * globally, to not risk convertability */
249         l = strlen(s);
250         if (l > (size_t) (uint32_t) -1)
251                 return -EINVAL;
252
253         /* Signature "(yv)" where the variant contains "s" */
254
255         if (BUS_MESSAGE_IS_GVARIANT(m)) {
256
257                 /* (field id 64bit, ((string + NUL) + NUL + signature string 's') */
258                 p = message_extend_fields(m, 8, 8 + l + 1 + 1 + 1, true);
259                 if (!p)
260                         return -ENOMEM;
261
262                 *((uint64_t*) p) = h;
263                 memcpy(p+8, s, l);
264                 p[8+l] = 0;
265                 p[8+l+1] = 0;
266                 p[8+l+2] = type;
267
268                 if (ret)
269                         *ret = (char*) p + 8;
270
271         } else {
272                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
273                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
274                 if (!p)
275                         return -ENOMEM;
276
277                 p[0] = (uint8_t) h;
278                 p[1] = 1;
279                 p[2] = type;
280                 p[3] = 0;
281
282                 ((uint32_t*) p)[1] = l;
283                 memcpy(p + 8, s, l + 1);
284
285                 if (ret)
286                         *ret = (char*) p + 8;
287         }
288
289         return 0;
290 }
291
292 static int message_append_field_signature(
293                 sd_bus_message *m,
294                 uint64_t h,
295                 const char *s,
296                 const char **ret) {
297
298         size_t l;
299         uint8_t *p;
300
301         assert(m);
302
303         /* dbus1 only allows 8bit header field ids */
304         if (h > 0xFF)
305                 return -EINVAL;
306
307         /* dbus1 doesn't allow signatures over 8bit, let's enforce
308          * this globally, to not risk convertability */
309         l = strlen(s);
310         if (l > 255)
311                 return -EINVAL;
312
313         /* Signature "(yv)" where the variant contains "g" */
314
315         if (BUS_MESSAGE_IS_GVARIANT(m))
316                 /* For gvariant the serialization is the same as for normal strings */
317                 return message_append_field_string(m, h, 'g', s, ret);
318         else {
319                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
320                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
321                 if (!p)
322                         return -ENOMEM;
323
324                 p[0] = (uint8_t) h;
325                 p[1] = 1;
326                 p[2] = SD_BUS_TYPE_SIGNATURE;
327                 p[3] = 0;
328                 p[4] = l;
329                 memcpy(p + 5, s, l + 1);
330
331                 if (ret)
332                         *ret = (const char*) p + 5;
333         }
334
335         return 0;
336 }
337
338 static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x) {
339         uint8_t *p;
340
341         assert(m);
342
343         /* dbus1 only allows 8bit header field ids */
344         if (h > 0xFF)
345                 return -EINVAL;
346
347         if (BUS_MESSAGE_IS_GVARIANT(m)) {
348                 /* (field id 64bit + ((value + NUL + signature string 'u') */
349
350                 p = message_extend_fields(m, 8, 8 + 4 + 1 + 1, true);
351                 if (!p)
352                         return -ENOMEM;
353
354                 *((uint64_t*) p) = h;
355                 *((uint32_t*) (p + 8)) = x;
356                 p[12] = 0;
357                 p[13] = 'u';
358         } else {
359                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
360                 p = message_extend_fields(m, 8, 4 + 4, false);
361                 if (!p)
362                         return -ENOMEM;
363
364                 p[0] = (uint8_t) h;
365                 p[1] = 1;
366                 p[2] = 'u';
367                 p[3] = 0;
368
369                 ((uint32_t*) p)[1] = x;
370         }
371
372         return 0;
373 }
374
375 static int message_append_field_uint64(sd_bus_message *m, uint64_t h, uint64_t x) {
376         uint8_t *p;
377
378         assert(m);
379
380         /* dbus1 only allows 8bit header field ids */
381         if (h > 0xFF)
382                 return -EINVAL;
383
384         if (BUS_MESSAGE_IS_GVARIANT(m)) {
385                 /* (field id 64bit + ((value + NUL + signature string 't') */
386
387                 p = message_extend_fields(m, 8, 8 + 8 + 1 + 1, true);
388                 if (!p)
389                         return -ENOMEM;
390
391                 *((uint64_t*) p) = h;
392                 *((uint64_t*) (p + 8)) = x;
393                 p[16] = 0;
394                 p[17] = 't';
395         } else {
396                 /* (field id byte + (signature length + signature 't' + NUL) + 4 byte padding + value) */
397                 p = message_extend_fields(m, 8, 4 + 4 + 8, false);
398                 if (!p)
399                         return -ENOMEM;
400
401                 p[0] = (uint8_t) h;
402                 p[1] = 1;
403                 p[2] = 't';
404                 p[3] = 0;
405                 p[4] = 0;
406                 p[5] = 0;
407                 p[6] = 0;
408                 p[7] = 0;
409
410                 ((uint64_t*) p)[1] = x;
411         }
412
413         return 0;
414 }
415
416 static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) {
417         assert(m);
418
419         if (BUS_MESSAGE_IS_GVARIANT(m))
420                 return message_append_field_uint64(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, cookie);
421         else {
422                 /* 64bit cookies are not supported on dbus1 */
423                 if (cookie > 0xffffffffUL)
424                         return -ENOTSUP;
425
426                 return message_append_field_uint32(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) cookie);
427         }
428 }
429
430 int bus_message_from_header(
431                 sd_bus *bus,
432                 void *header,
433                 size_t header_accessible,
434                 void *footer,
435                 size_t footer_accessible,
436                 size_t message_size,
437                 int *fds,
438                 unsigned n_fds,
439                 const struct ucred *ucred,
440                 const char *label,
441                 size_t extra,
442                 sd_bus_message **ret) {
443
444         sd_bus_message *m;
445         struct bus_header *h;
446         size_t a, label_sz;
447
448         assert(bus);
449         assert(header || header_accessible <= 0);
450         assert(footer || footer_accessible <= 0);
451         assert(fds || n_fds <= 0);
452         assert(ret);
453
454         if (header_accessible < sizeof(struct bus_header))
455                 return -EBADMSG;
456
457         if (header_accessible > message_size)
458                 return -EBADMSG;
459         if (footer_accessible > message_size)
460                 return -EBADMSG;
461
462         h = header;
463         if (h->version != 1 &&
464             h->version != 2)
465                 return -EBADMSG;
466
467         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
468                 return -EBADMSG;
469
470         if (h->endian != BUS_LITTLE_ENDIAN &&
471             h->endian != BUS_BIG_ENDIAN)
472                 return -EBADMSG;
473
474         /* Note that we are happy with unknown flags in the flags header! */
475
476         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
477
478         if (label) {
479                 label_sz = strlen(label);
480                 a += label_sz + 1;
481         }
482
483         m = malloc0(a);
484         if (!m)
485                 return -ENOMEM;
486
487         m->n_ref = 1;
488         m->sealed = true;
489         m->header = header;
490         m->header_accessible = header_accessible;
491         m->footer = footer;
492         m->footer_accessible = footer_accessible;
493
494         if (BUS_MESSAGE_IS_GVARIANT(m)) {
495                 size_t ws;
496
497                 if (h->dbus2.cookie == 0)
498                         return -EBADMSG;
499
500                 /* dbus2 derives the sizes from the message size and
501                 the offset table at the end, since it is formatted as
502                 gvariant "yyyyuta{tv}v". Since the message itself is a
503                 structure with precisely to variable sized entries,
504                 there's only one offset in the table, which marks the
505                 end of the fields array. */
506
507                 ws = bus_gvariant_determine_word_size(message_size, 0);
508                 if (footer_accessible < ws)
509                         return -EBADMSG;
510
511                 m->fields_size = bus_gvariant_read_word_le((uint8_t*) footer + footer_accessible - ws, ws);
512                 if (ALIGN8(m->fields_size) > message_size - ws)
513                         return -EBADMSG;
514                 if (m->fields_size < sizeof(struct bus_header))
515                         return -EBADMSG;
516
517                 m->fields_size -= sizeof(struct bus_header);
518                 m->body_size = message_size - (sizeof(struct bus_header) + ALIGN8(m->fields_size));
519         } else {
520                 if (h->dbus1.serial == 0)
521                         return -EBADMSG;
522
523                 /* dbus1 has the sizes in the header */
524                 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
525                 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
526
527                 if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
528                         return -EBADMSG;
529         }
530
531         m->fds = fds;
532         m->n_fds = n_fds;
533
534         if (ucred) {
535                 m->creds.pid = ucred->pid;
536                 m->creds.euid = ucred->uid;
537                 m->creds.egid = ucred->gid;
538
539                 /* Due to namespace translations some data might be
540                  * missing from this ucred record. */
541                 if (m->creds.pid > 0)
542                         m->creds.mask |= SD_BUS_CREDS_PID;
543
544                 if (m->creds.euid != UID_INVALID)
545                         m->creds.mask |= SD_BUS_CREDS_EUID;
546
547                 if (m->creds.egid != GID_INVALID)
548                         m->creds.mask |= SD_BUS_CREDS_EGID;
549         }
550
551         if (label) {
552                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
553                 memcpy(m->creds.label, label, label_sz + 1);
554
555                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
556         }
557
558         m->bus = sd_bus_ref(bus);
559         *ret = m;
560
561         return 0;
562 }
563
564 int bus_message_from_malloc(
565                 sd_bus *bus,
566                 void *buffer,
567                 size_t length,
568                 int *fds,
569                 unsigned n_fds,
570                 const struct ucred *ucred,
571                 const char *label,
572                 sd_bus_message **ret) {
573
574         sd_bus_message *m;
575         size_t sz;
576         int r;
577
578         r = bus_message_from_header(
579                         bus,
580                         buffer, length, /* in this case the initial bytes and the final bytes are the same */
581                         buffer, length,
582                         length,
583                         fds, n_fds,
584                         ucred, label,
585                         0, &m);
586         if (r < 0)
587                 return r;
588
589         sz = length - sizeof(struct bus_header) - ALIGN8(m->fields_size);
590         if (sz > 0) {
591                 m->n_body_parts = 1;
592                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(m->fields_size);
593                 m->body.size = sz;
594                 m->body.sealed = true;
595                 m->body.memfd = -1;
596         }
597
598         m->n_iovec = 1;
599         m->iovec = m->iovec_fixed;
600         m->iovec[0].iov_base = buffer;
601         m->iovec[0].iov_len = length;
602
603         r = bus_message_parse_fields(m);
604         if (r < 0)
605                 goto fail;
606
607         /* We take possession of the memory and fds now */
608         m->free_header = true;
609         m->free_fds = true;
610
611         *ret = m;
612         return 0;
613
614 fail:
615         message_free(m);
616         return r;
617 }
618
619 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
620         sd_bus_message *m;
621
622         assert(bus);
623
624         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
625         if (!m)
626                 return NULL;
627
628         m->n_ref = 1;
629         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
630         m->header->endian = BUS_NATIVE_ENDIAN;
631         m->header->type = type;
632         m->header->version = bus ? bus->message_version : 1;
633         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
634         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
635         m->bus = sd_bus_ref(bus);
636
637         return m;
638 }
639
640 _public_ int sd_bus_message_new_signal(
641                 sd_bus *bus,
642                 sd_bus_message **m,
643                 const char *path,
644                 const char *interface,
645                 const char *member) {
646
647         sd_bus_message *t;
648         int r;
649
650         assert_return(bus, -ENOTCONN);
651         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
652         assert_return(object_path_is_valid(path), -EINVAL);
653         assert_return(interface_name_is_valid(interface), -EINVAL);
654         assert_return(member_name_is_valid(member), -EINVAL);
655         assert_return(m, -EINVAL);
656
657         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
658         if (!t)
659                 return -ENOMEM;
660
661         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
662
663         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
664         if (r < 0)
665                 goto fail;
666         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
667         if (r < 0)
668                 goto fail;
669         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
670         if (r < 0)
671                 goto fail;
672
673         *m = t;
674         return 0;
675
676 fail:
677         sd_bus_message_unref(t);
678         return r;
679 }
680
681 _public_ int sd_bus_message_new_method_call(
682                 sd_bus *bus,
683                 sd_bus_message **m,
684                 const char *destination,
685                 const char *path,
686                 const char *interface,
687                 const char *member) {
688
689         sd_bus_message *t;
690         int r;
691
692         assert_return(bus, -ENOTCONN);
693         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
694         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
695         assert_return(object_path_is_valid(path), -EINVAL);
696         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
697         assert_return(member_name_is_valid(member), -EINVAL);
698         assert_return(m, -EINVAL);
699
700         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
701         if (!t)
702                 return -ENOMEM;
703
704         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
705         if (r < 0)
706                 goto fail;
707         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
708         if (r < 0)
709                 goto fail;
710
711         if (interface) {
712                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
713                 if (r < 0)
714                         goto fail;
715         }
716
717         if (destination) {
718                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
719                 if (r < 0)
720                         goto fail;
721         }
722
723         *m = t;
724         return 0;
725
726 fail:
727         message_free(t);
728         return r;
729 }
730
731 static int message_new_reply(
732                 sd_bus_message *call,
733                 uint8_t type,
734                 sd_bus_message **m) {
735
736         sd_bus_message *t;
737         int r;
738
739         assert_return(call, -EINVAL);
740         assert_return(call->sealed, -EPERM);
741         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
742         assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
743         assert_return(m, -EINVAL);
744
745         t = message_new(call->bus, type);
746         if (!t)
747                 return -ENOMEM;
748
749         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
750         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
751         if (t->reply_cookie == 0)
752                 return -ENOTSUP;
753
754         r = message_append_reply_cookie(t, t->reply_cookie);
755         if (r < 0)
756                 goto fail;
757
758         if (call->sender) {
759                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
760                 if (r < 0)
761                         goto fail;
762         }
763
764         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
765         t->enforced_reply_signature = call->enforced_reply_signature;
766
767         *m = t;
768         return 0;
769
770 fail:
771         message_free(t);
772         return r;
773 }
774
775 _public_ int sd_bus_message_new_method_return(
776                 sd_bus_message *call,
777                 sd_bus_message **m) {
778
779         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
780 }
781
782 _public_ int sd_bus_message_new_method_error(
783                 sd_bus_message *call,
784                 sd_bus_message **m,
785                 const sd_bus_error *e) {
786
787         sd_bus_message *t;
788         int r;
789
790         assert_return(sd_bus_error_is_set(e), -EINVAL);
791         assert_return(m, -EINVAL);
792
793         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
794         if (r < 0)
795                 return r;
796
797         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
798         if (r < 0)
799                 goto fail;
800
801         if (e->message) {
802                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
803                 if (r < 0)
804                         goto fail;
805         }
806
807         t->error._need_free = -1;
808
809         *m = t;
810         return 0;
811
812 fail:
813         message_free(t);
814         return r;
815 }
816
817 _public_ int sd_bus_message_new_method_errorf(
818                 sd_bus_message *call,
819                 sd_bus_message **m,
820                 const char *name,
821                 const char *format,
822                 ...) {
823
824         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
825         va_list ap;
826
827         assert_return(name, -EINVAL);
828         assert_return(m, -EINVAL);
829
830         va_start(ap, format);
831         bus_error_setfv(&error, name, format, ap);
832         va_end(ap);
833
834         return sd_bus_message_new_method_error(call, m, &error);
835 }
836
837 _public_ int sd_bus_message_new_method_errno(
838                 sd_bus_message *call,
839                 sd_bus_message **m,
840                 int error,
841                 const sd_bus_error *p) {
842
843         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
844
845         if (sd_bus_error_is_set(p))
846                 return sd_bus_message_new_method_error(call, m, p);
847
848         sd_bus_error_set_errno(&berror, error);
849
850         return sd_bus_message_new_method_error(call, m, &berror);
851 }
852
853 _public_ int sd_bus_message_new_method_errnof(
854                 sd_bus_message *call,
855                 sd_bus_message **m,
856                 int error,
857                 const char *format,
858                 ...) {
859
860         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
861         va_list ap;
862
863         va_start(ap, format);
864         sd_bus_error_set_errnofv(&berror, error, format, ap);
865         va_end(ap);
866
867         return sd_bus_message_new_method_error(call, m, &berror);
868 }
869
870 void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
871         assert(bus);
872         assert(m);
873
874         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
875         m->creds.well_known_names_local = true;
876         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
877 }
878
879 void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) {
880         assert(bus);
881         assert(m);
882
883         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
884         m->creds.well_known_names_driver = true;
885         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
886 }
887
888 int bus_message_new_synthetic_error(
889                 sd_bus *bus,
890                 uint64_t cookie,
891                 const sd_bus_error *e,
892                 sd_bus_message **m) {
893
894         sd_bus_message *t;
895         int r;
896
897         assert(bus);
898         assert(sd_bus_error_is_set(e));
899         assert(m);
900
901         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
902         if (!t)
903                 return -ENOMEM;
904
905         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
906         t->reply_cookie = cookie;
907
908         r = message_append_reply_cookie(t, t->reply_cookie);
909         if (r < 0)
910                 goto fail;
911
912         if (bus && bus->unique_name) {
913                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
914                 if (r < 0)
915                         goto fail;
916         }
917
918         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
919         if (r < 0)
920                 goto fail;
921
922         if (e->message) {
923                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
924                 if (r < 0)
925                         goto fail;
926         }
927
928         t->error._need_free = -1;
929
930         bus_message_set_sender_driver(bus, t);
931
932         *m = t;
933         return 0;
934
935 fail:
936         message_free(t);
937         return r;
938 }
939
940 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
941         assert_return(m, NULL);
942
943         assert(m->n_ref > 0);
944         m->n_ref++;
945
946         return m;
947 }
948
949 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
950
951         if (!m)
952                 return NULL;
953
954         assert(m->n_ref > 0);
955         m->n_ref--;
956
957         if (m->n_ref > 0)
958                 return NULL;
959
960         message_free(m);
961         return NULL;
962 }
963
964 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
965         assert_return(m, -EINVAL);
966         assert_return(type, -EINVAL);
967
968         *type = m->header->type;
969         return 0;
970 }
971
972 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
973         uint64_t c;
974
975         assert_return(m, -EINVAL);
976         assert_return(cookie, -EINVAL);
977
978         c = BUS_MESSAGE_COOKIE(m);
979         if (c == 0)
980                 return -ENODATA;
981
982         *cookie = BUS_MESSAGE_COOKIE(m);
983         return 0;
984 }
985
986 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
987         assert_return(m, -EINVAL);
988         assert_return(cookie, -EINVAL);
989
990         if (m->reply_cookie == 0)
991                 return -ENODATA;
992
993         *cookie = m->reply_cookie;
994         return 0;
995 }
996
997 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
998         assert_return(m, -EINVAL);
999
1000         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
1001                 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
1002 }
1003
1004 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
1005         assert_return(m, -EINVAL);
1006
1007         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
1008 }
1009
1010 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
1011         assert_return(m, -EINVAL);
1012
1013         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
1014                 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
1015 }
1016
1017 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
1018         assert_return(m, NULL);
1019
1020         return m->path;
1021 }
1022
1023 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
1024         assert_return(m, NULL);
1025
1026         return m->interface;
1027 }
1028
1029 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
1030         assert_return(m, NULL);
1031
1032         return m->member;
1033 }
1034
1035 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
1036         assert_return(m, NULL);
1037
1038         return m->destination;
1039 }
1040
1041 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
1042         assert_return(m, NULL);
1043
1044         return m->sender;
1045 }
1046
1047 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
1048         assert_return(m, NULL);
1049         assert_return(sd_bus_error_is_set(&m->error), NULL);
1050
1051         return &m->error;
1052 }
1053
1054 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
1055         assert_return(m, -EINVAL);
1056         assert_return(usec, -EINVAL);
1057
1058         if (m->monotonic <= 0)
1059                 return -ENODATA;
1060
1061         *usec = m->monotonic;
1062         return 0;
1063 }
1064
1065 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
1066         assert_return(m, -EINVAL);
1067         assert_return(usec, -EINVAL);
1068
1069         if (m->realtime <= 0)
1070                 return -ENODATA;
1071
1072         *usec = m->realtime;
1073         return 0;
1074 }
1075
1076 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
1077         assert_return(m, -EINVAL);
1078         assert_return(seqnum, -EINVAL);
1079
1080         if (m->seqnum <= 0)
1081                 return -ENODATA;
1082
1083         *seqnum = m->seqnum;
1084         return 0;
1085 }
1086
1087 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
1088         assert_return(m, NULL);
1089
1090         if (m->creds.mask == 0)
1091                 return NULL;
1092
1093         return &m->creds;
1094 }
1095
1096 _public_ int sd_bus_message_is_signal(
1097                 sd_bus_message *m,
1098                 const char *interface,
1099                 const char *member) {
1100
1101         assert_return(m, -EINVAL);
1102
1103         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1104                 return 0;
1105
1106         if (interface && (!m->interface || !streq(m->interface, interface)))
1107                 return 0;
1108
1109         if (member &&  (!m->member || !streq(m->member, member)))
1110                 return 0;
1111
1112         return 1;
1113 }
1114
1115 _public_ int sd_bus_message_is_method_call(
1116                 sd_bus_message *m,
1117                 const char *interface,
1118                 const char *member) {
1119
1120         assert_return(m, -EINVAL);
1121
1122         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1123                 return 0;
1124
1125         if (interface && (!m->interface || !streq(m->interface, interface)))
1126                 return 0;
1127
1128         if (member &&  (!m->member || !streq(m->member, member)))
1129                 return 0;
1130
1131         return 1;
1132 }
1133
1134 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1135         assert_return(m, -EINVAL);
1136
1137         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1138                 return 0;
1139
1140         if (name && (!m->error.name || !streq(m->error.name, name)))
1141                 return 0;
1142
1143         return 1;
1144 }
1145
1146 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1147         assert_return(m, -EINVAL);
1148         assert_return(!m->sealed, -EPERM);
1149         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1150
1151         if (b)
1152                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
1153         else
1154                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1155
1156         return 0;
1157 }
1158
1159 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1160         assert_return(m, -EINVAL);
1161         assert_return(!m->sealed, -EPERM);
1162
1163         if (b)
1164                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
1165         else
1166                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
1167
1168         return 0;
1169 }
1170
1171 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1172         assert_return(m, -EINVAL);
1173         assert_return(!m->sealed, -EPERM);
1174
1175         if (b)
1176                 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1177         else
1178                 m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1179
1180         return 0;
1181 }
1182
1183 static struct bus_container *message_get_container(sd_bus_message *m) {
1184         assert(m);
1185
1186         if (m->n_containers == 0)
1187                 return &m->root_container;
1188
1189         assert(m->containers);
1190         return m->containers + m->n_containers - 1;
1191 }
1192
1193 struct bus_body_part *message_append_part(sd_bus_message *m) {
1194         struct bus_body_part *part;
1195
1196         assert(m);
1197
1198         if (m->poisoned)
1199                 return NULL;
1200
1201         if (m->n_body_parts <= 0) {
1202                 part = &m->body;
1203                 zero(*part);
1204         } else {
1205                 assert(m->body_end);
1206
1207                 part = new0(struct bus_body_part, 1);
1208                 if (!part) {
1209                         m->poisoned = true;
1210                         return NULL;
1211                 }
1212
1213                 m->body_end->next = part;
1214         }
1215
1216         part->memfd = -1;
1217         m->body_end = part;
1218         m->n_body_parts ++;
1219
1220         return part;
1221 }
1222
1223 static void part_zero(struct bus_body_part *part, size_t sz) {
1224         assert(part);
1225         assert(sz > 0);
1226         assert(sz < 8);
1227
1228         /* All other fields can be left in their defaults */
1229         assert(!part->data);
1230         assert(part->memfd < 0);
1231
1232         part->size = sz;
1233         part->is_zero = true;
1234         part->sealed = true;
1235 }
1236
1237 static int part_make_space(
1238                 struct sd_bus_message *m,
1239                 struct bus_body_part *part,
1240                 size_t sz,
1241                 void **q) {
1242
1243         void *n;
1244         int r;
1245
1246         assert(m);
1247         assert(part);
1248         assert(!part->sealed);
1249
1250         if (m->poisoned)
1251                 return -ENOMEM;
1252
1253         if (!part->data && part->memfd < 0) {
1254                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1255                 part->mmap_begin = part->data;
1256         }
1257
1258         if (part->memfd >= 0) {
1259
1260                 if (part->allocated == 0 || sz > part->allocated) {
1261                         uint64_t new_allocated;
1262
1263                         new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1264                         r = memfd_set_size(part->memfd, new_allocated);
1265                         if (r < 0) {
1266                                 m->poisoned = true;
1267                                 return r;
1268                         }
1269
1270                         part->allocated = new_allocated;
1271                 }
1272
1273                 if (!part->data || sz > part->mapped) {
1274                         size_t psz;
1275
1276                         psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1277                         if (part->mapped <= 0)
1278                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1279                         else
1280                                 n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
1281
1282                         if (n == MAP_FAILED) {
1283                                 m->poisoned = true;
1284                                 return -errno;
1285                         }
1286
1287                         part->mmap_begin = part->data = n;
1288                         part->mapped = psz;
1289                         part->memfd_offset = 0;
1290                 }
1291
1292                 part->munmap_this = true;
1293         } else {
1294                 if (part->allocated == 0 || sz > part->allocated) {
1295                         size_t new_allocated;
1296
1297                         new_allocated = sz > 0 ? 2 * sz : 64;
1298                         n = realloc(part->data, new_allocated);
1299                         if (!n) {
1300                                 m->poisoned = true;
1301                                 return -ENOMEM;
1302                         }
1303
1304                         part->data = n;
1305                         part->allocated = new_allocated;
1306                         part->free_this = true;
1307                 }
1308         }
1309
1310         if (q)
1311                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1312
1313         part->size = sz;
1314         return 0;
1315 }
1316
1317 static int message_add_offset(sd_bus_message *m, size_t offset) {
1318         struct bus_container *c;
1319
1320         assert(m);
1321         assert(BUS_MESSAGE_IS_GVARIANT(m));
1322
1323         /* Add offset to current container, unless this is the first
1324          * item in it, which will have the 0 offset, which we can
1325          * ignore. */
1326         c = message_get_container(m);
1327
1328         if (!c->need_offsets)
1329                 return 0;
1330
1331         if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1332                 return -ENOMEM;
1333
1334         c->offsets[c->n_offsets++] = offset;
1335         return 0;
1336 }
1337
1338 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1339         struct bus_container *c;
1340
1341         assert(m);
1342
1343         if (expand <= 0)
1344                 return;
1345
1346         /* Update counters */
1347         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1348
1349                 if (c->array_size)
1350                         *c->array_size += expand;
1351         }
1352 }
1353
1354 static void *message_extend_body(
1355                 sd_bus_message *m,
1356                 size_t align,
1357                 size_t sz,
1358                 bool add_offset,
1359                 bool force_inline) {
1360
1361         size_t start_body, end_body, padding, added;
1362         void *p;
1363         int r;
1364
1365         assert(m);
1366         assert(align > 0);
1367         assert(!m->sealed);
1368
1369         if (m->poisoned)
1370                 return NULL;
1371
1372         start_body = ALIGN_TO((size_t) m->body_size, align);
1373         end_body = start_body + sz;
1374
1375         padding = start_body - m->body_size;
1376         added = padding + sz;
1377
1378         /* Check for 32bit overflows */
1379         if (end_body > (size_t) ((uint32_t) -1) ||
1380             end_body < start_body) {
1381                 m->poisoned = true;
1382                 return NULL;
1383         }
1384
1385         if (added > 0) {
1386                 struct bus_body_part *part = NULL;
1387                 bool add_new_part;
1388
1389                 add_new_part =
1390                         m->n_body_parts <= 0 ||
1391                         m->body_end->sealed ||
1392                         (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
1393                         (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 */
1394
1395                 if (add_new_part) {
1396                         if (padding > 0) {
1397                                 part = message_append_part(m);
1398                                 if (!part)
1399                                         return NULL;
1400
1401                                 part_zero(part, padding);
1402                         }
1403
1404                         part = message_append_part(m);
1405                         if (!part)
1406                                 return NULL;
1407
1408                         r = part_make_space(m, part, sz, &p);
1409                         if (r < 0)
1410                                 return NULL;
1411                 } else {
1412                         struct bus_container *c;
1413                         void *op;
1414                         size_t os, start_part, end_part;
1415
1416                         part = m->body_end;
1417                         op = part->data;
1418                         os = part->size;
1419
1420                         start_part = ALIGN_TO(part->size, align);
1421                         end_part = start_part + sz;
1422
1423                         r = part_make_space(m, part, end_part, &p);
1424                         if (r < 0)
1425                                 return NULL;
1426
1427                         if (padding > 0) {
1428                                 memzero(p, padding);
1429                                 p = (uint8_t*) p + padding;
1430                         }
1431
1432                         /* Readjust pointers */
1433                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1434                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1435
1436                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1437                 }
1438         } else
1439                 /* Return something that is not NULL and is aligned */
1440                 p = (uint8_t *) NULL + align;
1441
1442         m->body_size = end_body;
1443         message_extend_containers(m, added);
1444
1445         if (add_offset) {
1446                 r = message_add_offset(m, end_body);
1447                 if (r < 0) {
1448                         m->poisoned = true;
1449                         return NULL;
1450                 }
1451         }
1452
1453         return p;
1454 }
1455
1456 static int message_push_fd(sd_bus_message *m, int fd) {
1457         int *f, copy;
1458
1459         assert(m);
1460
1461         if (fd < 0)
1462                 return -EINVAL;
1463
1464         if (!m->allow_fds)
1465                 return -ENOTSUP;
1466
1467         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1468         if (copy < 0)
1469                 return -errno;
1470
1471         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1472         if (!f) {
1473                 m->poisoned = true;
1474                 safe_close(copy);
1475                 return -ENOMEM;
1476         }
1477
1478         m->fds = f;
1479         m->fds[m->n_fds] = copy;
1480         m->free_fds = true;
1481
1482         return copy;
1483 }
1484
1485 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1486         _cleanup_close_ int fd = -1;
1487         struct bus_container *c;
1488         ssize_t align, sz;
1489         void *a;
1490
1491         assert_return(m, -EINVAL);
1492         assert_return(!m->sealed, -EPERM);
1493         assert_return(bus_type_is_basic(type), -EINVAL);
1494         assert_return(!m->poisoned, -ESTALE);
1495
1496         c = message_get_container(m);
1497
1498         if (c->signature && c->signature[c->index]) {
1499                 /* Container signature is already set */
1500
1501                 if (c->signature[c->index] != type)
1502                         return -ENXIO;
1503         } else {
1504                 char *e;
1505
1506                 /* Maybe we can append to the signature? But only if this is the top-level container */
1507                 if (c->enclosing != 0)
1508                         return -ENXIO;
1509
1510                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1511                 if (!e) {
1512                         m->poisoned = true;
1513                         return -ENOMEM;
1514                 }
1515         }
1516
1517         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1518                 uint8_t u8;
1519                 uint32_t u32;
1520
1521                 switch (type) {
1522
1523                 case SD_BUS_TYPE_SIGNATURE:
1524                 case SD_BUS_TYPE_STRING:
1525                         p = strempty(p);
1526
1527                         /* Fall through... */
1528                 case SD_BUS_TYPE_OBJECT_PATH:
1529                         if (!p)
1530                                 return -EINVAL;
1531
1532                         align = 1;
1533                         sz = strlen(p) + 1;
1534                         break;
1535
1536                 case SD_BUS_TYPE_BOOLEAN:
1537
1538                         u8 = p && *(int*) p;
1539                         p = &u8;
1540
1541                         align = sz = 1;
1542                         break;
1543
1544                 case SD_BUS_TYPE_UNIX_FD:
1545
1546                         if (!p)
1547                                 return -EINVAL;
1548
1549                         fd = message_push_fd(m, *(int*) p);
1550                         if (fd < 0)
1551                                 return fd;
1552
1553                         u32 = m->n_fds;
1554                         p = &u32;
1555
1556                         align = sz = 4;
1557                         break;
1558
1559                 default:
1560                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1561                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1562                         break;
1563                 }
1564
1565                 assert(align > 0);
1566                 assert(sz > 0);
1567
1568                 a = message_extend_body(m, align, sz, true, false);
1569                 if (!a)
1570                         return -ENOMEM;
1571
1572                 memcpy(a, p, sz);
1573
1574                 if (stored)
1575                         *stored = (const uint8_t*) a;
1576
1577         } else {
1578                 uint32_t u32;
1579
1580                 switch (type) {
1581
1582                 case SD_BUS_TYPE_STRING:
1583                         /* To make things easy we'll serialize a NULL string
1584                          * into the empty string */
1585                         p = strempty(p);
1586
1587                         /* Fall through... */
1588                 case SD_BUS_TYPE_OBJECT_PATH:
1589
1590                         if (!p)
1591                                 return -EINVAL;
1592
1593                         align = 4;
1594                         sz = 4 + strlen(p) + 1;
1595                         break;
1596
1597                 case SD_BUS_TYPE_SIGNATURE:
1598
1599                         p = strempty(p);
1600
1601                         align = 1;
1602                         sz = 1 + strlen(p) + 1;
1603                         break;
1604
1605                 case SD_BUS_TYPE_BOOLEAN:
1606
1607                         u32 = p && *(int*) p;
1608                         p = &u32;
1609
1610                         align = sz = 4;
1611                         break;
1612
1613                 case SD_BUS_TYPE_UNIX_FD:
1614
1615                         if (!p)
1616                                 return -EINVAL;
1617
1618                         fd = message_push_fd(m, *(int*) p);
1619                         if (fd < 0)
1620                                 return fd;
1621
1622                         u32 = m->n_fds;
1623                         p = &u32;
1624
1625                         align = sz = 4;
1626                         break;
1627
1628                 default:
1629                         align = bus_type_get_alignment(type);
1630                         sz = bus_type_get_size(type);
1631                         break;
1632                 }
1633
1634                 assert(align > 0);
1635                 assert(sz > 0);
1636
1637                 a = message_extend_body(m, align, sz, false, false);
1638                 if (!a)
1639                         return -ENOMEM;
1640
1641                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1642                         *(uint32_t*) a = sz - 5;
1643                         memcpy((uint8_t*) a + 4, p, sz - 4);
1644
1645                         if (stored)
1646                                 *stored = (const uint8_t*) a + 4;
1647
1648                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1649                         *(uint8_t*) a = sz - 2;
1650                         memcpy((uint8_t*) a + 1, p, sz - 1);
1651
1652                         if (stored)
1653                                 *stored = (const uint8_t*) a + 1;
1654                 } else {
1655                         memcpy(a, p, sz);
1656
1657                         if (stored)
1658                                 *stored = a;
1659                 }
1660         }
1661
1662         if (type == SD_BUS_TYPE_UNIX_FD)
1663                 m->n_fds ++;
1664
1665         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1666                 c->index++;
1667
1668         fd = -1;
1669         return 0;
1670 }
1671
1672 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1673         return message_append_basic(m, type, p, NULL);
1674 }
1675
1676 _public_ int sd_bus_message_append_string_space(
1677                 sd_bus_message *m,
1678                 size_t size,
1679                 char **s) {
1680
1681         struct bus_container *c;
1682         void *a;
1683
1684         assert_return(m, -EINVAL);
1685         assert_return(s, -EINVAL);
1686         assert_return(!m->sealed, -EPERM);
1687         assert_return(!m->poisoned, -ESTALE);
1688
1689         c = message_get_container(m);
1690
1691         if (c->signature && c->signature[c->index]) {
1692                 /* Container signature is already set */
1693
1694                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1695                         return -ENXIO;
1696         } else {
1697                 char *e;
1698
1699                 /* Maybe we can append to the signature? But only if this is the top-level container */
1700                 if (c->enclosing != 0)
1701                         return -ENXIO;
1702
1703                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1704                 if (!e) {
1705                         m->poisoned = true;
1706                         return -ENOMEM;
1707                 }
1708         }
1709
1710         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1711                 a = message_extend_body(m, 1, size + 1, true, false);
1712                 if (!a)
1713                         return -ENOMEM;
1714
1715                 *s = a;
1716         } else {
1717                 a = message_extend_body(m, 4, 4 + size + 1, false, false);
1718                 if (!a)
1719                         return -ENOMEM;
1720
1721                 *(uint32_t*) a = size;
1722                 *s = (char*) a + 4;
1723         }
1724
1725         (*s)[size] = 0;
1726
1727         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1728                 c->index++;
1729
1730         return 0;
1731 }
1732
1733 _public_ int sd_bus_message_append_string_iovec(
1734                 sd_bus_message *m,
1735                 const struct iovec *iov,
1736                 unsigned n) {
1737
1738         size_t size;
1739         unsigned i;
1740         char *p;
1741         int r;
1742
1743         assert_return(m, -EINVAL);
1744         assert_return(!m->sealed, -EPERM);
1745         assert_return(iov || n == 0, -EINVAL);
1746         assert_return(!m->poisoned, -ESTALE);
1747
1748         size = IOVEC_TOTAL_SIZE(iov, n);
1749
1750         r = sd_bus_message_append_string_space(m, size, &p);
1751         if (r < 0)
1752                 return r;
1753
1754         for (i = 0; i < n; i++) {
1755
1756                 if (iov[i].iov_base)
1757                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1758                 else
1759                         memset(p, ' ', iov[i].iov_len);
1760
1761                 p += iov[i].iov_len;
1762         }
1763
1764         return 0;
1765 }
1766
1767 static int bus_message_open_array(
1768                 sd_bus_message *m,
1769                 struct bus_container *c,
1770                 const char *contents,
1771                 uint32_t **array_size,
1772                 size_t *begin,
1773                 bool *need_offsets) {
1774
1775         unsigned nindex;
1776         int alignment, r;
1777
1778         assert(m);
1779         assert(c);
1780         assert(contents);
1781         assert(array_size);
1782         assert(begin);
1783         assert(need_offsets);
1784
1785         if (!signature_is_single(contents, true))
1786                 return -EINVAL;
1787
1788         if (c->signature && c->signature[c->index]) {
1789
1790                 /* Verify the existing signature */
1791
1792                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1793                         return -ENXIO;
1794
1795                 if (!startswith(c->signature + c->index + 1, contents))
1796                         return -ENXIO;
1797
1798                 nindex = c->index + 1 + strlen(contents);
1799         } else {
1800                 char *e;
1801
1802                 if (c->enclosing != 0)
1803                         return -ENXIO;
1804
1805                 /* Extend the existing signature */
1806
1807                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1808                 if (!e) {
1809                         m->poisoned = true;
1810                         return -ENOMEM;
1811                 }
1812
1813                 nindex = e - c->signature;
1814         }
1815
1816         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1817                 alignment = bus_gvariant_get_alignment(contents);
1818                 if (alignment < 0)
1819                         return alignment;
1820
1821                 /* Add alignment padding and add to offset list */
1822                 if (!message_extend_body(m, alignment, 0, false, false))
1823                         return -ENOMEM;
1824
1825                 r = bus_gvariant_is_fixed_size(contents);
1826                 if (r < 0)
1827                         return r;
1828
1829                 *begin = m->body_size;
1830                 *need_offsets = r == 0;
1831         } else {
1832                 void *a, *op;
1833                 size_t os;
1834                 struct bus_body_part *o;
1835
1836                 alignment = bus_type_get_alignment(contents[0]);
1837                 if (alignment < 0)
1838                         return alignment;
1839
1840                 a = message_extend_body(m, 4, 4, false, false);
1841                 if (!a)
1842                         return -ENOMEM;
1843
1844                 o = m->body_end;
1845                 op = m->body_end->data;
1846                 os = m->body_end->size;
1847
1848                 /* Add alignment between size and first element */
1849                 if (!message_extend_body(m, alignment, 0, false, false))
1850                         return -ENOMEM;
1851
1852                 /* location of array size might have changed so let's readjust a */
1853                 if (o == m->body_end)
1854                         a = adjust_pointer(a, op, os, m->body_end->data);
1855
1856                 *(uint32_t*) a = 0;
1857                 *array_size = a;
1858         }
1859
1860         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1861                 c->index = nindex;
1862
1863         return 0;
1864 }
1865
1866 static int bus_message_open_variant(
1867                 sd_bus_message *m,
1868                 struct bus_container *c,
1869                 const char *contents) {
1870
1871         assert(m);
1872         assert(c);
1873         assert(contents);
1874
1875         if (!signature_is_single(contents, false))
1876                 return -EINVAL;
1877
1878         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1879                 return -EINVAL;
1880
1881         if (c->signature && c->signature[c->index]) {
1882
1883                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1884                         return -ENXIO;
1885
1886         } else {
1887                 char *e;
1888
1889                 if (c->enclosing != 0)
1890                         return -ENXIO;
1891
1892                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1893                 if (!e) {
1894                         m->poisoned = true;
1895                         return -ENOMEM;
1896                 }
1897         }
1898
1899         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1900                 /* Variants are always aligned to 8 */
1901
1902                 if (!message_extend_body(m, 8, 0, false, false))
1903                         return -ENOMEM;
1904
1905         } else {
1906                 size_t l;
1907                 void *a;
1908
1909                 l = strlen(contents);
1910                 a = message_extend_body(m, 1, 1 + l + 1, false, false);
1911                 if (!a)
1912                         return -ENOMEM;
1913
1914                 *(uint8_t*) a = l;
1915                 memcpy((uint8_t*) a + 1, contents, l + 1);
1916         }
1917
1918         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1919                 c->index++;
1920
1921         return 0;
1922 }
1923
1924 static int bus_message_open_struct(
1925                 sd_bus_message *m,
1926                 struct bus_container *c,
1927                 const char *contents,
1928                 size_t *begin,
1929                 bool *need_offsets) {
1930
1931         size_t nindex;
1932         int r;
1933
1934         assert(m);
1935         assert(c);
1936         assert(contents);
1937         assert(begin);
1938         assert(need_offsets);
1939
1940         if (!signature_is_valid(contents, false))
1941                 return -EINVAL;
1942
1943         if (c->signature && c->signature[c->index]) {
1944                 size_t l;
1945
1946                 l = strlen(contents);
1947
1948                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1949                     !startswith(c->signature + c->index + 1, contents) ||
1950                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1951                         return -ENXIO;
1952
1953                 nindex = c->index + 1 + l + 1;
1954         } else {
1955                 char *e;
1956
1957                 if (c->enclosing != 0)
1958                         return -ENXIO;
1959
1960                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1961                 if (!e) {
1962                         m->poisoned = true;
1963                         return -ENOMEM;
1964                 }
1965
1966                 nindex = e - c->signature;
1967         }
1968
1969         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1970                 int alignment;
1971
1972                 alignment = bus_gvariant_get_alignment(contents);
1973                 if (alignment < 0)
1974                         return alignment;
1975
1976                 if (!message_extend_body(m, alignment, 0, false, false))
1977                         return -ENOMEM;
1978
1979                 r = bus_gvariant_is_fixed_size(contents);
1980                 if (r < 0)
1981                         return r;
1982
1983                 *begin = m->body_size;
1984                 *need_offsets = r == 0;
1985         } else {
1986                 /* Align contents to 8 byte boundary */
1987                 if (!message_extend_body(m, 8, 0, false, false))
1988                         return -ENOMEM;
1989         }
1990
1991         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1992                 c->index = nindex;
1993
1994         return 0;
1995 }
1996
1997 static int bus_message_open_dict_entry(
1998                 sd_bus_message *m,
1999                 struct bus_container *c,
2000                 const char *contents,
2001                 size_t *begin,
2002                 bool *need_offsets) {
2003
2004         int r;
2005
2006         assert(m);
2007         assert(c);
2008         assert(contents);
2009         assert(begin);
2010         assert(need_offsets);
2011
2012         if (!signature_is_pair(contents))
2013                 return -EINVAL;
2014
2015         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2016                 return -ENXIO;
2017
2018         if (c->signature && c->signature[c->index]) {
2019                 size_t l;
2020
2021                 l = strlen(contents);
2022
2023                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2024                     !startswith(c->signature + c->index + 1, contents) ||
2025                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2026                         return -ENXIO;
2027         } else
2028                 return -ENXIO;
2029
2030         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2031                 int alignment;
2032
2033                 alignment = bus_gvariant_get_alignment(contents);
2034                 if (alignment < 0)
2035                         return alignment;
2036
2037                 if (!message_extend_body(m, alignment, 0, false, false))
2038                         return -ENOMEM;
2039
2040                 r = bus_gvariant_is_fixed_size(contents);
2041                 if (r < 0)
2042                         return r;
2043
2044                 *begin = m->body_size;
2045                 *need_offsets = r == 0;
2046         } else {
2047                 /* Align contents to 8 byte boundary */
2048                 if (!message_extend_body(m, 8, 0, false, false))
2049                         return -ENOMEM;
2050         }
2051
2052         return 0;
2053 }
2054
2055 _public_ int sd_bus_message_open_container(
2056                 sd_bus_message *m,
2057                 char type,
2058                 const char *contents) {
2059
2060         struct bus_container *c, *w;
2061         uint32_t *array_size = NULL;
2062         char *signature;
2063         size_t before, begin = 0;
2064         bool need_offsets = false;
2065         int r;
2066
2067         assert_return(m, -EINVAL);
2068         assert_return(!m->sealed, -EPERM);
2069         assert_return(contents, -EINVAL);
2070         assert_return(!m->poisoned, -ESTALE);
2071
2072         /* Make sure we have space for one more container */
2073         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
2074                 m->poisoned = true;
2075                 return -ENOMEM;
2076         }
2077
2078         c = message_get_container(m);
2079
2080         signature = strdup(contents);
2081         if (!signature) {
2082                 m->poisoned = true;
2083                 return -ENOMEM;
2084         }
2085
2086         /* Save old index in the parent container, in case we have to
2087          * abort this container */
2088         c->saved_index = c->index;
2089         before = m->body_size;
2090
2091         if (type == SD_BUS_TYPE_ARRAY)
2092                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
2093         else if (type == SD_BUS_TYPE_VARIANT)
2094                 r = bus_message_open_variant(m, c, contents);
2095         else if (type == SD_BUS_TYPE_STRUCT)
2096                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
2097         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2098                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
2099         else
2100                 r = -EINVAL;
2101
2102         if (r < 0) {
2103                 free(signature);
2104                 return r;
2105         }
2106
2107         /* OK, let's fill it in */
2108         w = m->containers + m->n_containers++;
2109         w->enclosing = type;
2110         w->signature = signature;
2111         w->index = 0;
2112         w->array_size = array_size;
2113         w->before = before;
2114         w->begin = begin;
2115         w->n_offsets = w->offsets_allocated = 0;
2116         w->offsets = NULL;
2117         w->need_offsets = need_offsets;
2118
2119         return 0;
2120 }
2121
2122 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2123
2124         assert(m);
2125         assert(c);
2126
2127         if (!BUS_MESSAGE_IS_GVARIANT(m))
2128                 return 0;
2129
2130         if (c->need_offsets) {
2131                 size_t payload, sz, i;
2132                 uint8_t *a;
2133
2134                 /* Variable-width arrays */
2135
2136                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2137                 sz = bus_gvariant_determine_word_size(payload, c->n_offsets);
2138
2139                 a = message_extend_body(m, 1, sz * c->n_offsets, true, false);
2140                 if (!a)
2141                         return -ENOMEM;
2142
2143                 for (i = 0; i < c->n_offsets; i++)
2144                         bus_gvariant_write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2145         } else {
2146                 void *a;
2147
2148                 /* Fixed-width or empty arrays */
2149
2150                 a = message_extend_body(m, 1, 0, true, false); /* let's add offset to parent */
2151                 if (!a)
2152                         return -ENOMEM;
2153         }
2154
2155         return 0;
2156 }
2157
2158 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2159         uint8_t *a;
2160         size_t l;
2161
2162         assert(m);
2163         assert(c);
2164         assert(c->signature);
2165
2166         if (!BUS_MESSAGE_IS_GVARIANT(m))
2167                 return 0;
2168
2169         l = strlen(c->signature);
2170
2171         a = message_extend_body(m, 1, 1 + l, true, false);
2172         if (!a)
2173                 return -ENOMEM;
2174
2175         a[0] = 0;
2176         memcpy(a+1, c->signature, l);
2177
2178         return 0;
2179 }
2180
2181 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2182         size_t n_variable = 0;
2183         unsigned i = 0;
2184         const char *p;
2185         uint8_t *a;
2186         int r;
2187
2188         assert(m);
2189         assert(c);
2190
2191         if (!BUS_MESSAGE_IS_GVARIANT(m))
2192                 return 0;
2193
2194         p = strempty(c->signature);
2195         while (*p != 0) {
2196                 size_t n;
2197
2198                 r = signature_element_length(p, &n);
2199                 if (r < 0)
2200                         return r;
2201                 else {
2202                         char t[n+1];
2203
2204                         memcpy(t, p, n);
2205                         t[n] = 0;
2206
2207                         r = bus_gvariant_is_fixed_size(t);
2208                         if (r < 0)
2209                                 return r;
2210                 }
2211
2212                 assert(!c->need_offsets || i <= c->n_offsets);
2213
2214                 /* We need to add an offset for each item that has a
2215                  * variable size and that is not the last one in the
2216                  * list */
2217                 if (r == 0 && p[n] != 0)
2218                         n_variable++;
2219
2220                 i++;
2221                 p += n;
2222         }
2223
2224         assert(!c->need_offsets || i == c->n_offsets);
2225         assert(c->need_offsets || n_variable == 0);
2226
2227         if (n_variable <= 0) {
2228                 a = message_extend_body(m, 1, 0, add_offset, false);
2229                 if (!a)
2230                         return -ENOMEM;
2231         } else {
2232                 size_t sz;
2233                 unsigned j;
2234
2235                 assert(c->offsets[c->n_offsets-1] == m->body_size);
2236
2237                 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2238
2239                 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2240                 if (!a)
2241                         return -ENOMEM;
2242
2243                 p = strempty(c->signature);
2244                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2245                         unsigned k;
2246                         size_t n;
2247
2248                         r = signature_element_length(p, &n);
2249                         if (r < 0)
2250                                 return r;
2251                         else {
2252                                 char t[n+1];
2253
2254                                 memcpy(t, p, n);
2255                                 t[n] = 0;
2256
2257                                 p += n;
2258
2259                                 r = bus_gvariant_is_fixed_size(t);
2260                                 if (r < 0)
2261                                         return r;
2262                                 if (r > 0 || p[0] == 0)
2263                                         continue;
2264                         }
2265
2266                         k = n_variable - 1 - j;
2267
2268                         bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2269
2270                         j++;
2271                 }
2272         }
2273
2274         return 0;
2275 }
2276
2277 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2278         struct bus_container *c;
2279         int r;
2280
2281         assert_return(m, -EINVAL);
2282         assert_return(!m->sealed, -EPERM);
2283         assert_return(m->n_containers > 0, -EINVAL);
2284         assert_return(!m->poisoned, -ESTALE);
2285
2286         c = message_get_container(m);
2287
2288         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2289                 if (c->signature && c->signature[c->index] != 0)
2290                         return -EINVAL;
2291
2292         m->n_containers--;
2293
2294         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2295                 r = bus_message_close_array(m, c);
2296         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2297                 r = bus_message_close_variant(m, c);
2298         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2299                 r = bus_message_close_struct(m, c, true);
2300         else
2301                 assert_not_reached("Unknown container type");
2302
2303         free(c->signature);
2304         free(c->offsets);
2305
2306         return r;
2307 }
2308
2309 typedef struct {
2310         const char *types;
2311         unsigned n_struct;
2312         unsigned n_array;
2313 } TypeStack;
2314
2315 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2316         assert(stack);
2317         assert(max > 0);
2318
2319         if (*i >= max)
2320                 return -EINVAL;
2321
2322         stack[*i].types = types;
2323         stack[*i].n_struct = n_struct;
2324         stack[*i].n_array = n_array;
2325         (*i)++;
2326
2327         return 0;
2328 }
2329
2330 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2331         assert(stack);
2332         assert(max > 0);
2333         assert(types);
2334         assert(n_struct);
2335         assert(n_array);
2336
2337         if (*i <= 0)
2338                 return 0;
2339
2340         (*i)--;
2341         *types = stack[*i].types;
2342         *n_struct = stack[*i].n_struct;
2343         *n_array = stack[*i].n_array;
2344
2345         return 1;
2346 }
2347
2348 int bus_message_append_ap(
2349                 sd_bus_message *m,
2350                 const char *types,
2351                 va_list ap) {
2352
2353         unsigned n_array, n_struct;
2354         TypeStack stack[BUS_CONTAINER_DEPTH];
2355         unsigned stack_ptr = 0;
2356         int r;
2357
2358         assert(m);
2359
2360         if (!types)
2361                 return 0;
2362
2363         n_array = (unsigned) -1;
2364         n_struct = strlen(types);
2365
2366         for (;;) {
2367                 const char *t;
2368
2369                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2370                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2371                         if (r < 0)
2372                                 return r;
2373                         if (r == 0)
2374                                 break;
2375
2376                         r = sd_bus_message_close_container(m);
2377                         if (r < 0)
2378                                 return r;
2379
2380                         continue;
2381                 }
2382
2383                 t = types;
2384                 if (n_array != (unsigned) -1)
2385                         n_array --;
2386                 else {
2387                         types ++;
2388                         n_struct--;
2389                 }
2390
2391                 switch (*t) {
2392
2393                 case SD_BUS_TYPE_BYTE: {
2394                         uint8_t x;
2395
2396                         x = (uint8_t) va_arg(ap, int);
2397                         r = sd_bus_message_append_basic(m, *t, &x);
2398                         break;
2399                 }
2400
2401                 case SD_BUS_TYPE_BOOLEAN:
2402                 case SD_BUS_TYPE_INT32:
2403                 case SD_BUS_TYPE_UINT32:
2404                 case SD_BUS_TYPE_UNIX_FD: {
2405                         uint32_t x;
2406
2407                         /* We assume a boolean is the same as int32_t */
2408                         assert_cc(sizeof(int32_t) == sizeof(int));
2409
2410                         x = va_arg(ap, uint32_t);
2411                         r = sd_bus_message_append_basic(m, *t, &x);
2412                         break;
2413                 }
2414
2415                 case SD_BUS_TYPE_INT16:
2416                 case SD_BUS_TYPE_UINT16: {
2417                         uint16_t x;
2418
2419                         x = (uint16_t) va_arg(ap, int);
2420                         r = sd_bus_message_append_basic(m, *t, &x);
2421                         break;
2422                 }
2423
2424                 case SD_BUS_TYPE_INT64:
2425                 case SD_BUS_TYPE_UINT64: {
2426                         uint64_t x;
2427
2428                         x = va_arg(ap, uint64_t);
2429                         r = sd_bus_message_append_basic(m, *t, &x);
2430                         break;
2431                 }
2432
2433                 case SD_BUS_TYPE_DOUBLE: {
2434                         double x;
2435
2436                         x = va_arg(ap, double);
2437                         r = sd_bus_message_append_basic(m, *t, &x);
2438                         break;
2439                 }
2440
2441                 case SD_BUS_TYPE_STRING:
2442                 case SD_BUS_TYPE_OBJECT_PATH:
2443                 case SD_BUS_TYPE_SIGNATURE: {
2444                         const char *x;
2445
2446                         x = va_arg(ap, const char*);
2447                         r = sd_bus_message_append_basic(m, *t, x);
2448                         break;
2449                 }
2450
2451                 case SD_BUS_TYPE_ARRAY: {
2452                         size_t k;
2453
2454                         r = signature_element_length(t + 1, &k);
2455                         if (r < 0)
2456                                 return r;
2457
2458                         {
2459                                 char s[k + 1];
2460                                 memcpy(s, t + 1, k);
2461                                 s[k] = 0;
2462
2463                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2464                                 if (r < 0)
2465                                         return r;
2466                         }
2467
2468                         if (n_array == (unsigned) -1) {
2469                                 types += k;
2470                                 n_struct -= k;
2471                         }
2472
2473                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2474                         if (r < 0)
2475                                 return r;
2476
2477                         types = t + 1;
2478                         n_struct = k;
2479                         n_array = va_arg(ap, unsigned);
2480
2481                         break;
2482                 }
2483
2484                 case SD_BUS_TYPE_VARIANT: {
2485                         const char *s;
2486
2487                         s = va_arg(ap, const char*);
2488                         if (!s)
2489                                 return -EINVAL;
2490
2491                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2492                         if (r < 0)
2493                                 return r;
2494
2495                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2496                         if (r < 0)
2497                                 return r;
2498
2499                         types = s;
2500                         n_struct = strlen(s);
2501                         n_array = (unsigned) -1;
2502
2503                         break;
2504                 }
2505
2506                 case SD_BUS_TYPE_STRUCT_BEGIN:
2507                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2508                         size_t k;
2509
2510                         r = signature_element_length(t, &k);
2511                         if (r < 0)
2512                                 return r;
2513
2514                         {
2515                                 char s[k - 1];
2516
2517                                 memcpy(s, t + 1, k - 2);
2518                                 s[k - 2] = 0;
2519
2520                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2521                                 if (r < 0)
2522                                         return r;
2523                         }
2524
2525                         if (n_array == (unsigned) -1) {
2526                                 types += k - 1;
2527                                 n_struct -= k - 1;
2528                         }
2529
2530                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2531                         if (r < 0)
2532                                 return r;
2533
2534                         types = t + 1;
2535                         n_struct = k - 2;
2536                         n_array = (unsigned) -1;
2537
2538                         break;
2539                 }
2540
2541                 default:
2542                         r = -EINVAL;
2543                 }
2544
2545                 if (r < 0)
2546                         return r;
2547         }
2548
2549         return 1;
2550 }
2551
2552 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2553         va_list ap;
2554         int r;
2555
2556         assert_return(m, -EINVAL);
2557         assert_return(types, -EINVAL);
2558         assert_return(!m->sealed, -EPERM);
2559         assert_return(!m->poisoned, -ESTALE);
2560
2561         va_start(ap, types);
2562         r = bus_message_append_ap(m, types, ap);
2563         va_end(ap);
2564
2565         return r;
2566 }
2567
2568 _public_ int sd_bus_message_append_array_space(
2569                 sd_bus_message *m,
2570                 char type,
2571                 size_t size,
2572                 void **ptr) {
2573
2574         ssize_t align, sz;
2575         void *a;
2576         int r;
2577
2578         assert_return(m, -EINVAL);
2579         assert_return(!m->sealed, -EPERM);
2580         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2581         assert_return(ptr || size == 0, -EINVAL);
2582         assert_return(!m->poisoned, -ESTALE);
2583
2584         /* alignment and size of the trivial types (except bool) is
2585          * identical for gvariant and dbus1 marshalling */
2586         align = bus_type_get_alignment(type);
2587         sz = bus_type_get_size(type);
2588
2589         assert_se(align > 0);
2590         assert_se(sz > 0);
2591
2592         if (size % sz != 0)
2593                 return -EINVAL;
2594
2595         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2596         if (r < 0)
2597                 return r;
2598
2599         a = message_extend_body(m, align, size, false, false);
2600         if (!a)
2601                 return -ENOMEM;
2602
2603         r = sd_bus_message_close_container(m);
2604         if (r < 0)
2605                 return r;
2606
2607         *ptr = a;
2608         return 0;
2609 }
2610
2611 _public_ int sd_bus_message_append_array(
2612                 sd_bus_message *m,
2613                 char type,
2614                 const void *ptr,
2615                 size_t size) {
2616         int r;
2617         void *p;
2618
2619         assert_return(m, -EINVAL);
2620         assert_return(!m->sealed, -EPERM);
2621         assert_return(bus_type_is_trivial(type), -EINVAL);
2622         assert_return(ptr || size == 0, -EINVAL);
2623         assert_return(!m->poisoned, -ESTALE);
2624
2625         r = sd_bus_message_append_array_space(m, type, size, &p);
2626         if (r < 0)
2627                 return r;
2628
2629         if (size > 0)
2630                 memcpy(p, ptr, size);
2631
2632         return 0;
2633 }
2634
2635 _public_ int sd_bus_message_append_array_iovec(
2636                 sd_bus_message *m,
2637                 char type,
2638                 const struct iovec *iov,
2639                 unsigned n) {
2640
2641         size_t size;
2642         unsigned i;
2643         void *p;
2644         int r;
2645
2646         assert_return(m, -EINVAL);
2647         assert_return(!m->sealed, -EPERM);
2648         assert_return(bus_type_is_trivial(type), -EINVAL);
2649         assert_return(iov || n == 0, -EINVAL);
2650         assert_return(!m->poisoned, -ESTALE);
2651
2652         size = IOVEC_TOTAL_SIZE(iov, n);
2653
2654         r = sd_bus_message_append_array_space(m, type, size, &p);
2655         if (r < 0)
2656                 return r;
2657
2658         for (i = 0; i < n; i++) {
2659
2660                 if (iov[i].iov_base)
2661                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2662                 else
2663                         memzero(p, iov[i].iov_len);
2664
2665                 p = (uint8_t*) p + iov[i].iov_len;
2666         }
2667
2668         return 0;
2669 }
2670
2671 _public_ int sd_bus_message_append_array_memfd(
2672                 sd_bus_message *m,
2673                 char type,
2674                 int memfd,
2675                 uint64_t offset,
2676                 uint64_t size) {
2677
2678         _cleanup_close_ int copy_fd = -1;
2679         struct bus_body_part *part;
2680         ssize_t align, sz;
2681         uint64_t real_size;
2682         void *a;
2683         int r;
2684
2685         assert_return(m, -EINVAL);
2686         assert_return(memfd >= 0, -EINVAL);
2687         assert_return(bus_type_is_trivial(type), -EINVAL);
2688         assert_return(size > 0, -EINVAL);
2689         assert_return(!m->sealed, -EPERM);
2690         assert_return(!m->poisoned, -ESTALE);
2691
2692         r = memfd_set_sealed(memfd);
2693         if (r < 0)
2694                 return r;
2695
2696         copy_fd = dup(memfd);
2697         if (copy_fd < 0)
2698                 return copy_fd;
2699
2700         r = memfd_get_size(memfd, &real_size);
2701         if (r < 0)
2702                 return r;
2703
2704         if (offset == 0 && size == (uint64_t) -1)
2705                 size = real_size;
2706         else if (offset + size > real_size)
2707                 return -EMSGSIZE;
2708
2709         align = bus_type_get_alignment(type);
2710         sz = bus_type_get_size(type);
2711
2712         assert_se(align > 0);
2713         assert_se(sz > 0);
2714
2715         if (offset % align != 0)
2716                 return -EINVAL;
2717
2718         if (size % sz != 0)
2719                 return -EINVAL;
2720
2721         if (size > (uint64_t) (uint32_t) -1)
2722                 return -EINVAL;
2723
2724         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2725         if (r < 0)
2726                 return r;
2727
2728         a = message_extend_body(m, align, 0, false, false);
2729         if (!a)
2730                 return -ENOMEM;
2731
2732         part = message_append_part(m);
2733         if (!part)
2734                 return -ENOMEM;
2735
2736         part->memfd = copy_fd;
2737         part->memfd_offset = offset;
2738         part->sealed = true;
2739         part->size = size;
2740         copy_fd = -1;
2741
2742         m->body_size += size;
2743         message_extend_containers(m, size);
2744
2745         return sd_bus_message_close_container(m);
2746 }
2747
2748 _public_ int sd_bus_message_append_string_memfd(
2749                 sd_bus_message *m,
2750                 int memfd,
2751                 uint64_t offset,
2752                 uint64_t size) {
2753
2754         _cleanup_close_ int copy_fd = -1;
2755         struct bus_body_part *part;
2756         struct bus_container *c;
2757         uint64_t real_size;
2758         void *a;
2759         int r;
2760
2761         assert_return(m, -EINVAL);
2762         assert_return(memfd >= 0, -EINVAL);
2763         assert_return(size > 0, -EINVAL);
2764         assert_return(!m->sealed, -EPERM);
2765         assert_return(!m->poisoned, -ESTALE);
2766
2767         r = memfd_set_sealed(memfd);
2768         if (r < 0)
2769                 return r;
2770
2771         copy_fd = dup(memfd);
2772         if (copy_fd < 0)
2773                 return copy_fd;
2774
2775         r = memfd_get_size(memfd, &real_size);
2776         if (r < 0)
2777                 return r;
2778
2779         if (offset == 0 && size == (uint64_t) -1)
2780                 size = real_size;
2781         else if (offset + size > real_size)
2782                 return -EMSGSIZE;
2783
2784         /* We require this to be NUL terminated */
2785         if (size == 0)
2786                 return -EINVAL;
2787
2788         if (size > (uint64_t) (uint32_t) -1)
2789                 return -EINVAL;
2790
2791         c = message_get_container(m);
2792         if (c->signature && c->signature[c->index]) {
2793                 /* Container signature is already set */
2794
2795                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2796                         return -ENXIO;
2797         } else {
2798                 char *e;
2799
2800                 /* Maybe we can append to the signature? But only if this is the top-level container */
2801                 if (c->enclosing != 0)
2802                         return -ENXIO;
2803
2804                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2805                 if (!e) {
2806                         m->poisoned = true;
2807                         return -ENOMEM;
2808                 }
2809         }
2810
2811         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2812                 a = message_extend_body(m, 4, 4, false, false);
2813                 if (!a)
2814                         return -ENOMEM;
2815
2816                 *(uint32_t*) a = size - 1;
2817         }
2818
2819         part = message_append_part(m);
2820         if (!part)
2821                 return -ENOMEM;
2822
2823         part->memfd = copy_fd;
2824         part->memfd_offset = offset;
2825         part->sealed = true;
2826         part->size = size;
2827         copy_fd = -1;
2828
2829         m->body_size += size;
2830         message_extend_containers(m, size);
2831
2832         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2833                 r = message_add_offset(m, m->body_size);
2834                 if (r < 0) {
2835                         m->poisoned = true;
2836                         return -ENOMEM;
2837                 }
2838         }
2839
2840         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2841                 c->index++;
2842
2843         return 0;
2844 }
2845
2846 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2847         char **i;
2848         int r;
2849
2850         assert_return(m, -EINVAL);
2851         assert_return(!m->sealed, -EPERM);
2852         assert_return(!m->poisoned, -ESTALE);
2853
2854         r = sd_bus_message_open_container(m, 'a', "s");
2855         if (r < 0)
2856                 return r;
2857
2858         STRV_FOREACH(i, l) {
2859                 r = sd_bus_message_append_basic(m, 's', *i);
2860                 if (r < 0)
2861                         return r;
2862         }
2863
2864         return sd_bus_message_close_container(m);
2865 }
2866
2867 static int bus_message_close_header(sd_bus_message *m) {
2868
2869         assert(m);
2870
2871         /* The actual user data is finished now, we just complete the
2872            variant and struct now (at least on gvariant). Remember
2873            this position, so that during parsing we know where to to
2874            put the outer container end. */
2875         m->user_body_size = m->body_size;
2876
2877         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2878                 const char *signature;
2879                 size_t sz, l;
2880                 void *d;
2881
2882                 /* Add offset table to end of fields array */
2883                 if (m->n_header_offsets >= 1) {
2884                         uint8_t *a;
2885                         unsigned i;
2886
2887                         assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2888
2889                         sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2890                         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2891                         if (!a)
2892                                 return -ENOMEM;
2893
2894                         for (i = 0; i < m->n_header_offsets; i++)
2895                                 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2896                 }
2897
2898                 /* Add gvariant NUL byte plus signature to the end of
2899                  * the body, followed by the final offset pointing to
2900                  * the end of the fields array */
2901
2902                 signature = strempty(m->root_container.signature);
2903                 l = strlen(signature);
2904
2905                 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l, 1);
2906                 d = message_extend_body(m, 1, 1 + l + sz, false, true);
2907                 if (!d)
2908                         return -ENOMEM;
2909
2910                 *(uint8_t*) d = 0;
2911                 memcpy((uint8_t*) d + 1, signature, l);
2912
2913                 bus_gvariant_write_word_le((uint8_t*) d + 1 + l, sz, sizeof(struct bus_header) + m->fields_size);
2914
2915                 m->footer = d;
2916                 m->footer_accessible = 1 + l + sz;
2917         } else {
2918                 m->header->dbus1.fields_size = m->fields_size;
2919                 m->header->dbus1.body_size = m->body_size;
2920         }
2921
2922         return 0;
2923 }
2924
2925 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2926         struct bus_body_part *part;
2927         size_t a;
2928         unsigned i;
2929         int r;
2930
2931         assert(m);
2932
2933         if (m->sealed)
2934                 return -EPERM;
2935
2936         if (m->n_containers > 0)
2937                 return -EBADMSG;
2938
2939         if (m->poisoned)
2940                 return -ESTALE;
2941
2942         if (cookie > 0xffffffffULL &&
2943             !BUS_MESSAGE_IS_GVARIANT(m))
2944                 return -ENOTSUP;
2945
2946         /* In vtables the return signature of method calls is listed,
2947          * let's check if they match if this is a response */
2948         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2949             m->enforced_reply_signature &&
2950             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2951                 return -ENOMSG;
2952
2953         /* If gvariant marshalling is used we need to close the body structure */
2954         r = bus_message_close_struct(m, &m->root_container, false);
2955         if (r < 0)
2956                 return r;
2957
2958         /* If there's a non-trivial signature set, then add it in
2959          * here, but only on dbus1 */
2960         if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2961                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2962                 if (r < 0)
2963                         return r;
2964         }
2965
2966         if (m->n_fds > 0) {
2967                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2968                 if (r < 0)
2969                         return r;
2970         }
2971
2972         r = bus_message_close_header(m);
2973         if (r < 0)
2974                 return r;
2975
2976         if (BUS_MESSAGE_IS_GVARIANT(m))
2977                 m->header->dbus2.cookie = cookie;
2978         else
2979                 m->header->dbus1.serial = (uint32_t) cookie;
2980
2981         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2982
2983         /* Add padding at the end of the fields part, since we know
2984          * the body needs to start at an 8 byte alignment. We made
2985          * sure we allocated enough space for this, so all we need to
2986          * do here is to zero it out. */
2987         a = ALIGN8(m->fields_size) - m->fields_size;
2988         if (a > 0)
2989                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2990
2991         /* If this is something we can send as memfd, then let's seal
2992         the memfd now. Note that we can send memfds as payload only
2993         for directed messages, and not for broadcasts. */
2994         if (m->destination && m->bus->use_memfd) {
2995                 MESSAGE_FOREACH_PART(part, i, m)
2996                         if (part->memfd >= 0 &&
2997                             !part->sealed &&
2998                             (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
2999                             part != m->body_end) { /* The last part may never be sent as memfd */
3000                                 uint64_t sz;
3001
3002                                 /* Try to seal it if that makes
3003                                  * sense. First, unmap our own map to
3004                                  * make sure we don't keep it busy. */
3005                                 bus_body_part_unmap(part);
3006
3007                                 /* Then, sync up real memfd size */
3008                                 sz = part->size;
3009                                 r = memfd_set_size(part->memfd, sz);
3010                                 if (r < 0)
3011                                         return r;
3012
3013                                 /* Finally, try to seal */
3014                                 if (memfd_set_sealed(part->memfd) >= 0)
3015                                         part->sealed = true;
3016                         }
3017         }
3018
3019         m->root_container.end = m->user_body_size;
3020         m->root_container.index = 0;
3021         m->root_container.offset_index = 0;
3022         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3023
3024         m->sealed = true;
3025
3026         return 0;
3027 }
3028
3029 int bus_body_part_map(struct bus_body_part *part) {
3030         void *p;
3031         size_t psz, shift;
3032
3033         assert_se(part);
3034
3035         if (part->data)
3036                 return 0;
3037
3038         if (part->size <= 0)
3039                 return 0;
3040
3041         /* For smaller zero parts (as used for padding) we don't need to map anything... */
3042         if (part->memfd < 0 && part->is_zero && part->size < 8) {
3043                 static const uint8_t zeroes[7] = { };
3044                 part->data = (void*) zeroes;
3045                 return 0;
3046         }
3047
3048         shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3049         psz = PAGE_ALIGN(part->size + shift);
3050
3051         if (part->memfd >= 0)
3052                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3053         else if (part->is_zero)
3054                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3055         else
3056                 return -EINVAL;
3057
3058         if (p == MAP_FAILED)
3059                 return -errno;
3060
3061         part->mapped = psz;
3062         part->mmap_begin = p;
3063         part->data = (uint8_t*) p + shift;
3064         part->munmap_this = true;
3065
3066         return 0;
3067 }
3068
3069 void bus_body_part_unmap(struct bus_body_part *part) {
3070
3071         assert_se(part);
3072
3073         if (part->memfd < 0)
3074                 return;
3075
3076         if (!part->mmap_begin)
3077                 return;
3078
3079         if (!part->munmap_this)
3080                 return;
3081
3082         assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3083
3084         part->mmap_begin = NULL;
3085         part->data = NULL;
3086         part->mapped = 0;
3087         part->munmap_this = false;
3088
3089         return;
3090 }
3091
3092 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3093         size_t k, start, end;
3094
3095         assert(rindex);
3096         assert(align > 0);
3097
3098         start = ALIGN_TO((size_t) *rindex, align);
3099         end = start + nbytes;
3100
3101         if (end > sz)
3102                 return -EBADMSG;
3103
3104         /* Verify that padding is 0 */
3105         for (k = *rindex; k < start; k++)
3106                 if (((const uint8_t*) p)[k] != 0)
3107                         return -EBADMSG;
3108
3109         if (r)
3110                 *r = (uint8_t*) p + start;
3111
3112         *rindex = end;
3113
3114         return 1;
3115 }
3116
3117 static bool message_end_of_signature(sd_bus_message *m) {
3118         struct bus_container *c;
3119
3120         assert(m);
3121
3122         c = message_get_container(m);
3123         return !c->signature || c->signature[c->index] == 0;
3124 }
3125
3126 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3127         struct bus_container *c;
3128
3129         assert(m);
3130
3131         c = message_get_container(m);
3132         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3133                 return false;
3134
3135         if (BUS_MESSAGE_IS_GVARIANT(m))
3136                 return index >= c->end;
3137         else {
3138                 assert(c->array_size);
3139                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3140         }
3141 }
3142
3143 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3144         assert_return(m, -EINVAL);
3145         assert_return(m->sealed, -EPERM);
3146
3147         if (complete && m->n_containers > 0)
3148                 return false;
3149
3150         if (message_end_of_signature(m))
3151                 return true;
3152
3153         if (message_end_of_array(m, m->rindex))
3154                 return true;
3155
3156         return false;
3157 }
3158
3159 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3160         struct bus_body_part *part;
3161         size_t begin;
3162         int r;
3163
3164         assert(m);
3165
3166         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3167                 part = m->cached_rindex_part;
3168                 begin = m->cached_rindex_part_begin;
3169         } else {
3170                 part = &m->body;
3171                 begin = 0;
3172         }
3173
3174         while (part) {
3175                 if (index < begin)
3176                         return NULL;
3177
3178                 if (index + sz <= begin + part->size) {
3179
3180                         r = bus_body_part_map(part);
3181                         if (r < 0)
3182                                 return NULL;
3183
3184                         if (p)
3185                                 *p = (uint8_t*) part->data + index - begin;
3186
3187                         m->cached_rindex_part = part;
3188                         m->cached_rindex_part_begin = begin;
3189
3190                         return part;
3191                 }
3192
3193                 begin += part->size;
3194                 part = part->next;
3195         }
3196
3197         return NULL;
3198 }
3199
3200 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3201         int r;
3202
3203         assert(m);
3204         assert(c);
3205         assert(rindex);
3206
3207         if (!BUS_MESSAGE_IS_GVARIANT(m))
3208                 return 0;
3209
3210         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3211                 int sz;
3212
3213                 sz = bus_gvariant_get_size(c->signature);
3214                 if (sz < 0) {
3215                         int alignment;
3216
3217                         if (c->offset_index+1 >= c->n_offsets)
3218                                 goto end;
3219
3220                         /* Variable-size array */
3221
3222                         alignment = bus_gvariant_get_alignment(c->signature);
3223                         assert(alignment > 0);
3224
3225                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3226                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3227                 } else {
3228
3229                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3230                                 goto end;
3231
3232                         /* Fixed-size array */
3233                         *rindex = c->begin + (c->offset_index+1) * sz;
3234                         c->item_size = sz;
3235                 }
3236
3237                 c->offset_index++;
3238
3239         } else if (c->enclosing == 0 ||
3240                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3241                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3242
3243                 int alignment;
3244                 size_t n, j;
3245
3246                 if (c->offset_index+1 >= c->n_offsets)
3247                         goto end;
3248
3249                 r = signature_element_length(c->signature + c->index, &n);
3250                 if (r < 0)
3251                         return r;
3252
3253                 r = signature_element_length(c->signature + c->index + n, &j);
3254                 if (r < 0)
3255                         return r;
3256                 else {
3257                         char t[j+1];
3258                         memcpy(t, c->signature + c->index + n, j);
3259                         t[j] = 0;
3260
3261                         alignment = bus_gvariant_get_alignment(t);
3262                 }
3263
3264                 assert(alignment > 0);
3265
3266                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3267                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3268
3269                 c->offset_index++;
3270
3271         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3272                 goto end;
3273         else
3274                 assert_not_reached("Unknown container type");
3275
3276         return 0;
3277
3278 end:
3279         /* Reached the end */
3280         *rindex = c->end;
3281         c->item_size = 0;
3282         return 0;
3283 }
3284
3285
3286 static int message_peek_body(
3287                 sd_bus_message *m,
3288                 size_t *rindex,
3289                 size_t align,
3290                 size_t nbytes,
3291                 void **ret) {
3292
3293         size_t k, start, end, padding;
3294         struct bus_body_part *part;
3295         uint8_t *q;
3296
3297         assert(m);
3298         assert(rindex);
3299         assert(align > 0);
3300
3301         start = ALIGN_TO((size_t) *rindex, align);
3302         padding = start - *rindex;
3303         end = start + nbytes;
3304
3305         if (end > m->user_body_size)
3306                 return -EBADMSG;
3307
3308         part = find_part(m, *rindex, padding, (void**) &q);
3309         if (!part)
3310                 return -EBADMSG;
3311
3312         if (q) {
3313                 /* Verify padding */
3314                 for (k = 0; k < padding; k++)
3315                         if (q[k] != 0)
3316                                 return -EBADMSG;
3317         }
3318
3319         part = find_part(m, start, nbytes, (void**) &q);
3320         if (!part || (nbytes > 0 && !q))
3321                 return -EBADMSG;
3322
3323         *rindex = end;
3324
3325         if (ret)
3326                 *ret = q;
3327
3328         return 0;
3329 }
3330
3331 static bool validate_nul(const char *s, size_t l) {
3332
3333         /* Check for NUL chars in the string */
3334         if (memchr(s, 0, l))
3335                 return false;
3336
3337         /* Check for NUL termination */
3338         if (s[l] != 0)
3339                 return false;
3340
3341         return true;
3342 }
3343
3344 static bool validate_string(const char *s, size_t l) {
3345
3346         if (!validate_nul(s, l))
3347                 return false;
3348
3349         /* Check if valid UTF8 */
3350         if (!utf8_is_valid(s))
3351                 return false;
3352
3353         return true;
3354 }
3355
3356 static bool validate_signature(const char *s, size_t l) {
3357
3358         if (!validate_nul(s, l))
3359                 return false;
3360
3361         /* Check if valid signature */
3362         if (!signature_is_valid(s, true))
3363                 return false;
3364
3365         return true;
3366 }
3367
3368 static bool validate_object_path(const char *s, size_t l) {
3369
3370         if (!validate_nul(s, l))
3371                 return false;
3372
3373         if (!object_path_is_valid(s))
3374                 return false;
3375
3376         return true;
3377 }
3378
3379 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3380         struct bus_container *c;
3381         size_t rindex;
3382         void *q;
3383         int r;
3384
3385         assert_return(m, -EINVAL);
3386         assert_return(m->sealed, -EPERM);
3387         assert_return(bus_type_is_basic(type), -EINVAL);
3388
3389         if (message_end_of_signature(m))
3390                 return -ENXIO;
3391
3392         if (message_end_of_array(m, m->rindex))
3393                 return 0;
3394
3395         c = message_get_container(m);
3396         if (c->signature[c->index] != type)
3397                 return -ENXIO;
3398
3399         rindex = m->rindex;
3400
3401         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3402
3403                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3404                         bool ok;
3405
3406                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3407                         if (r < 0)
3408                                 return r;
3409
3410                         if (type == SD_BUS_TYPE_STRING)
3411                                 ok = validate_string(q, c->item_size-1);
3412                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3413                                 ok = validate_object_path(q, c->item_size-1);
3414                         else
3415                                 ok = validate_signature(q, c->item_size-1);
3416
3417                         if (!ok)
3418                                 return -EBADMSG;
3419
3420                         if (p)
3421                                 *(const char**) p = q;
3422                 } else {
3423                         int sz, align;
3424
3425                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3426                         assert(sz > 0);
3427                         if ((size_t) sz != c->item_size)
3428                                 return -EBADMSG;
3429
3430                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3431                         assert(align > 0);
3432
3433                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3434                         if (r < 0)
3435                                 return r;
3436
3437                         switch (type) {
3438
3439                         case SD_BUS_TYPE_BYTE:
3440                                 if (p)
3441                                         *(uint8_t*) p = *(uint8_t*) q;
3442                                 break;
3443
3444                         case SD_BUS_TYPE_BOOLEAN:
3445                                 if (p)
3446                                         *(int*) p = !!*(uint8_t*) q;
3447                                 break;
3448
3449                         case SD_BUS_TYPE_INT16:
3450                         case SD_BUS_TYPE_UINT16:
3451                                 if (p)
3452                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3453                                 break;
3454
3455                         case SD_BUS_TYPE_INT32:
3456                         case SD_BUS_TYPE_UINT32:
3457                                 if (p)
3458                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3459                                 break;
3460
3461                         case SD_BUS_TYPE_INT64:
3462                         case SD_BUS_TYPE_UINT64:
3463                         case SD_BUS_TYPE_DOUBLE:
3464                                 if (p)
3465                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3466                                 break;
3467
3468                         case SD_BUS_TYPE_UNIX_FD: {
3469                                 uint32_t j;
3470
3471                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3472                                 if (j >= m->n_fds)
3473                                         return -EBADMSG;
3474
3475                                 if (p)
3476                                         *(int*) p = m->fds[j];
3477
3478                                 break;
3479                         }
3480
3481                         default:
3482                                 assert_not_reached("unexpected type");
3483                         }
3484                 }
3485
3486                 r = container_next_item(m, c, &rindex);
3487                 if (r < 0)
3488                         return r;
3489         } else {
3490
3491                 rindex = m->rindex;
3492
3493                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3494                         uint32_t l;
3495                         bool ok;
3496
3497                         r = message_peek_body(m, &rindex, 4, 4, &q);
3498                         if (r < 0)
3499                                 return r;
3500
3501                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3502                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3503                         if (r < 0)
3504                                 return r;
3505
3506                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3507                                 ok = validate_object_path(q, l);
3508                         else
3509                                 ok = validate_string(q, l);
3510                         if (!ok)
3511                                 return -EBADMSG;
3512
3513                         if (p)
3514                                 *(const char**) p = q;
3515
3516                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3517                         uint8_t l;
3518
3519                         r = message_peek_body(m, &rindex, 1, 1, &q);
3520                         if (r < 0)
3521                                 return r;
3522
3523                         l = *(uint8_t*) q;
3524                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3525                         if (r < 0)
3526                                 return r;
3527
3528                         if (!validate_signature(q, l))
3529                                 return -EBADMSG;
3530
3531                         if (p)
3532                                 *(const char**) p = q;
3533
3534                 } else {
3535                         ssize_t sz, align;
3536
3537                         align = bus_type_get_alignment(type);
3538                         assert(align > 0);
3539
3540                         sz = bus_type_get_size(type);
3541                         assert(sz > 0);
3542
3543                         r = message_peek_body(m, &rindex, align, sz, &q);
3544                         if (r < 0)
3545                                 return r;
3546
3547                         switch (type) {
3548
3549                         case SD_BUS_TYPE_BYTE:
3550                                 if (p)
3551                                         *(uint8_t*) p = *(uint8_t*) q;
3552                                 break;
3553
3554                         case SD_BUS_TYPE_BOOLEAN:
3555                                 if (p)
3556                                         *(int*) p = !!*(uint32_t*) q;
3557                                 break;
3558
3559                         case SD_BUS_TYPE_INT16:
3560                         case SD_BUS_TYPE_UINT16:
3561                                 if (p)
3562                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3563                                 break;
3564
3565                         case SD_BUS_TYPE_INT32:
3566                         case SD_BUS_TYPE_UINT32:
3567                                 if (p)
3568                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3569                                 break;
3570
3571                         case SD_BUS_TYPE_INT64:
3572                         case SD_BUS_TYPE_UINT64:
3573                         case SD_BUS_TYPE_DOUBLE:
3574                                 if (p)
3575                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3576                                 break;
3577
3578                         case SD_BUS_TYPE_UNIX_FD: {
3579                                 uint32_t j;
3580
3581                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3582                                 if (j >= m->n_fds)
3583                                         return -EBADMSG;
3584
3585                                 if (p)
3586                                         *(int*) p = m->fds[j];
3587                                 break;
3588                         }
3589
3590                         default:
3591                                 assert_not_reached("Unknown basic type...");
3592                         }
3593                 }
3594         }
3595
3596         m->rindex = rindex;
3597
3598         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3599                 c->index++;
3600
3601         return 1;
3602 }
3603
3604 static int bus_message_enter_array(
3605                 sd_bus_message *m,
3606                 struct bus_container *c,
3607                 const char *contents,
3608                 uint32_t **array_size,
3609                 size_t *item_size,
3610                 size_t **offsets,
3611                 size_t *n_offsets) {
3612
3613         size_t rindex;
3614         void *q;
3615         int r, alignment;
3616
3617         assert(m);
3618         assert(c);
3619         assert(contents);
3620         assert(array_size);
3621         assert(item_size);
3622         assert(offsets);
3623         assert(n_offsets);
3624
3625         if (!signature_is_single(contents, true))
3626                 return -EINVAL;
3627
3628         if (!c->signature || c->signature[c->index] == 0)
3629                 return -ENXIO;
3630
3631         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3632                 return -ENXIO;
3633
3634         if (!startswith(c->signature + c->index + 1, contents))
3635                 return -ENXIO;
3636
3637         rindex = m->rindex;
3638
3639         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3640                 /* dbus1 */
3641
3642                 r = message_peek_body(m, &rindex, 4, 4, &q);
3643                 if (r < 0)
3644                         return r;
3645
3646                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3647                         return -EBADMSG;
3648
3649                 alignment = bus_type_get_alignment(contents[0]);
3650                 if (alignment < 0)
3651                         return alignment;