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