chiark / gitweb /
sd-bus: add extra assert check
[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         assert(c->signature);
2067
2068         if (!BUS_MESSAGE_IS_GVARIANT(m))
2069                 return 0;
2070
2071         l = strlen(c->signature);
2072
2073         a = message_extend_body(m, 1, 1 + l, true);
2074         if (!a)
2075                 return -ENOMEM;
2076
2077         a[0] = 0;
2078         memcpy(a+1, c->signature, l);
2079
2080         return 0;
2081 }
2082
2083 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2084         size_t n_variable = 0;
2085         unsigned i = 0;
2086         const char *p;
2087         uint8_t *a;
2088         int r;
2089
2090         assert(m);
2091         assert(c);
2092
2093         if (!BUS_MESSAGE_IS_GVARIANT(m))
2094                 return 0;
2095
2096         p = strempty(c->signature);
2097         while (*p != 0) {
2098                 size_t n;
2099
2100                 r = signature_element_length(p, &n);
2101                 if (r < 0)
2102                         return r;
2103                 else {
2104                         char t[n+1];
2105
2106                         memcpy(t, p, n);
2107                         t[n] = 0;
2108
2109                         r = bus_gvariant_is_fixed_size(t);
2110                         if (r < 0)
2111                                 return r;
2112                 }
2113
2114                 assert(!c->need_offsets || i <= c->n_offsets);
2115
2116                 /* We need to add an offset for each item that has a
2117                  * variable size and that is not the last one in the
2118                  * list */
2119                 if (r == 0 && p[n] != 0)
2120                         n_variable++;
2121
2122                 i++;
2123                 p += n;
2124         }
2125
2126         assert(!c->need_offsets || i == c->n_offsets);
2127         assert(c->need_offsets || n_variable == 0);
2128
2129         if (n_variable <= 0) {
2130                 a = message_extend_body(m, 1, 0, add_offset);
2131                 if (!a)
2132                         return -ENOMEM;
2133         } else {
2134                 size_t sz;
2135                 unsigned j;
2136
2137                 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2138
2139                 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2140
2141                 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2142                 if (!a)
2143                         return -ENOMEM;
2144
2145                 p = strempty(c->signature);
2146                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2147                         unsigned k;
2148                         size_t n;
2149
2150                         r = signature_element_length(p, &n);
2151                         if (r < 0)
2152                                 return r;
2153                         else {
2154                                 char t[n+1];
2155
2156                                 memcpy(t, p, n);
2157                                 t[n] = 0;
2158
2159                                 p += n;
2160
2161                                 r = bus_gvariant_is_fixed_size(t);
2162                                 if (r < 0)
2163                                         return r;
2164                                 if (r > 0 || p[0] == 0)
2165                                         continue;
2166                         }
2167
2168                         k = n_variable - 1 - j;
2169
2170                         write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2171
2172                         j++;
2173                 }
2174         }
2175
2176         return 0;
2177 }
2178
2179 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2180         struct bus_container *c;
2181         int r;
2182
2183         assert_return(m, -EINVAL);
2184         assert_return(!m->sealed, -EPERM);
2185         assert_return(m->n_containers > 0, -EINVAL);
2186         assert_return(!m->poisoned, -ESTALE);
2187
2188         c = message_get_container(m);
2189
2190         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2191                 if (c->signature && c->signature[c->index] != 0)
2192                         return -EINVAL;
2193
2194         m->n_containers--;
2195
2196         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2197                 r = bus_message_close_array(m, c);
2198         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2199                 r = bus_message_close_variant(m, c);
2200         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2201                 r = bus_message_close_struct(m, c, true);
2202         else
2203                 assert_not_reached("Unknown container type");
2204
2205         free(c->signature);
2206         free(c->offsets);
2207
2208         return r;
2209 }
2210
2211 typedef struct {
2212         const char *types;
2213         unsigned n_struct;
2214         unsigned n_array;
2215 } TypeStack;
2216
2217 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2218         assert(stack);
2219         assert(max > 0);
2220
2221         if (*i >= max)
2222                 return -EINVAL;
2223
2224         stack[*i].types = types;
2225         stack[*i].n_struct = n_struct;
2226         stack[*i].n_array = n_array;
2227         (*i)++;
2228
2229         return 0;
2230 }
2231
2232 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2233         assert(stack);
2234         assert(max > 0);
2235         assert(types);
2236         assert(n_struct);
2237         assert(n_array);
2238
2239         if (*i <= 0)
2240                 return 0;
2241
2242         (*i)--;
2243         *types = stack[*i].types;
2244         *n_struct = stack[*i].n_struct;
2245         *n_array = stack[*i].n_array;
2246
2247         return 1;
2248 }
2249
2250 int bus_message_append_ap(
2251                 sd_bus_message *m,
2252                 const char *types,
2253                 va_list ap) {
2254
2255         unsigned n_array, n_struct;
2256         TypeStack stack[BUS_CONTAINER_DEPTH];
2257         unsigned stack_ptr = 0;
2258         int r;
2259
2260         assert(m);
2261
2262         if (!types)
2263                 return 0;
2264
2265         n_array = (unsigned) -1;
2266         n_struct = strlen(types);
2267
2268         for (;;) {
2269                 const char *t;
2270
2271                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2272                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2273                         if (r < 0)
2274                                 return r;
2275                         if (r == 0)
2276                                 break;
2277
2278                         r = sd_bus_message_close_container(m);
2279                         if (r < 0)
2280                                 return r;
2281
2282                         continue;
2283                 }
2284
2285                 t = types;
2286                 if (n_array != (unsigned) -1)
2287                         n_array --;
2288                 else {
2289                         types ++;
2290                         n_struct--;
2291                 }
2292
2293                 switch (*t) {
2294
2295                 case SD_BUS_TYPE_BYTE: {
2296                         uint8_t x;
2297
2298                         x = (uint8_t) va_arg(ap, int);
2299                         r = sd_bus_message_append_basic(m, *t, &x);
2300                         break;
2301                 }
2302
2303                 case SD_BUS_TYPE_BOOLEAN:
2304                 case SD_BUS_TYPE_INT32:
2305                 case SD_BUS_TYPE_UINT32:
2306                 case SD_BUS_TYPE_UNIX_FD: {
2307                         uint32_t x;
2308
2309                         /* We assume a boolean is the same as int32_t */
2310                         assert_cc(sizeof(int32_t) == sizeof(int));
2311
2312                         x = va_arg(ap, uint32_t);
2313                         r = sd_bus_message_append_basic(m, *t, &x);
2314                         break;
2315                 }
2316
2317                 case SD_BUS_TYPE_INT16:
2318                 case SD_BUS_TYPE_UINT16: {
2319                         uint16_t x;
2320
2321                         x = (uint16_t) va_arg(ap, int);
2322                         r = sd_bus_message_append_basic(m, *t, &x);
2323                         break;
2324                 }
2325
2326                 case SD_BUS_TYPE_INT64:
2327                 case SD_BUS_TYPE_UINT64:
2328                 case SD_BUS_TYPE_DOUBLE: {
2329                         uint64_t x;
2330
2331                         x = va_arg(ap, uint64_t);
2332                         r = sd_bus_message_append_basic(m, *t, &x);
2333                         break;
2334                 }
2335
2336                 case SD_BUS_TYPE_STRING:
2337                 case SD_BUS_TYPE_OBJECT_PATH:
2338                 case SD_BUS_TYPE_SIGNATURE: {
2339                         const char *x;
2340
2341                         x = va_arg(ap, const char*);
2342                         r = sd_bus_message_append_basic(m, *t, x);
2343                         break;
2344                 }
2345
2346                 case SD_BUS_TYPE_ARRAY: {
2347                         size_t k;
2348
2349                         r = signature_element_length(t + 1, &k);
2350                         if (r < 0)
2351                                 return r;
2352
2353                         {
2354                                 char s[k + 1];
2355                                 memcpy(s, t + 1, k);
2356                                 s[k] = 0;
2357
2358                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2359                                 if (r < 0)
2360                                         return r;
2361                         }
2362
2363                         if (n_array == (unsigned) -1) {
2364                                 types += k;
2365                                 n_struct -= k;
2366                         }
2367
2368                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2369                         if (r < 0)
2370                                 return r;
2371
2372                         types = t + 1;
2373                         n_struct = k;
2374                         n_array = va_arg(ap, unsigned);
2375
2376                         break;
2377                 }
2378
2379                 case SD_BUS_TYPE_VARIANT: {
2380                         const char *s;
2381
2382                         s = va_arg(ap, const char*);
2383                         if (!s)
2384                                 return -EINVAL;
2385
2386                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2387                         if (r < 0)
2388                                 return r;
2389
2390                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2391                         if (r < 0)
2392                                 return r;
2393
2394                         types = s;
2395                         n_struct = strlen(s);
2396                         n_array = (unsigned) -1;
2397
2398                         break;
2399                 }
2400
2401                 case SD_BUS_TYPE_STRUCT_BEGIN:
2402                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2403                         size_t k;
2404
2405                         r = signature_element_length(t, &k);
2406                         if (r < 0)
2407                                 return r;
2408
2409                         {
2410                                 char s[k - 1];
2411
2412                                 memcpy(s, t + 1, k - 2);
2413                                 s[k - 2] = 0;
2414
2415                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2416                                 if (r < 0)
2417                                         return r;
2418                         }
2419
2420                         if (n_array == (unsigned) -1) {
2421                                 types += k - 1;
2422                                 n_struct -= k - 1;
2423                         }
2424
2425                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2426                         if (r < 0)
2427                                 return r;
2428
2429                         types = t + 1;
2430                         n_struct = k - 2;
2431                         n_array = (unsigned) -1;
2432
2433                         break;
2434                 }
2435
2436                 default:
2437                         r = -EINVAL;
2438                 }
2439
2440                 if (r < 0)
2441                         return r;
2442         }
2443
2444         return 1;
2445 }
2446
2447 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2448         va_list ap;
2449         int r;
2450
2451         assert_return(m, -EINVAL);
2452         assert_return(types, -EINVAL);
2453         assert_return(!m->sealed, -EPERM);
2454         assert_return(!m->poisoned, -ESTALE);
2455
2456         va_start(ap, types);
2457         r = bus_message_append_ap(m, types, ap);
2458         va_end(ap);
2459
2460         return r;
2461 }
2462
2463 _public_ int sd_bus_message_append_array_space(
2464                 sd_bus_message *m,
2465                 char type,
2466                 size_t size,
2467                 void **ptr) {
2468
2469         ssize_t align, sz;
2470         void *a;
2471         int r;
2472
2473         assert_return(m, -EINVAL);
2474         assert_return(!m->sealed, -EPERM);
2475         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2476         assert_return(ptr || size == 0, -EINVAL);
2477         assert_return(!m->poisoned, -ESTALE);
2478
2479         /* alignment and size of the trivial types (except bool) is
2480          * identical for gvariant and dbus1 marshalling */
2481         align = bus_type_get_alignment(type);
2482         sz = bus_type_get_size(type);
2483
2484         assert_se(align > 0);
2485         assert_se(sz > 0);
2486
2487         if (size % sz != 0)
2488                 return -EINVAL;
2489
2490         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2491         if (r < 0)
2492                 return r;
2493
2494         a = message_extend_body(m, align, size, false);
2495         if (!a)
2496                 return -ENOMEM;
2497
2498         r = sd_bus_message_close_container(m);
2499         if (r < 0)
2500                 return r;
2501
2502         *ptr = a;
2503         return 0;
2504 }
2505
2506 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2507                                          char type,
2508                                          const void *ptr,
2509                                          size_t size) {
2510         int r;
2511         void *p;
2512
2513         assert_return(m, -EINVAL);
2514         assert_return(!m->sealed, -EPERM);
2515         assert_return(bus_type_is_trivial(type), -EINVAL);
2516         assert_return(ptr || size == 0, -EINVAL);
2517         assert_return(!m->poisoned, -ESTALE);
2518
2519         r = sd_bus_message_append_array_space(m, type, size, &p);
2520         if (r < 0)
2521                 return r;
2522
2523         if (size > 0)
2524                 memcpy(p, ptr, size);
2525
2526         return 0;
2527 }
2528
2529 _public_ int sd_bus_message_append_array_iovec(
2530                 sd_bus_message *m,
2531                 char type,
2532                 const struct iovec *iov,
2533                 unsigned n) {
2534
2535         size_t size;
2536         unsigned i;
2537         void *p;
2538         int r;
2539
2540         assert_return(m, -EINVAL);
2541         assert_return(!m->sealed, -EPERM);
2542         assert_return(bus_type_is_trivial(type), -EINVAL);
2543         assert_return(iov || n == 0, -EINVAL);
2544         assert_return(!m->poisoned, -ESTALE);
2545
2546         size = IOVEC_TOTAL_SIZE(iov, n);
2547
2548         r = sd_bus_message_append_array_space(m, type, size, &p);
2549         if (r < 0)
2550                 return r;
2551
2552         for (i = 0; i < n; i++) {
2553
2554                 if (iov[i].iov_base)
2555                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2556                 else
2557                         memzero(p, iov[i].iov_len);
2558
2559                 p = (uint8_t*) p + iov[i].iov_len;
2560         }
2561
2562         return 0;
2563 }
2564
2565 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2566                                                char type,
2567                                                int memfd) {
2568         _cleanup_close_ int copy_fd = -1;
2569         struct bus_body_part *part;
2570         ssize_t align, sz;
2571         uint64_t size;
2572         void *a;
2573         int r;
2574
2575         if (!m)
2576                 return -EINVAL;
2577         if (memfd < 0)
2578                 return -EINVAL;
2579         if (m->sealed)
2580                 return -EPERM;
2581         if (!bus_type_is_trivial(type))
2582                 return -EINVAL;
2583         if (m->poisoned)
2584                 return -ESTALE;
2585
2586         r = memfd_set_sealed(memfd);
2587         if (r < 0)
2588                 return r;
2589
2590         copy_fd = dup(memfd);
2591         if (copy_fd < 0)
2592                 return copy_fd;
2593
2594         r = memfd_get_size(memfd, &size);
2595         if (r < 0)
2596                 return r;
2597
2598         align = bus_type_get_alignment(type);
2599         sz = bus_type_get_size(type);
2600
2601         assert_se(align > 0);
2602         assert_se(sz > 0);
2603
2604         if (size % sz != 0)
2605                 return -EINVAL;
2606
2607         if (size > (uint64_t) (uint32_t) -1)
2608                 return -EINVAL;
2609
2610         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2611         if (r < 0)
2612                 return r;
2613
2614         a = message_extend_body(m, align, 0, false);
2615         if (!a)
2616                 return -ENOMEM;
2617
2618         part = message_append_part(m);
2619         if (!part)
2620                 return -ENOMEM;
2621
2622         part->memfd = copy_fd;
2623         part->sealed = true;
2624         part->size = size;
2625         copy_fd = -1;
2626
2627         m->header->body_size += size;
2628         message_extend_containers(m, size);
2629
2630         return sd_bus_message_close_container(m);
2631 }
2632
2633 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
2634         _cleanup_close_ int copy_fd = -1;
2635         struct bus_body_part *part;
2636         struct bus_container *c;
2637         uint64_t size;
2638         void *a;
2639         int r;
2640
2641         assert_return(m, -EINVAL);
2642         assert_return(memfd >= 0, -EINVAL);
2643         assert_return(!m->sealed, -EPERM);
2644         assert_return(!m->poisoned, -ESTALE);
2645
2646         r = memfd_set_sealed(memfd);
2647         if (r < 0)
2648                 return r;
2649
2650         copy_fd = dup(memfd);
2651         if (copy_fd < 0)
2652                 return copy_fd;
2653
2654         r = memfd_get_size(memfd, &size);
2655         if (r < 0)
2656                 return r;
2657
2658         /* We require this to be NUL terminated */
2659         if (size == 0)
2660                 return -EINVAL;
2661
2662         if (size > (uint64_t) (uint32_t) -1)
2663                 return -EINVAL;
2664
2665         c = message_get_container(m);
2666         if (c->signature && c->signature[c->index]) {
2667                 /* Container signature is already set */
2668
2669                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2670                         return -ENXIO;
2671         } else {
2672                 char *e;
2673
2674                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2675                 if (c->enclosing != 0)
2676                         return -ENXIO;
2677
2678                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2679                 if (!e) {
2680                         m->poisoned = true;
2681                         return -ENOMEM;
2682                 }
2683         }
2684
2685         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2686                 a = message_extend_body(m, 4, 4, false);
2687                 if (!a)
2688                         return -ENOMEM;
2689
2690                 *(uint32_t*) a = size - 1;
2691         }
2692
2693         part = message_append_part(m);
2694         if (!part)
2695                 return -ENOMEM;
2696
2697         part->memfd = copy_fd;
2698         part->sealed = true;
2699         part->size = size;
2700         copy_fd = -1;
2701
2702         m->header->body_size += size;
2703         message_extend_containers(m, size);
2704
2705         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2706                 r = message_add_offset(m, m->header->body_size);
2707                 if (r < 0) {
2708                         m->poisoned = true;
2709                         return -ENOMEM;
2710                 }
2711         }
2712
2713         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2714                 c->index++;
2715
2716         return 0;
2717 }
2718
2719 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2720         char **i;
2721         int r;
2722
2723         assert_return(m, -EINVAL);
2724         assert_return(!m->sealed, -EPERM);
2725         assert_return(!m->poisoned, -ESTALE);
2726
2727         r = sd_bus_message_open_container(m, 'a', "s");
2728         if (r < 0)
2729                 return r;
2730
2731         STRV_FOREACH(i, l) {
2732                 r = sd_bus_message_append_basic(m, 's', *i);
2733                 if (r < 0)
2734                         return r;
2735         }
2736
2737         return sd_bus_message_close_container(m);
2738 }
2739
2740 static int bus_message_close_header(sd_bus_message *m) {
2741         uint8_t *a;
2742         size_t sz, i;
2743
2744         assert(m);
2745
2746         if (!BUS_MESSAGE_IS_GVARIANT(m))
2747                 return 0;
2748
2749         if (m->n_header_offsets < 1)
2750                 return 0;
2751
2752         assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2753
2754         sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2755
2756         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2757         if (!a)
2758                 return -ENOMEM;
2759
2760         for (i = 0; i < m->n_header_offsets; i++)
2761                 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2762
2763         return 0;
2764 }
2765
2766 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2767         struct bus_body_part *part;
2768         size_t l, a;
2769         unsigned i;
2770         int r;
2771
2772         assert(m);
2773
2774         if (m->sealed)
2775                 return -EPERM;
2776
2777         if (m->n_containers > 0)
2778                 return -EBADMSG;
2779
2780         if (m->poisoned)
2781                 return -ESTALE;
2782
2783         /* In vtables the return signature of method calls is listed,
2784          * let's check if they match if this is a response */
2785         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2786             m->enforced_reply_signature &&
2787             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2788                 return -ENOMSG;
2789
2790         /* If gvariant marshalling is used we need to close the body structure */
2791         r = bus_message_close_struct(m, &m->root_container, false);
2792         if (r < 0)
2793                 return r;
2794
2795         /* If there's a non-trivial signature set, then add it in here */
2796         if (!isempty(m->root_container.signature)) {
2797                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2798                 if (r < 0)
2799                         return r;
2800         }
2801
2802         if (m->n_fds > 0) {
2803                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2804                 if (r < 0)
2805                         return r;
2806         }
2807
2808         r = bus_message_close_header(m);
2809         if (r < 0)
2810                 return r;
2811
2812         m->header->serial = (uint32_t) cookie;
2813         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2814
2815         /* Add padding at the end of the fields part, since we know
2816          * the body needs to start at an 8 byte alignment. We made
2817          * sure we allocated enough space for this, so all we need to
2818          * do here is to zero it out. */
2819         l = BUS_MESSAGE_FIELDS_SIZE(m);
2820         a = ALIGN8(l) - l;
2821         if (a > 0)
2822                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2823
2824         /* If this is something we can send as memfd, then let's seal
2825         the memfd now. Note that we can send memfds as payload only
2826         for directed messages, and not for broadcasts. */
2827         if (m->destination && m->bus->use_memfd) {
2828                 MESSAGE_FOREACH_PART(part, i, m)
2829                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2830                                 uint64_t sz;
2831
2832                                 /* Try to seal it if that makes
2833                                  * sense. First, unmap our own map to
2834                                  * make sure we don't keep it busy. */
2835                                 bus_body_part_unmap(part);
2836
2837                                 /* Then, sync up real memfd size */
2838                                 sz = part->size;
2839                                 r = memfd_set_size(part->memfd, sz);
2840                                 if (r < 0)
2841                                         return r;
2842
2843                                 /* Finally, try to seal */
2844                                 if (memfd_set_sealed(part->memfd) >= 0)
2845                                         part->sealed = true;
2846                         }
2847         }
2848
2849         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2850         m->root_container.index = 0;
2851         m->root_container.offset_index = 0;
2852         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2853
2854         m->sealed = true;
2855
2856         return 0;
2857 }
2858
2859 int bus_body_part_map(struct bus_body_part *part) {
2860         void *p;
2861         size_t psz;
2862
2863         assert_se(part);
2864
2865         if (part->data)
2866                 return 0;
2867
2868         if (part->size <= 0)
2869                 return 0;
2870
2871         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2872         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2873                 static const uint8_t zeroes[7] = { };
2874                 part->data = (void*) zeroes;
2875                 return 0;
2876         }
2877
2878         psz = PAGE_ALIGN(part->size);
2879
2880         if (part->memfd >= 0)
2881                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
2882         else if (part->is_zero)
2883                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2884         else
2885                 return -EINVAL;
2886
2887         if (p == MAP_FAILED)
2888                 return -errno;
2889
2890         part->mapped = psz;
2891         part->data = p;
2892         part->munmap_this = true;
2893
2894         return 0;
2895 }
2896
2897 void bus_body_part_unmap(struct bus_body_part *part) {
2898
2899         assert_se(part);
2900
2901         if (part->memfd < 0)
2902                 return;
2903
2904         if (!part->data)
2905                 return;
2906
2907         if (!part->munmap_this)
2908                 return;
2909
2910         assert_se(munmap(part->data, part->mapped) == 0);
2911
2912         part->data = NULL;
2913         part->mapped = 0;
2914         part->munmap_this = false;
2915
2916         return;
2917 }
2918
2919 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2920         size_t k, start, end;
2921
2922         assert(rindex);
2923         assert(align > 0);
2924
2925         start = ALIGN_TO((size_t) *rindex, align);
2926         end = start + nbytes;
2927
2928         if (end > sz)
2929                 return -EBADMSG;
2930
2931         /* Verify that padding is 0 */
2932         for (k = *rindex; k < start; k++)
2933                 if (((const uint8_t*) p)[k] != 0)
2934                         return -EBADMSG;
2935
2936         if (r)
2937                 *r = (uint8_t*) p + start;
2938
2939         *rindex = end;
2940
2941         return 1;
2942 }
2943
2944 static bool message_end_of_signature(sd_bus_message *m) {
2945         struct bus_container *c;
2946
2947         assert(m);
2948
2949         c = message_get_container(m);
2950         return !c->signature || c->signature[c->index] == 0;
2951 }
2952
2953 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2954         struct bus_container *c;
2955
2956         assert(m);
2957
2958         c = message_get_container(m);
2959         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2960                 return false;
2961
2962         if (BUS_MESSAGE_IS_GVARIANT(m))
2963                 return index >= c->end;
2964         else {
2965                 assert(c->array_size);
2966                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2967         }
2968 }
2969
2970 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2971         assert_return(m, -EINVAL);
2972         assert_return(m->sealed, -EPERM);
2973
2974         if (complete && m->n_containers > 0)
2975                 return false;
2976
2977         if (message_end_of_signature(m))
2978                 return true;
2979
2980         if (message_end_of_array(m, m->rindex))
2981                 return true;
2982
2983         return false;
2984 }
2985
2986 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2987         struct bus_body_part *part;
2988         size_t begin;
2989         int r;
2990
2991         assert(m);
2992
2993         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2994                 part = m->cached_rindex_part;
2995                 begin = m->cached_rindex_part_begin;
2996         } else {
2997                 part = &m->body;
2998                 begin = 0;
2999         }
3000
3001         while (part) {
3002                 if (index < begin)
3003                         return NULL;
3004
3005                 if (index + sz <= begin + part->size) {
3006
3007                         r = bus_body_part_map(part);
3008                         if (r < 0)
3009                                 return NULL;
3010
3011                         if (p)
3012                                 *p = (uint8_t*) part->data + index - begin;
3013
3014                         m->cached_rindex_part = part;
3015                         m->cached_rindex_part_begin = begin;
3016
3017                         return part;
3018                 }
3019
3020                 begin += part->size;
3021                 part = part->next;
3022         }
3023
3024         return NULL;
3025 }
3026
3027 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3028         int r;
3029
3030         assert(m);
3031         assert(c);
3032         assert(rindex);
3033
3034         if (!BUS_MESSAGE_IS_GVARIANT(m))
3035                 return 0;
3036
3037         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3038                 int sz;
3039
3040                 sz = bus_gvariant_get_size(c->signature);
3041                 if (sz < 0) {
3042                         int alignment;
3043
3044                         if (c->offset_index+1 >= c->n_offsets)
3045                                 goto end;
3046
3047                         /* Variable-size array */
3048
3049                         alignment = bus_gvariant_get_alignment(c->signature);
3050                         assert(alignment > 0);
3051
3052                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3053                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3054                 } else {
3055
3056                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3057                                 goto end;
3058
3059                         /* Fixed-size array */
3060                         *rindex = c->begin + (c->offset_index+1) * sz;
3061                         c->item_size = sz;
3062                 }
3063
3064                 c->offset_index++;
3065
3066         } else if (c->enclosing == 0 ||
3067                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3068                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3069
3070                 int alignment;
3071                 size_t n, j;
3072
3073                 if (c->offset_index+1 >= c->n_offsets)
3074                         goto end;
3075
3076                 r = signature_element_length(c->signature + c->index, &n);
3077                 if (r < 0)
3078                         return r;
3079
3080                 r = signature_element_length(c->signature + c->index + n, &j);
3081                 if (r < 0)
3082                         return r;
3083                 else {
3084                         char t[j+1];
3085                         memcpy(t, c->signature + c->index + n, j);
3086                         t[j] = 0;
3087
3088                         alignment = bus_gvariant_get_alignment(t);
3089                 }
3090
3091                 assert(alignment > 0);
3092
3093                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3094                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3095
3096                 c->offset_index++;
3097
3098         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3099                 goto end;
3100         else
3101                 assert_not_reached("Unknown container type");
3102
3103         return 0;
3104
3105 end:
3106         /* Reached the end */
3107         *rindex = c->end;
3108         c->item_size = 0;
3109         return 0;
3110 }
3111
3112
3113 static int message_peek_body(
3114                 sd_bus_message *m,
3115                 size_t *rindex,
3116                 size_t align,
3117                 size_t nbytes,
3118                 void **ret) {
3119
3120         size_t k, start, end, padding;
3121         struct bus_body_part *part;
3122         uint8_t *q;
3123
3124         assert(m);
3125         assert(rindex);
3126         assert(align > 0);
3127
3128         start = ALIGN_TO((size_t) *rindex, align);
3129         padding = start - *rindex;
3130         end = start + nbytes;
3131
3132         if (end > BUS_MESSAGE_BODY_SIZE(m))
3133                 return -EBADMSG;
3134
3135         part = find_part(m, *rindex, padding, (void**) &q);
3136         if (!part)
3137                 return -EBADMSG;
3138
3139         if (q) {
3140                 /* Verify padding */
3141                 for (k = 0; k < padding; k++)
3142                         if (q[k] != 0)
3143                                 return -EBADMSG;
3144         }
3145
3146         part = find_part(m, start, nbytes, (void**) &q);
3147         if (!part || (nbytes > 0 && !q))
3148                 return -EBADMSG;
3149
3150         *rindex = end;
3151
3152         if (ret)
3153                 *ret = q;
3154
3155         return 0;
3156 }
3157
3158 static bool validate_nul(const char *s, size_t l) {
3159
3160         /* Check for NUL chars in the string */
3161         if (memchr(s, 0, l))
3162                 return false;
3163
3164         /* Check for NUL termination */
3165         if (s[l] != 0)
3166                 return false;
3167
3168         return true;
3169 }
3170
3171 static bool validate_string(const char *s, size_t l) {
3172
3173         if (!validate_nul(s, l))
3174                 return false;
3175
3176         /* Check if valid UTF8 */
3177         if (!utf8_is_valid(s))
3178                 return false;
3179
3180         return true;
3181 }
3182
3183 static bool validate_signature(const char *s, size_t l) {
3184
3185         if (!validate_nul(s, l))
3186                 return false;
3187
3188         /* Check if valid signature */
3189         if (!signature_is_valid(s, true))
3190                 return false;
3191
3192         return true;
3193 }
3194
3195 static bool validate_object_path(const char *s, size_t l) {
3196
3197         if (!validate_nul(s, l))
3198                 return false;
3199
3200         if (!object_path_is_valid(s))
3201                 return false;
3202
3203         return true;
3204 }
3205
3206 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {