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