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