]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-message.c
bus: map sealed memfds as MAP_PRIVATE
[thirdparty/systemd.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
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
38 #include "bus-util.h"
39
40 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
41
42 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
43
44 if (p == NULL)
45 return NULL;
46
47 if (old_base == new_base)
48 return (void*) p;
49
50 if ((uint8_t*) p < (uint8_t*) old_base)
51 return (void*) p;
52
53 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (void*) p;
55
56 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 }
58
59 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
60 assert(m);
61 assert(part);
62
63 if (part->memfd >= 0) {
64 /* If we can reuse the memfd, try that. For that it
65 * can't be sealed yet. */
66
67 if (!part->sealed)
68 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
69 else {
70 if (part->mapped > 0)
71 assert_se(munmap(part->data, part->mapped) == 0);
72
73 safe_close(part->memfd);
74 }
75
76 } else if (part->munmap_this)
77 munmap(part->data, part->mapped);
78 else if (part->free_this)
79 free(part->data);
80
81 if (part != &m->body)
82 free(part);
83 }
84
85 static void message_reset_parts(sd_bus_message *m) {
86 struct bus_body_part *part;
87
88 assert(m);
89
90 part = &m->body;
91 while (m->n_body_parts > 0) {
92 struct bus_body_part *next = part->next;
93 message_free_part(m, part);
94 part = next;
95 m->n_body_parts--;
96 }
97
98 m->body_end = NULL;
99
100 m->cached_rindex_part = NULL;
101 m->cached_rindex_part_begin = 0;
102 }
103
104 static void message_reset_containers(sd_bus_message *m) {
105 unsigned i;
106
107 assert(m);
108
109 for (i = 0; i < m->n_containers; i++) {
110 free(m->containers[i].signature);
111 free(m->containers[i].offsets);
112 }
113
114 free(m->containers);
115 m->containers = NULL;
116
117 m->n_containers = m->containers_allocated = 0;
118 m->root_container.index = 0;
119 }
120
121 static void message_free(sd_bus_message *m) {
122 assert(m);
123
124 if (m->free_header)
125 free(m->header);
126
127 message_reset_parts(m);
128
129 if (m->free_kdbus)
130 free(m->kdbus);
131
132 if (m->release_kdbus) {
133 uint64_t off;
134
135 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
136 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
137 }
138
139 sd_bus_unref(m->bus);
140
141 if (m->free_fds) {
142 close_many(m->fds, m->n_fds);
143 free(m->fds);
144 }
145
146 if (m->iovec != m->iovec_fixed)
147 free(m->iovec);
148
149 message_reset_containers(m);
150 free(m->root_container.signature);
151 free(m->root_container.offsets);
152
153 free(m->root_container.peeked_signature);
154
155 bus_creds_done(&m->creds);
156 free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
160 void *op, *np;
161 size_t old_size, new_size, start;
162
163 assert(m);
164
165 if (m->poisoned)
166 return NULL;
167
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
171
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
174
175 if (new_size > (size_t) ((uint32_t) -1))
176 goto poison;
177
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
180 if (!np)
181 goto poison;
182 } else {
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
185 * dynamic data */
186
187 np = malloc(ALIGN8(new_size));
188 if (!np)
189 goto poison;
190
191 memcpy(np, m->header, sizeof(struct bus_header));
192 }
193
194 /* Zero out padding */
195 if (start > old_size)
196 memzero((uint8_t*) np + old_size, start - old_size);
197
198 op = m->header;
199 m->header = np;
200 m->header->fields_size = new_size - sizeof(struct bus_header);
201
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210 m->free_header = true;
211
212 if (add_offset) {
213 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
214 goto poison;
215
216 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
217 }
218
219 return (uint8_t*) np + start;
220
221 poison:
222 m->poisoned = true;
223 return NULL;
224 }
225
226 static int message_append_field_string(
227 sd_bus_message *m,
228 uint8_t h,
229 char type,
230 const char *s,
231 const char **ret) {
232
233 size_t l;
234 uint8_t *p;
235
236 assert(m);
237
238 /* dbus1 doesn't allow strings over 32bit, let's enforce this
239 * globally, to not risk convertability */
240 l = strlen(s);
241 if (l > (size_t) (uint32_t) -1)
242 return -EINVAL;
243
244 /* Signature "(yv)" where the variant contains "s" */
245
246 if (BUS_MESSAGE_IS_GVARIANT(m)) {
247
248 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
249 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
250 if (!p)
251 return -ENOMEM;
252
253 p[0] = h;
254 memzero(p+1, 7);
255 memcpy(p+8, s, l);
256 p[8+l] = 0;
257 p[8+l+1] = 0;
258 p[8+l+2] = type;
259
260 if (ret)
261 *ret = (char*) p + 8;
262
263 } else {
264 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
265 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
266 if (!p)
267 return -ENOMEM;
268
269 p[0] = h;
270 p[1] = 1;
271 p[2] = type;
272 p[3] = 0;
273
274 ((uint32_t*) p)[1] = l;
275 memcpy(p + 8, s, l + 1);
276
277 if (ret)
278 *ret = (char*) p + 8;
279 }
280
281 return 0;
282 }
283
284 static int message_append_field_signature(
285 sd_bus_message *m,
286 uint8_t h,
287 const char *s,
288 const char **ret) {
289
290 size_t l;
291 uint8_t *p;
292
293 assert(m);
294
295 /* dbus1 doesn't allow signatures over 32bit, let's enforce
296 * this globally, to not risk convertability */
297 l = strlen(s);
298 if (l > 255)
299 return -EINVAL;
300
301 /* Signature "(yv)" where the variant contains "g" */
302
303 if (BUS_MESSAGE_IS_GVARIANT(m))
304 /* For gvariant the serialization is the same as for normal strings */
305 return message_append_field_string(m, h, 'g', s, ret);
306 else {
307 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
308 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
309 if (!p)
310 return -ENOMEM;
311
312 p[0] = h;
313 p[1] = 1;
314 p[2] = SD_BUS_TYPE_SIGNATURE;
315 p[3] = 0;
316 p[4] = l;
317 memcpy(p + 5, s, l + 1);
318
319 if (ret)
320 *ret = (const char*) p + 5;
321 }
322
323 return 0;
324 }
325
326 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
327 uint8_t *p;
328
329 assert(m);
330
331 if (BUS_MESSAGE_IS_GVARIANT(m)) {
332 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
333
334 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
335 if (!p)
336 return -ENOMEM;
337
338 p[0] = h;
339 memzero(p+1, 7);
340 *((uint32_t*) (p + 8)) = x;
341 p[12] = 0;
342 p[13] = 'u';
343 } else {
344 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
345 p = message_extend_fields(m, 8, 4 + 4, false);
346 if (!p)
347 return -ENOMEM;
348
349 p[0] = h;
350 p[1] = 1;
351 p[2] = SD_BUS_TYPE_UINT32;
352 p[3] = 0;
353
354 ((uint32_t*) p)[1] = x;
355 }
356
357 return 0;
358 }
359
360 int bus_message_from_header(
361 sd_bus *bus,
362 void *buffer,
363 size_t length,
364 int *fds,
365 unsigned n_fds,
366 const struct ucred *ucred,
367 const char *label,
368 size_t extra,
369 sd_bus_message **ret) {
370
371 sd_bus_message *m;
372 struct bus_header *h;
373 size_t a, label_sz;
374
375 assert(bus);
376 assert(buffer || length <= 0);
377 assert(fds || n_fds <= 0);
378 assert(ret);
379
380 if (length < sizeof(struct bus_header))
381 return -EBADMSG;
382
383 h = buffer;
384 if (h->version != 1 &&
385 h->version != 2)
386 return -EBADMSG;
387
388 if (h->serial == 0)
389 return -EBADMSG;
390
391 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
392 return -EBADMSG;
393
394 if (h->endian != BUS_LITTLE_ENDIAN &&
395 h->endian != BUS_BIG_ENDIAN)
396 return -EBADMSG;
397
398 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
399
400 if (label) {
401 label_sz = strlen(label);
402 a += label_sz + 1;
403 }
404
405 m = malloc0(a);
406 if (!m)
407 return -ENOMEM;
408
409 m->n_ref = 1;
410 m->sealed = true;
411 m->header = h;
412 m->fds = fds;
413 m->n_fds = n_fds;
414
415 if (ucred) {
416 m->creds.uid = ucred->uid;
417 m->creds.pid = ucred->pid;
418 m->creds.gid = ucred->gid;
419 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
420 }
421
422 if (label) {
423 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
424 memcpy(m->creds.label, label, label_sz + 1);
425
426 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
427 }
428
429 m->bus = sd_bus_ref(bus);
430 *ret = m;
431
432 return 0;
433 }
434
435 int bus_message_from_malloc(
436 sd_bus *bus,
437 void *buffer,
438 size_t length,
439 int *fds,
440 unsigned n_fds,
441 const struct ucred *ucred,
442 const char *label,
443 sd_bus_message **ret) {
444
445 sd_bus_message *m;
446 size_t sz;
447 int r;
448
449 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
450 if (r < 0)
451 return r;
452
453 if (length != BUS_MESSAGE_SIZE(m)) {
454 r = -EBADMSG;
455 goto fail;
456 }
457
458 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
459 if (sz > 0) {
460 m->n_body_parts = 1;
461 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
462 m->body.size = sz;
463 m->body.sealed = true;
464 m->body.memfd = -1;
465 }
466
467 m->n_iovec = 1;
468 m->iovec = m->iovec_fixed;
469 m->iovec[0].iov_base = buffer;
470 m->iovec[0].iov_len = length;
471
472 r = bus_message_parse_fields(m);
473 if (r < 0)
474 goto fail;
475
476 /* We take possession of the memory and fds now */
477 m->free_header = true;
478 m->free_fds = true;
479
480 *ret = m;
481 return 0;
482
483 fail:
484 message_free(m);
485 return r;
486 }
487
488 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
489 sd_bus_message *m;
490
491 assert(bus);
492
493 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
494 if (!m)
495 return NULL;
496
497 m->n_ref = 1;
498 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
499 m->header->endian = BUS_NATIVE_ENDIAN;
500 m->header->type = type;
501 m->header->version = bus ? bus->message_version : 1;
502 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
503 m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
504 m->bus = sd_bus_ref(bus);
505
506 return m;
507 }
508
509 _public_ int sd_bus_message_new_signal(
510 sd_bus *bus,
511 sd_bus_message **m,
512 const char *path,
513 const char *interface,
514 const char *member) {
515
516 sd_bus_message *t;
517 int r;
518
519 assert_return(bus, -ENOTCONN);
520 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
521 assert_return(object_path_is_valid(path), -EINVAL);
522 assert_return(interface_name_is_valid(interface), -EINVAL);
523 assert_return(member_name_is_valid(member), -EINVAL);
524 assert_return(m, -EINVAL);
525
526 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
527 if (!t)
528 return -ENOMEM;
529
530 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
531
532 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
533 if (r < 0)
534 goto fail;
535 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
536 if (r < 0)
537 goto fail;
538 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
539 if (r < 0)
540 goto fail;
541
542 *m = t;
543 return 0;
544
545 fail:
546 sd_bus_message_unref(t);
547 return r;
548 }
549
550 _public_ int sd_bus_message_new_method_call(
551 sd_bus *bus,
552 sd_bus_message **m,
553 const char *destination,
554 const char *path,
555 const char *interface,
556 const char *member) {
557
558 sd_bus_message *t;
559 int r;
560
561 assert_return(bus, -ENOTCONN);
562 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
563 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
564 assert_return(object_path_is_valid(path), -EINVAL);
565 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
566 assert_return(member_name_is_valid(member), -EINVAL);
567 assert_return(m, -EINVAL);
568
569 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
570 if (!t)
571 return -ENOMEM;
572
573 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
574 if (r < 0)
575 goto fail;
576 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
577 if (r < 0)
578 goto fail;
579
580 if (interface) {
581 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
582 if (r < 0)
583 goto fail;
584 }
585
586 if (destination) {
587 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
588 if (r < 0)
589 goto fail;
590 }
591
592 *m = t;
593 return 0;
594
595 fail:
596 message_free(t);
597 return r;
598 }
599
600 static int message_new_reply(
601 sd_bus_message *call,
602 uint8_t type,
603 sd_bus_message **m) {
604
605 sd_bus_message *t;
606 int r;
607
608 assert_return(call, -EINVAL);
609 assert_return(call->sealed, -EPERM);
610 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
611 assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
612 assert_return(m, -EINVAL);
613
614 t = message_new(call->bus, type);
615 if (!t)
616 return -ENOMEM;
617
618 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
619 t->reply_cookie = BUS_MESSAGE_COOKIE(call);
620
621 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
622 if (r < 0)
623 goto fail;
624
625 if (call->sender) {
626 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
627 if (r < 0)
628 goto fail;
629 }
630
631 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
632 t->enforced_reply_signature = call->enforced_reply_signature;
633
634 *m = t;
635 return 0;
636
637 fail:
638 message_free(t);
639 return r;
640 }
641
642 _public_ int sd_bus_message_new_method_return(
643 sd_bus_message *call,
644 sd_bus_message **m) {
645
646 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
647 }
648
649 _public_ int sd_bus_message_new_method_error(
650 sd_bus_message *call,
651 sd_bus_message **m,
652 const sd_bus_error *e) {
653
654 sd_bus_message *t;
655 int r;
656
657 assert_return(sd_bus_error_is_set(e), -EINVAL);
658 assert_return(m, -EINVAL);
659
660 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
661 if (r < 0)
662 return r;
663
664 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
665 if (r < 0)
666 goto fail;
667
668 if (e->message) {
669 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
670 if (r < 0)
671 goto fail;
672 }
673
674 t->error._need_free = -1;
675
676 *m = t;
677 return 0;
678
679 fail:
680 message_free(t);
681 return r;
682 }
683
684 _public_ int sd_bus_message_new_method_errorf(
685 sd_bus_message *call,
686 sd_bus_message **m,
687 const char *name,
688 const char *format,
689 ...) {
690
691 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
692 va_list ap;
693
694 assert_return(name, -EINVAL);
695 assert_return(m, -EINVAL);
696
697 va_start(ap, format);
698 bus_error_setfv(&error, name, format, ap);
699 va_end(ap);
700
701 return sd_bus_message_new_method_error(call, m, &error);
702 }
703
704 _public_ int sd_bus_message_new_method_errno(
705 sd_bus_message *call,
706 sd_bus_message **m,
707 int error,
708 const sd_bus_error *p) {
709
710 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
711
712 if (sd_bus_error_is_set(p))
713 return sd_bus_message_new_method_error(call, m, p);
714
715 sd_bus_error_set_errno(&berror, error);
716
717 return sd_bus_message_new_method_error(call, m, &berror);
718 }
719
720 _public_ int sd_bus_message_new_method_errnof(
721 sd_bus_message *call,
722 sd_bus_message **m,
723 int error,
724 const char *format,
725 ...) {
726
727 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
728 va_list ap;
729
730 va_start(ap, format);
731 bus_error_set_errnofv(&berror, error, format, ap);
732 va_end(ap);
733
734 return sd_bus_message_new_method_error(call, m, &berror);
735 }
736
737 int bus_message_new_synthetic_error(
738 sd_bus *bus,
739 uint64_t cookie,
740 const sd_bus_error *e,
741 sd_bus_message **m) {
742
743 sd_bus_message *t;
744 int r;
745
746 assert(bus);
747 assert(sd_bus_error_is_set(e));
748 assert(m);
749
750 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
751 if (!t)
752 return -ENOMEM;
753
754 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
755 t->reply_cookie = cookie;
756
757 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
758 if (r < 0)
759 goto fail;
760
761 if (bus && bus->unique_name) {
762 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
763 if (r < 0)
764 goto fail;
765 }
766
767 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
768 if (r < 0)
769 goto fail;
770
771 if (e->message) {
772 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
773 if (r < 0)
774 goto fail;
775 }
776
777 t->error._need_free = -1;
778
779 *m = t;
780 return 0;
781
782 fail:
783 message_free(t);
784 return r;
785 }
786
787 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
788 assert_return(m, NULL);
789
790 assert(m->n_ref > 0);
791 m->n_ref++;
792
793 return m;
794 }
795
796 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
797
798 if (!m)
799 return NULL;
800
801 assert(m->n_ref > 0);
802 m->n_ref--;
803
804 if (m->n_ref > 0)
805 return NULL;
806
807 message_free(m);
808 return NULL;
809 }
810
811 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
812 assert_return(m, -EINVAL);
813 assert_return(type, -EINVAL);
814
815 *type = m->header->type;
816 return 0;
817 }
818
819 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
820 assert_return(m, -EINVAL);
821 assert_return(cookie, -EINVAL);
822 assert_return(m->header->serial != 0, -ENODATA);
823
824 *cookie = BUS_MESSAGE_COOKIE(m);
825 return 0;
826 }
827
828 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
829 assert_return(m, -EINVAL);
830 assert_return(cookie, -EINVAL);
831 assert_return(m->reply_cookie != 0, -ENODATA);
832
833 *cookie = m->reply_cookie;
834 return 0;
835 }
836
837 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
838 assert_return(m, -EINVAL);
839
840 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
841 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
842 }
843
844 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
845 assert_return(m, -EINVAL);
846
847 return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
848 }
849
850 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
851 assert_return(m, NULL);
852
853 return m->path;
854 }
855
856 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
857 assert_return(m, NULL);
858
859 return m->interface;
860 }
861
862 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
863 assert_return(m, NULL);
864
865 return m->member;
866 }
867
868 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
869 assert_return(m, NULL);
870
871 return m->destination;
872 }
873
874 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
875 assert_return(m, NULL);
876
877 return m->sender;
878 }
879
880 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
881 assert_return(m, NULL);
882 assert_return(sd_bus_error_is_set(&m->error), NULL);
883
884 return &m->error;
885 }
886
887 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
888 assert_return(m, -EINVAL);
889 assert_return(usec, -EINVAL);
890
891 if (m->monotonic <= 0)
892 return -ENODATA;
893
894 *usec = m->monotonic;
895 return 0;
896 }
897
898 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
899 assert_return(m, -EINVAL);
900 assert_return(usec, -EINVAL);
901
902 if (m->realtime <= 0)
903 return -ENODATA;
904
905 *usec = m->realtime;
906 return 0;
907 }
908
909 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
910 assert_return(m, -EINVAL);
911 assert_return(seqnum, -EINVAL);
912
913 if (m->seqnum <= 0)
914 return -ENODATA;
915
916 *seqnum = m->seqnum;
917 return 0;
918 }
919
920 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
921 assert_return(m, NULL);
922
923 if (m->creds.mask == 0)
924 return NULL;
925
926 return &m->creds;
927 }
928
929 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
930 const char *interface,
931 const char *member) {
932 assert_return(m, -EINVAL);
933
934 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
935 return 0;
936
937 if (interface && (!m->interface || !streq(m->interface, interface)))
938 return 0;
939
940 if (member && (!m->member || !streq(m->member, member)))
941 return 0;
942
943 return 1;
944 }
945
946 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
947 const char *interface,
948 const char *member) {
949 assert_return(m, -EINVAL);
950
951 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
952 return 0;
953
954 if (interface && (!m->interface || !streq(m->interface, interface)))
955 return 0;
956
957 if (member && (!m->member || !streq(m->member, member)))
958 return 0;
959
960 return 1;
961 }
962
963 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
964 assert_return(m, -EINVAL);
965
966 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
967 return 0;
968
969 if (name && (!m->error.name || !streq(m->error.name, name)))
970 return 0;
971
972 return 1;
973 }
974
975 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
976 assert_return(m, -EINVAL);
977 assert_return(!m->sealed, -EPERM);
978 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
979
980 if (b)
981 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
982 else
983 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
984
985 return 0;
986 }
987
988 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
989 assert_return(m, -EINVAL);
990 assert_return(!m->sealed, -EPERM);
991
992 if (b)
993 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
994 else
995 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
996
997 return 0;
998 }
999
1000 static struct bus_container *message_get_container(sd_bus_message *m) {
1001 assert(m);
1002
1003 if (m->n_containers == 0)
1004 return &m->root_container;
1005
1006 assert(m->containers);
1007 return m->containers + m->n_containers - 1;
1008 }
1009
1010 struct bus_body_part *message_append_part(sd_bus_message *m) {
1011 struct bus_body_part *part;
1012
1013 assert(m);
1014
1015 if (m->poisoned)
1016 return NULL;
1017
1018 if (m->n_body_parts <= 0) {
1019 part = &m->body;
1020 zero(*part);
1021 } else {
1022 assert(m->body_end);
1023
1024 part = new0(struct bus_body_part, 1);
1025 if (!part) {
1026 m->poisoned = true;
1027 return NULL;
1028 }
1029
1030 m->body_end->next = part;
1031 }
1032
1033 part->memfd = -1;
1034 m->body_end = part;
1035 m->n_body_parts ++;
1036
1037 return part;
1038 }
1039
1040 static void part_zero(struct bus_body_part *part, size_t sz) {
1041 assert(part);
1042 assert(sz > 0);
1043 assert(sz < 8);
1044
1045 /* All other fields can be left in their defaults */
1046 assert(!part->data);
1047 assert(part->memfd < 0);
1048
1049 part->size = sz;
1050 part->is_zero = true;
1051 part->sealed = true;
1052 }
1053
1054 static int part_make_space(
1055 struct sd_bus_message *m,
1056 struct bus_body_part *part,
1057 size_t sz,
1058 void **q) {
1059
1060 void *n;
1061 int r;
1062
1063 assert(m);
1064 assert(part);
1065 assert(!part->sealed);
1066
1067 if (m->poisoned)
1068 return -ENOMEM;
1069
1070 if (!part->data && part->memfd < 0)
1071 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1072
1073 if (part->memfd >= 0) {
1074
1075 if (part->allocated == 0 || sz > part->allocated) {
1076 uint64_t new_allocated;
1077
1078 new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1079 r = ftruncate(part->memfd, new_allocated);
1080 if (r < 0) {
1081 m->poisoned = true;
1082 return -errno;
1083 }
1084
1085 part->allocated = new_allocated;
1086 }
1087
1088 if (!part->data || sz > part->mapped) {
1089 size_t psz;
1090
1091 psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1092 if (part->mapped <= 0)
1093 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1094 else
1095 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1096
1097 if (n == MAP_FAILED) {
1098 m->poisoned = true;
1099 return -errno;
1100 }
1101
1102 part->mapped = psz;
1103 part->data = n;
1104 }
1105
1106 part->munmap_this = true;
1107 } else {
1108 if (part->allocated == 0 || sz > part->allocated) {
1109 size_t new_allocated;
1110
1111 new_allocated = sz > 0 ? 2 * sz : 64;
1112 n = realloc(part->data, new_allocated);
1113 if (!n) {
1114 m->poisoned = true;
1115 return -ENOMEM;
1116 }
1117
1118 part->data = n;
1119 part->allocated = new_allocated;
1120 part->free_this = true;
1121 }
1122 }
1123
1124 if (q)
1125 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1126
1127 part->size = sz;
1128 return 0;
1129 }
1130
1131 static int message_add_offset(sd_bus_message *m, size_t offset) {
1132 struct bus_container *c;
1133
1134 assert(m);
1135 assert(BUS_MESSAGE_IS_GVARIANT(m));
1136
1137 /* Add offset to current container, unless this is the first
1138 * item in it, which will have the 0 offset, which we can
1139 * ignore. */
1140 c = message_get_container(m);
1141
1142 if (!c->need_offsets)
1143 return 0;
1144
1145 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1146 return -ENOMEM;
1147
1148 c->offsets[c->n_offsets++] = offset;
1149 return 0;
1150 }
1151
1152 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1153 struct bus_container *c;
1154
1155 assert(m);
1156
1157 if (expand <= 0)
1158 return;
1159
1160 /* Update counters */
1161 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1162
1163 if (c->array_size)
1164 *c->array_size += expand;
1165 }
1166 }
1167
1168 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1169 size_t start_body, end_body, padding, added;
1170 void *p;
1171 int r;
1172
1173 assert(m);
1174 assert(align > 0);
1175 assert(!m->sealed);
1176
1177 if (m->poisoned)
1178 return NULL;
1179
1180 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1181 end_body = start_body + sz;
1182
1183 padding = start_body - m->header->body_size;
1184 added = padding + sz;
1185
1186 /* Check for 32bit overflows */
1187 if (end_body > (size_t) ((uint32_t) -1)) {
1188 m->poisoned = true;
1189 return NULL;
1190 }
1191
1192 if (added > 0) {
1193 struct bus_body_part *part = NULL;
1194 bool add_new_part;
1195
1196 add_new_part =
1197 m->n_body_parts <= 0 ||
1198 m->body_end->sealed ||
1199 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1200
1201 if (add_new_part) {
1202 if (padding > 0) {
1203 part = message_append_part(m);
1204 if (!part)
1205 return NULL;
1206
1207 part_zero(part, padding);
1208 }
1209
1210 part = message_append_part(m);
1211 if (!part)
1212 return NULL;
1213
1214 r = part_make_space(m, part, sz, &p);
1215 if (r < 0)
1216 return NULL;
1217 } else {
1218 struct bus_container *c;
1219 void *op;
1220 size_t os, start_part, end_part;
1221
1222 part = m->body_end;
1223 op = part->data;
1224 os = part->size;
1225
1226 start_part = ALIGN_TO(part->size, align);
1227 end_part = start_part + sz;
1228
1229 r = part_make_space(m, part, end_part, &p);
1230 if (r < 0)
1231 return NULL;
1232
1233 if (padding > 0) {
1234 memzero(p, padding);
1235 p = (uint8_t*) p + padding;
1236 }
1237
1238 /* Readjust pointers */
1239 for (c = m->containers; c < m->containers + m->n_containers; c++)
1240 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1241
1242 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1243 }
1244 } else
1245 /* Return something that is not NULL and is aligned */
1246 p = (uint8_t *) NULL + align;
1247
1248 m->header->body_size = end_body;
1249 message_extend_containers(m, added);
1250
1251 if (add_offset) {
1252 r = message_add_offset(m, end_body);
1253 if (r < 0) {
1254 m->poisoned = true;
1255 return NULL;
1256 }
1257 }
1258
1259 return p;
1260 }
1261
1262 static int message_push_fd(sd_bus_message *m, int fd) {
1263 int *f, copy;
1264
1265 assert(m);
1266
1267 if (fd < 0)
1268 return -EINVAL;
1269
1270 if (!m->allow_fds)
1271 return -ENOTSUP;
1272
1273 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1274 if (copy < 0)
1275 return -errno;
1276
1277 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1278 if (!f) {
1279 m->poisoned = true;
1280 safe_close(copy);
1281 return -ENOMEM;
1282 }
1283
1284 m->fds = f;
1285 m->fds[m->n_fds] = copy;
1286 m->free_fds = true;
1287
1288 return copy;
1289 }
1290
1291 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1292 _cleanup_close_ int fd = -1;
1293 struct bus_container *c;
1294 ssize_t align, sz;
1295 void *a;
1296
1297 assert_return(m, -EINVAL);
1298 assert_return(!m->sealed, -EPERM);
1299 assert_return(bus_type_is_basic(type), -EINVAL);
1300 assert_return(!m->poisoned, -ESTALE);
1301
1302 c = message_get_container(m);
1303
1304 if (c->signature && c->signature[c->index]) {
1305 /* Container signature is already set */
1306
1307 if (c->signature[c->index] != type)
1308 return -ENXIO;
1309 } else {
1310 char *e;
1311
1312 /* Maybe we can append to the signature? But only if this is the top-level container*/
1313 if (c->enclosing != 0)
1314 return -ENXIO;
1315
1316 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1317 if (!e) {
1318 m->poisoned = true;
1319 return -ENOMEM;
1320 }
1321 }
1322
1323 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1324 uint8_t u8;
1325 uint32_t u32;
1326
1327 switch (type) {
1328
1329 case SD_BUS_TYPE_SIGNATURE:
1330 case SD_BUS_TYPE_STRING:
1331 p = strempty(p);
1332
1333 /* Fall through... */
1334 case SD_BUS_TYPE_OBJECT_PATH:
1335 if (!p)
1336 return -EINVAL;
1337
1338 align = 1;
1339 sz = strlen(p) + 1;
1340 break;
1341
1342 case SD_BUS_TYPE_BOOLEAN:
1343
1344 u8 = p && *(int*) p;
1345 p = &u8;
1346
1347 align = sz = 1;
1348 break;
1349
1350 case SD_BUS_TYPE_UNIX_FD:
1351
1352 if (!p)
1353 return -EINVAL;
1354
1355 fd = message_push_fd(m, *(int*) p);
1356 if (fd < 0)
1357 return fd;
1358
1359 u32 = m->n_fds;
1360 p = &u32;
1361
1362 align = sz = 4;
1363 break;
1364
1365 default:
1366 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1367 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1368 break;
1369 }
1370
1371 assert(align > 0);
1372 assert(sz > 0);
1373
1374 a = message_extend_body(m, align, sz, true);
1375 if (!a)
1376 return -ENOMEM;
1377
1378 memcpy(a, p, sz);
1379
1380 if (stored)
1381 *stored = (const uint8_t*) a;
1382
1383 } else {
1384 uint32_t u32;
1385
1386 switch (type) {
1387
1388 case SD_BUS_TYPE_STRING:
1389 /* To make things easy we'll serialize a NULL string
1390 * into the empty string */
1391 p = strempty(p);
1392
1393 /* Fall through... */
1394 case SD_BUS_TYPE_OBJECT_PATH:
1395
1396 if (!p)
1397 return -EINVAL;
1398
1399 align = 4;
1400 sz = 4 + strlen(p) + 1;
1401 break;
1402
1403 case SD_BUS_TYPE_SIGNATURE:
1404
1405 p = strempty(p);
1406
1407 align = 1;
1408 sz = 1 + strlen(p) + 1;
1409 break;
1410
1411 case SD_BUS_TYPE_BOOLEAN:
1412
1413 u32 = p && *(int*) p;
1414 p = &u32;
1415
1416 align = sz = 4;
1417 break;
1418
1419 case SD_BUS_TYPE_UNIX_FD:
1420
1421 if (!p)
1422 return -EINVAL;
1423
1424 fd = message_push_fd(m, *(int*) p);
1425 if (fd < 0)
1426 return fd;
1427
1428 u32 = m->n_fds;
1429 p = &u32;
1430
1431 align = sz = 4;
1432 break;
1433
1434 default:
1435 align = bus_type_get_alignment(type);
1436 sz = bus_type_get_size(type);
1437 break;
1438 }
1439
1440 assert(align > 0);
1441 assert(sz > 0);
1442
1443 a = message_extend_body(m, align, sz, false);
1444 if (!a)
1445 return -ENOMEM;
1446
1447 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1448 *(uint32_t*) a = sz - 5;
1449 memcpy((uint8_t*) a + 4, p, sz - 4);
1450
1451 if (stored)
1452 *stored = (const uint8_t*) a + 4;
1453
1454 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1455 *(uint8_t*) a = sz - 2;
1456 memcpy((uint8_t*) a + 1, p, sz - 1);
1457
1458 if (stored)
1459 *stored = (const uint8_t*) a + 1;
1460 } else {
1461 memcpy(a, p, sz);
1462
1463 if (stored)
1464 *stored = a;
1465 }
1466 }
1467
1468 if (type == SD_BUS_TYPE_UNIX_FD)
1469 m->n_fds ++;
1470
1471 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1472 c->index++;
1473
1474 fd = -1;
1475 return 0;
1476 }
1477
1478 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1479 return message_append_basic(m, type, p, NULL);
1480 }
1481
1482 _public_ int sd_bus_message_append_string_space(
1483 sd_bus_message *m,
1484 size_t size,
1485 char **s) {
1486
1487 struct bus_container *c;
1488 void *a;
1489
1490 assert_return(m, -EINVAL);
1491 assert_return(s, -EINVAL);
1492 assert_return(!m->sealed, -EPERM);
1493 assert_return(!m->poisoned, -ESTALE);
1494
1495 c = message_get_container(m);
1496
1497 if (c->signature && c->signature[c->index]) {
1498 /* Container signature is already set */
1499
1500 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1501 return -ENXIO;
1502 } else {
1503 char *e;
1504
1505 /* Maybe we can append to the signature? But only if this is the top-level container*/
1506 if (c->enclosing != 0)
1507 return -ENXIO;
1508
1509 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1510 if (!e) {
1511 m->poisoned = true;
1512 return -ENOMEM;
1513 }
1514 }
1515
1516 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1517 a = message_extend_body(m, 1, size + 1, true);
1518 if (!a)
1519 return -ENOMEM;
1520
1521 *s = a;
1522 } else {
1523 a = message_extend_body(m, 4, 4 + size + 1, false);
1524 if (!a)
1525 return -ENOMEM;
1526
1527 *(uint32_t*) a = size;
1528 *s = (char*) a + 4;
1529 }
1530
1531 (*s)[size] = 0;
1532
1533 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1534 c->index++;
1535
1536 return 0;
1537 }
1538
1539 _public_ int sd_bus_message_append_string_iovec(
1540 sd_bus_message *m,
1541 const struct iovec *iov,
1542 unsigned n) {
1543
1544 size_t size;
1545 unsigned i;
1546 char *p;
1547 int r;
1548
1549 assert_return(m, -EINVAL);
1550 assert_return(!m->sealed, -EPERM);
1551 assert_return(iov || n == 0, -EINVAL);
1552 assert_return(!m->poisoned, -ESTALE);
1553
1554 size = IOVEC_TOTAL_SIZE(iov, n);
1555
1556 r = sd_bus_message_append_string_space(m, size, &p);
1557 if (r < 0)
1558 return r;
1559
1560 for (i = 0; i < n; i++) {
1561
1562 if (iov[i].iov_base)
1563 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1564 else
1565 memset(p, ' ', iov[i].iov_len);
1566
1567 p += iov[i].iov_len;
1568 }
1569
1570 return 0;
1571 }
1572
1573 static int bus_message_open_array(
1574 sd_bus_message *m,
1575 struct bus_container *c,
1576 const char *contents,
1577 uint32_t **array_size,
1578 size_t *begin,
1579 bool *need_offsets) {
1580
1581 unsigned nindex;
1582 int alignment, r;
1583
1584 assert(m);
1585 assert(c);
1586 assert(contents);
1587 assert(array_size);
1588 assert(begin);
1589 assert(need_offsets);
1590
1591 if (!signature_is_single(contents, true))
1592 return -EINVAL;
1593
1594 if (c->signature && c->signature[c->index]) {
1595
1596 /* Verify the existing signature */
1597
1598 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1599 return -ENXIO;
1600
1601 if (!startswith(c->signature + c->index + 1, contents))
1602 return -ENXIO;
1603
1604 nindex = c->index + 1 + strlen(contents);
1605 } else {
1606 char *e;
1607
1608 if (c->enclosing != 0)
1609 return -ENXIO;
1610
1611 /* Extend the existing signature */
1612
1613 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1614 if (!e) {
1615 m->poisoned = true;
1616 return -ENOMEM;
1617 }
1618
1619 nindex = e - c->signature;
1620 }
1621
1622 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1623 alignment = bus_gvariant_get_alignment(contents);
1624 if (alignment < 0)
1625 return alignment;
1626
1627 /* Add alignment padding and add to offset list */
1628 if (!message_extend_body(m, alignment, 0, false))
1629 return -ENOMEM;
1630
1631 r = bus_gvariant_is_fixed_size(contents);
1632 if (r < 0)
1633 return r;
1634
1635 *begin = m->header->body_size;
1636 *need_offsets = r == 0;
1637 } else {
1638 void *a, *op;
1639 size_t os;
1640 struct bus_body_part *o;
1641
1642 alignment = bus_type_get_alignment(contents[0]);
1643 if (alignment < 0)
1644 return alignment;
1645
1646 a = message_extend_body(m, 4, 4, false);
1647 if (!a)
1648 return -ENOMEM;
1649
1650 o = m->body_end;
1651 op = m->body_end->data;
1652 os = m->body_end->size;
1653
1654 /* Add alignment between size and first element */
1655 if (!message_extend_body(m, alignment, 0, false))
1656 return -ENOMEM;
1657
1658 /* location of array size might have changed so let's readjust a */
1659 if (o == m->body_end)
1660 a = adjust_pointer(a, op, os, m->body_end->data);
1661
1662 *(uint32_t*) a = 0;
1663 *array_size = a;
1664 }
1665
1666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1667 c->index = nindex;
1668
1669 return 0;
1670 }
1671
1672 static int bus_message_open_variant(
1673 sd_bus_message *m,
1674 struct bus_container *c,
1675 const char *contents) {
1676
1677 assert(m);
1678 assert(c);
1679 assert(contents);
1680
1681 if (!signature_is_single(contents, false))
1682 return -EINVAL;
1683
1684 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1685 return -EINVAL;
1686
1687 if (c->signature && c->signature[c->index]) {
1688
1689 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1690 return -ENXIO;
1691
1692 } else {
1693 char *e;
1694
1695 if (c->enclosing != 0)
1696 return -ENXIO;
1697
1698 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1699 if (!e) {
1700 m->poisoned = true;
1701 return -ENOMEM;
1702 }
1703 }
1704
1705 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1706 /* Variants are always aligned to 8 */
1707
1708 if (!message_extend_body(m, 8, 0, false))
1709 return -ENOMEM;
1710
1711 } else {
1712 size_t l;
1713 void *a;
1714
1715 l = strlen(contents);
1716 a = message_extend_body(m, 1, 1 + l + 1, false);
1717 if (!a)
1718 return -ENOMEM;
1719
1720 *(uint8_t*) a = l;
1721 memcpy((uint8_t*) a + 1, contents, l + 1);
1722 }
1723
1724 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1725 c->index++;
1726
1727 return 0;
1728 }
1729
1730 static int bus_message_open_struct(
1731 sd_bus_message *m,
1732 struct bus_container *c,
1733 const char *contents,
1734 size_t *begin,
1735 bool *need_offsets) {
1736
1737 size_t nindex;
1738 int r;
1739
1740 assert(m);
1741 assert(c);
1742 assert(contents);
1743 assert(begin);
1744 assert(need_offsets);
1745
1746 if (!signature_is_valid(contents, false))
1747 return -EINVAL;
1748
1749 if (c->signature && c->signature[c->index]) {
1750 size_t l;
1751
1752 l = strlen(contents);
1753
1754 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1755 !startswith(c->signature + c->index + 1, contents) ||
1756 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1757 return -ENXIO;
1758
1759 nindex = c->index + 1 + l + 1;
1760 } else {
1761 char *e;
1762
1763 if (c->enclosing != 0)
1764 return -ENXIO;
1765
1766 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1767 if (!e) {
1768 m->poisoned = true;
1769 return -ENOMEM;
1770 }
1771
1772 nindex = e - c->signature;
1773 }
1774
1775 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1776 int alignment;
1777
1778 alignment = bus_gvariant_get_alignment(contents);
1779 if (alignment < 0)
1780 return alignment;
1781
1782 if (!message_extend_body(m, alignment, 0, false))
1783 return -ENOMEM;
1784
1785 r = bus_gvariant_is_fixed_size(contents);
1786 if (r < 0)
1787 return r;
1788
1789 *begin = m->header->body_size;
1790 *need_offsets = r == 0;
1791 } else {
1792 /* Align contents to 8 byte boundary */
1793 if (!message_extend_body(m, 8, 0, false))
1794 return -ENOMEM;
1795 }
1796
1797 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798 c->index = nindex;
1799
1800 return 0;
1801 }
1802
1803 static int bus_message_open_dict_entry(
1804 sd_bus_message *m,
1805 struct bus_container *c,
1806 const char *contents,
1807 size_t *begin,
1808 bool *need_offsets) {
1809
1810 int r;
1811
1812 assert(m);
1813 assert(c);
1814 assert(contents);
1815 assert(begin);
1816 assert(need_offsets);
1817
1818 if (!signature_is_pair(contents))
1819 return -EINVAL;
1820
1821 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1822 return -ENXIO;
1823
1824 if (c->signature && c->signature[c->index]) {
1825 size_t l;
1826
1827 l = strlen(contents);
1828
1829 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1830 !startswith(c->signature + c->index + 1, contents) ||
1831 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1832 return -ENXIO;
1833 } else
1834 return -ENXIO;
1835
1836 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1837 int alignment;
1838
1839 alignment = bus_gvariant_get_alignment(contents);
1840 if (alignment < 0)
1841 return alignment;
1842
1843 if (!message_extend_body(m, alignment, 0, false))
1844 return -ENOMEM;
1845
1846 r = bus_gvariant_is_fixed_size(contents);
1847 if (r < 0)
1848 return r;
1849
1850 *begin = m->header->body_size;
1851 *need_offsets = r == 0;
1852 } else {
1853 /* Align contents to 8 byte boundary */
1854 if (!message_extend_body(m, 8, 0, false))
1855 return -ENOMEM;
1856 }
1857
1858 return 0;
1859 }
1860
1861 _public_ int sd_bus_message_open_container(
1862 sd_bus_message *m,
1863 char type,
1864 const char *contents) {
1865
1866 struct bus_container *c, *w;
1867 uint32_t *array_size = NULL;
1868 char *signature;
1869 size_t before, begin = 0;
1870 bool need_offsets = false;
1871 int r;
1872
1873 assert_return(m, -EINVAL);
1874 assert_return(!m->sealed, -EPERM);
1875 assert_return(contents, -EINVAL);
1876 assert_return(!m->poisoned, -ESTALE);
1877
1878 /* Make sure we have space for one more container */
1879 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1880 m->poisoned = true;
1881 return -ENOMEM;
1882 }
1883
1884 c = message_get_container(m);
1885
1886 signature = strdup(contents);
1887 if (!signature) {
1888 m->poisoned = true;
1889 return -ENOMEM;
1890 }
1891
1892 /* Save old index in the parent container, in case we have to
1893 * abort this container */
1894 c->saved_index = c->index;
1895 before = m->header->body_size;
1896
1897 if (type == SD_BUS_TYPE_ARRAY)
1898 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1899 else if (type == SD_BUS_TYPE_VARIANT)
1900 r = bus_message_open_variant(m, c, contents);
1901 else if (type == SD_BUS_TYPE_STRUCT)
1902 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1903 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1904 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1905 else
1906 r = -EINVAL;
1907
1908 if (r < 0) {
1909 free(signature);
1910 return r;
1911 }
1912
1913 /* OK, let's fill it in */
1914 w = m->containers + m->n_containers++;
1915 w->enclosing = type;
1916 w->signature = signature;
1917 w->index = 0;
1918 w->array_size = array_size;
1919 w->before = before;
1920 w->begin = begin;
1921 w->n_offsets = w->offsets_allocated = 0;
1922 w->offsets = NULL;
1923 w->need_offsets = need_offsets;
1924
1925 return 0;
1926 }
1927
1928 static size_t determine_word_size(size_t sz, size_t extra) {
1929 if (sz + extra <= 0xFF)
1930 return 1;
1931 else if (sz + extra*2 <= 0xFFFF)
1932 return 2;
1933 else if (sz + extra*4 <= 0xFFFFFFFF)
1934 return 4;
1935 else
1936 return 8;
1937 }
1938
1939 static size_t read_word_le(void *p, size_t sz) {
1940 union {
1941 uint16_t u16;
1942 uint32_t u32;
1943 uint64_t u64;
1944 } x;
1945
1946 assert(p);
1947
1948 if (sz == 1)
1949 return *(uint8_t*) p;
1950
1951 memcpy(&x, p, sz);
1952
1953 if (sz == 2)
1954 return le16toh(x.u16);
1955 else if (sz == 4)
1956 return le32toh(x.u32);
1957 else if (sz == 8)
1958 return le64toh(x.u64);
1959
1960 assert_not_reached("unknown word width");
1961 }
1962
1963 static void write_word_le(void *p, size_t sz, size_t value) {
1964 union {
1965 uint16_t u16;
1966 uint32_t u32;
1967 uint64_t u64;
1968 } x;
1969
1970 assert(p);
1971 assert(sz == 8 || (value < (1ULL << (sz*8))));
1972
1973 if (sz == 1) {
1974 *(uint8_t*) p = value;
1975 return;
1976 } else if (sz == 2)
1977 x.u16 = htole16((uint16_t) value);
1978 else if (sz == 4)
1979 x.u32 = htole32((uint32_t) value);
1980 else if (sz == 8)
1981 x.u64 = htole64((uint64_t) value);
1982 else
1983 assert_not_reached("unknown word width");
1984
1985 memcpy(p, &x, sz);
1986 }
1987
1988 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1989
1990 assert(m);
1991 assert(c);
1992
1993 if (!BUS_MESSAGE_IS_GVARIANT(m))
1994 return 0;
1995
1996 if (c->need_offsets) {
1997 size_t payload, sz, i;
1998 uint8_t *a;
1999
2000 /* Variable-width arrays */
2001
2002 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2003 sz = determine_word_size(payload, c->n_offsets);
2004
2005 a = message_extend_body(m, 1, sz * c->n_offsets, true);
2006 if (!a)
2007 return -ENOMEM;
2008
2009 for (i = 0; i < c->n_offsets; i++)
2010 write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2011 } else {
2012 void *a;
2013
2014 /* Fixed-width or empty arrays */
2015
2016 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
2017 if (!a)
2018 return -ENOMEM;
2019 }
2020
2021 return 0;
2022 }
2023
2024 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2025 uint8_t *a;
2026 size_t l;
2027
2028 assert(m);
2029 assert(c);
2030
2031 if (!BUS_MESSAGE_IS_GVARIANT(m))
2032 return 0;
2033
2034 l = strlen(c->signature);
2035
2036 a = message_extend_body(m, 1, 1 + l, true);
2037 if (!a)
2038 return -ENOMEM;
2039
2040 a[0] = 0;
2041 memcpy(a+1, c->signature, l);
2042
2043 return 0;
2044 }
2045
2046 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2047 size_t n_variable = 0;
2048 unsigned i = 0;
2049 const char *p;
2050 uint8_t *a;
2051 int r;
2052
2053 assert(m);
2054 assert(c);
2055
2056 if (!BUS_MESSAGE_IS_GVARIANT(m))
2057 return 0;
2058
2059 p = strempty(c->signature);
2060 while (*p != 0) {
2061 size_t n;
2062
2063 r = signature_element_length(p, &n);
2064 if (r < 0)
2065 return r;
2066 else {
2067 char t[n+1];
2068
2069 memcpy(t, p, n);
2070 t[n] = 0;
2071
2072 r = bus_gvariant_is_fixed_size(t);
2073 if (r < 0)
2074 return r;
2075 }
2076
2077 assert(!c->need_offsets || i <= c->n_offsets);
2078
2079 /* We need to add an offset for each item that has a
2080 * variable size and that is not the last one in the
2081 * list */
2082 if (r == 0 && p[n] != 0)
2083 n_variable++;
2084
2085 i++;
2086 p += n;
2087 }
2088
2089 assert(!c->need_offsets || i == c->n_offsets);
2090 assert(c->need_offsets || n_variable == 0);
2091
2092 if (n_variable <= 0) {
2093 a = message_extend_body(m, 1, 0, add_offset);
2094 if (!a)
2095 return -ENOMEM;
2096 } else {
2097 size_t sz;
2098 unsigned j;
2099
2100 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2101
2102 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2103
2104 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2105 if (!a)
2106 return -ENOMEM;
2107
2108 p = strempty(c->signature);
2109 for (i = 0, j = 0; i < c->n_offsets; i++) {
2110 unsigned k;
2111 size_t n;
2112
2113 r = signature_element_length(p, &n);
2114 if (r < 0)
2115 return r;
2116 else {
2117 char t[n+1];
2118
2119 memcpy(t, p, n);
2120 t[n] = 0;
2121
2122 p += n;
2123
2124 r = bus_gvariant_is_fixed_size(t);
2125 if (r < 0)
2126 return r;
2127 if (r > 0 || p[0] == 0)
2128 continue;
2129 }
2130
2131 k = n_variable - 1 - j;
2132
2133 write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2134
2135 j++;
2136 }
2137 }
2138
2139 return 0;
2140 }
2141
2142 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2143 struct bus_container *c;
2144 int r;
2145
2146 assert_return(m, -EINVAL);
2147 assert_return(!m->sealed, -EPERM);
2148 assert_return(m->n_containers > 0, -EINVAL);
2149 assert_return(!m->poisoned, -ESTALE);
2150
2151 c = message_get_container(m);
2152
2153 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2154 if (c->signature && c->signature[c->index] != 0)
2155 return -EINVAL;
2156
2157 m->n_containers--;
2158
2159 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2160 r = bus_message_close_array(m, c);
2161 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2162 r = bus_message_close_variant(m, c);
2163 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2164 r = bus_message_close_struct(m, c, true);
2165 else
2166 assert_not_reached("Unknown container type");
2167
2168 free(c->signature);
2169 free(c->offsets);
2170
2171 return r;
2172 }
2173
2174 typedef struct {
2175 const char *types;
2176 unsigned n_struct;
2177 unsigned n_array;
2178 } TypeStack;
2179
2180 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2181 assert(stack);
2182 assert(max > 0);
2183
2184 if (*i >= max)
2185 return -EINVAL;
2186
2187 stack[*i].types = types;
2188 stack[*i].n_struct = n_struct;
2189 stack[*i].n_array = n_array;
2190 (*i)++;
2191
2192 return 0;
2193 }
2194
2195 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2196 assert(stack);
2197 assert(max > 0);
2198 assert(types);
2199 assert(n_struct);
2200 assert(n_array);
2201
2202 if (*i <= 0)
2203 return 0;
2204
2205 (*i)--;
2206 *types = stack[*i].types;
2207 *n_struct = stack[*i].n_struct;
2208 *n_array = stack[*i].n_array;
2209
2210 return 1;
2211 }
2212
2213 int bus_message_append_ap(
2214 sd_bus_message *m,
2215 const char *types,
2216 va_list ap) {
2217
2218 unsigned n_array, n_struct;
2219 TypeStack stack[BUS_CONTAINER_DEPTH];
2220 unsigned stack_ptr = 0;
2221 int r;
2222
2223 assert(m);
2224
2225 if (!types)
2226 return 0;
2227
2228 n_array = (unsigned) -1;
2229 n_struct = strlen(types);
2230
2231 for (;;) {
2232 const char *t;
2233
2234 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2235 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2236 if (r < 0)
2237 return r;
2238 if (r == 0)
2239 break;
2240
2241 r = sd_bus_message_close_container(m);
2242 if (r < 0)
2243 return r;
2244
2245 continue;
2246 }
2247
2248 t = types;
2249 if (n_array != (unsigned) -1)
2250 n_array --;
2251 else {
2252 types ++;
2253 n_struct--;
2254 }
2255
2256 switch (*t) {
2257
2258 case SD_BUS_TYPE_BYTE: {
2259 uint8_t x;
2260
2261 x = (uint8_t) va_arg(ap, int);
2262 r = sd_bus_message_append_basic(m, *t, &x);
2263 break;
2264 }
2265
2266 case SD_BUS_TYPE_BOOLEAN:
2267 case SD_BUS_TYPE_INT32:
2268 case SD_BUS_TYPE_UINT32:
2269 case SD_BUS_TYPE_UNIX_FD: {
2270 uint32_t x;
2271
2272 /* We assume a boolean is the same as int32_t */
2273 assert_cc(sizeof(int32_t) == sizeof(int));
2274
2275 x = va_arg(ap, uint32_t);
2276 r = sd_bus_message_append_basic(m, *t, &x);
2277 break;
2278 }
2279
2280 case SD_BUS_TYPE_INT16:
2281 case SD_BUS_TYPE_UINT16: {
2282 uint16_t x;
2283
2284 x = (uint16_t) va_arg(ap, int);
2285 r = sd_bus_message_append_basic(m, *t, &x);
2286 break;
2287 }
2288
2289 case SD_BUS_TYPE_INT64:
2290 case SD_BUS_TYPE_UINT64:
2291 case SD_BUS_TYPE_DOUBLE: {
2292 uint64_t x;
2293
2294 x = va_arg(ap, uint64_t);
2295 r = sd_bus_message_append_basic(m, *t, &x);
2296 break;
2297 }
2298
2299 case SD_BUS_TYPE_STRING:
2300 case SD_BUS_TYPE_OBJECT_PATH:
2301 case SD_BUS_TYPE_SIGNATURE: {
2302 const char *x;
2303
2304 x = va_arg(ap, const char*);
2305 r = sd_bus_message_append_basic(m, *t, x);
2306 break;
2307 }
2308
2309 case SD_BUS_TYPE_ARRAY: {
2310 size_t k;
2311
2312 r = signature_element_length(t + 1, &k);
2313 if (r < 0)
2314 return r;
2315
2316 {
2317 char s[k + 1];
2318 memcpy(s, t + 1, k);
2319 s[k] = 0;
2320
2321 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2322 if (r < 0)
2323 return r;
2324 }
2325
2326 if (n_array == (unsigned) -1) {
2327 types += k;
2328 n_struct -= k;
2329 }
2330
2331 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2332 if (r < 0)
2333 return r;
2334
2335 types = t + 1;
2336 n_struct = k;
2337 n_array = va_arg(ap, unsigned);
2338
2339 break;
2340 }
2341
2342 case SD_BUS_TYPE_VARIANT: {
2343 const char *s;
2344
2345 s = va_arg(ap, const char*);
2346 if (!s)
2347 return -EINVAL;
2348
2349 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2350 if (r < 0)
2351 return r;
2352
2353 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2354 if (r < 0)
2355 return r;
2356
2357 types = s;
2358 n_struct = strlen(s);
2359 n_array = (unsigned) -1;
2360
2361 break;
2362 }
2363
2364 case SD_BUS_TYPE_STRUCT_BEGIN:
2365 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2366 size_t k;
2367
2368 r = signature_element_length(t, &k);
2369 if (r < 0)
2370 return r;
2371
2372 {
2373 char s[k - 1];
2374
2375 memcpy(s, t + 1, k - 2);
2376 s[k - 2] = 0;
2377
2378 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2379 if (r < 0)
2380 return r;
2381 }
2382
2383 if (n_array == (unsigned) -1) {
2384 types += k - 1;
2385 n_struct -= k - 1;
2386 }
2387
2388 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2389 if (r < 0)
2390 return r;
2391
2392 types = t + 1;
2393 n_struct = k - 2;
2394 n_array = (unsigned) -1;
2395
2396 break;
2397 }
2398
2399 default:
2400 r = -EINVAL;
2401 }
2402
2403 if (r < 0)
2404 return r;
2405 }
2406
2407 return 1;
2408 }
2409
2410 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2411 va_list ap;
2412 int r;
2413
2414 assert_return(m, -EINVAL);
2415 assert_return(types, -EINVAL);
2416 assert_return(!m->sealed, -EPERM);
2417 assert_return(!m->poisoned, -ESTALE);
2418
2419 va_start(ap, types);
2420 r = bus_message_append_ap(m, types, ap);
2421 va_end(ap);
2422
2423 return r;
2424 }
2425
2426 _public_ int sd_bus_message_append_array_space(
2427 sd_bus_message *m,
2428 char type,
2429 size_t size,
2430 void **ptr) {
2431
2432 ssize_t align, sz;
2433 void *a;
2434 int r;
2435
2436 assert_return(m, -EINVAL);
2437 assert_return(!m->sealed, -EPERM);
2438 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2439 assert_return(ptr || size == 0, -EINVAL);
2440 assert_return(!m->poisoned, -ESTALE);
2441
2442 /* alignment and size of the trivial types (except bool) is
2443 * identical for gvariant and dbus1 marshalling */
2444 align = bus_type_get_alignment(type);
2445 sz = bus_type_get_size(type);
2446
2447 assert_se(align > 0);
2448 assert_se(sz > 0);
2449
2450 if (size % sz != 0)
2451 return -EINVAL;
2452
2453 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2454 if (r < 0)
2455 return r;
2456
2457 a = message_extend_body(m, align, size, false);
2458 if (!a)
2459 return -ENOMEM;
2460
2461 r = sd_bus_message_close_container(m);
2462 if (r < 0)
2463 return r;
2464
2465 *ptr = a;
2466 return 0;
2467 }
2468
2469 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2470 char type,
2471 const void *ptr,
2472 size_t size) {
2473 int r;
2474 void *p;
2475
2476 assert_return(m, -EINVAL);
2477 assert_return(!m->sealed, -EPERM);
2478 assert_return(bus_type_is_trivial(type), -EINVAL);
2479 assert_return(ptr || size == 0, -EINVAL);
2480 assert_return(!m->poisoned, -ESTALE);
2481
2482 r = sd_bus_message_append_array_space(m, type, size, &p);
2483 if (r < 0)
2484 return r;
2485
2486 if (size > 0)
2487 memcpy(p, ptr, size);
2488
2489 return 0;
2490 }
2491
2492 _public_ int sd_bus_message_append_array_iovec(
2493 sd_bus_message *m,
2494 char type,
2495 const struct iovec *iov,
2496 unsigned n) {
2497
2498 size_t size;
2499 unsigned i;
2500 void *p;
2501 int r;
2502
2503 assert_return(m, -EINVAL);
2504 assert_return(!m->sealed, -EPERM);
2505 assert_return(bus_type_is_trivial(type), -EINVAL);
2506 assert_return(iov || n == 0, -EINVAL);
2507 assert_return(!m->poisoned, -ESTALE);
2508
2509 size = IOVEC_TOTAL_SIZE(iov, n);
2510
2511 r = sd_bus_message_append_array_space(m, type, size, &p);
2512 if (r < 0)
2513 return r;
2514
2515 for (i = 0; i < n; i++) {
2516
2517 if (iov[i].iov_base)
2518 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2519 else
2520 memzero(p, iov[i].iov_len);
2521
2522 p = (uint8_t*) p + iov[i].iov_len;
2523 }
2524
2525 return 0;
2526 }
2527
2528 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2529 char type,
2530 int memfd) {
2531 _cleanup_close_ int copy_fd = -1;
2532 struct bus_body_part *part;
2533 ssize_t align, sz;
2534 uint64_t size;
2535 void *a;
2536 int r;
2537
2538 if (!m)
2539 return -EINVAL;
2540 if (memfd < 0)
2541 return -EINVAL;
2542 if (m->sealed)
2543 return -EPERM;
2544 if (!bus_type_is_trivial(type))
2545 return -EINVAL;
2546 if (m->poisoned)
2547 return -ESTALE;
2548
2549 r = memfd_set_sealed(memfd);
2550 if (r < 0)
2551 return r;
2552
2553 copy_fd = dup(memfd);
2554 if (copy_fd < 0)
2555 return copy_fd;
2556
2557 r = memfd_get_size(memfd, &size);
2558 if (r < 0)
2559 return r;
2560
2561 align = bus_type_get_alignment(type);
2562 sz = bus_type_get_size(type);
2563
2564 assert_se(align > 0);
2565 assert_se(sz > 0);
2566
2567 if (size % sz != 0)
2568 return -EINVAL;
2569
2570 if (size > (uint64_t) (uint32_t) -1)
2571 return -EINVAL;
2572
2573 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2574 if (r < 0)
2575 return r;
2576
2577 a = message_extend_body(m, align, 0, false);
2578 if (!a)
2579 return -ENOMEM;
2580
2581 part = message_append_part(m);
2582 if (!part)
2583 return -ENOMEM;
2584
2585 part->memfd = copy_fd;
2586 part->sealed = true;
2587 part->size = size;
2588 copy_fd = -1;
2589
2590 m->header->body_size += size;
2591 message_extend_containers(m, size);
2592
2593 return sd_bus_message_close_container(m);
2594 }
2595
2596 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
2597 _cleanup_close_ int copy_fd = -1;
2598 struct bus_body_part *part;
2599 struct bus_container *c;
2600 uint64_t size;
2601 void *a;
2602 int r;
2603
2604 assert_return(m, -EINVAL);
2605 assert_return(memfd >= 0, -EINVAL);
2606 assert_return(!m->sealed, -EPERM);
2607 assert_return(!m->poisoned, -ESTALE);
2608
2609 r = memfd_set_sealed(memfd);
2610 if (r < 0)
2611 return r;
2612
2613 copy_fd = dup(memfd);
2614 if (copy_fd < 0)
2615 return copy_fd;
2616
2617 r = memfd_get_size(memfd, &size);
2618 if (r < 0)
2619 return r;
2620
2621 /* We require this to be NUL terminated */
2622 if (size == 0)
2623 return -EINVAL;
2624
2625 if (size > (uint64_t) (uint32_t) -1)
2626 return -EINVAL;
2627
2628 c = message_get_container(m);
2629 if (c->signature && c->signature[c->index]) {
2630 /* Container signature is already set */
2631
2632 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2633 return -ENXIO;
2634 } else {
2635 char *e;
2636
2637 /* Maybe we can append to the signature? But only if this is the top-level container*/
2638 if (c->enclosing != 0)
2639 return -ENXIO;
2640
2641 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2642 if (!e) {
2643 m->poisoned = true;
2644 return -ENOMEM;
2645 }
2646 }
2647
2648 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2649 a = message_extend_body(m, 4, 4, false);
2650 if (!a)
2651 return -ENOMEM;
2652
2653 *(uint32_t*) a = size - 1;
2654 }
2655
2656 part = message_append_part(m);
2657 if (!part)
2658 return -ENOMEM;
2659
2660 part->memfd = copy_fd;
2661 part->sealed = true;
2662 part->size = size;
2663 copy_fd = -1;
2664
2665 m->header->body_size += size;
2666 message_extend_containers(m, size);
2667
2668 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2669 r = message_add_offset(m, m->header->body_size);
2670 if (r < 0) {
2671 m->poisoned = true;
2672 return -ENOMEM;
2673 }
2674 }
2675
2676 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2677 c->index++;
2678
2679 return 0;
2680 }
2681
2682 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2683 char **i;
2684 int r;
2685
2686 assert_return(m, -EINVAL);
2687 assert_return(!m->sealed, -EPERM);
2688 assert_return(!m->poisoned, -ESTALE);
2689
2690 r = sd_bus_message_open_container(m, 'a', "s");
2691 if (r < 0)
2692 return r;
2693
2694 STRV_FOREACH(i, l) {
2695 r = sd_bus_message_append_basic(m, 's', *i);
2696 if (r < 0)
2697 return r;
2698 }
2699
2700 return sd_bus_message_close_container(m);
2701 }
2702
2703 static int bus_message_close_header(sd_bus_message *m) {
2704 uint8_t *a;
2705 size_t sz, i;
2706
2707 assert(m);
2708
2709 if (!BUS_MESSAGE_IS_GVARIANT(m))
2710 return 0;
2711
2712 if (m->n_header_offsets < 1)
2713 return 0;
2714
2715 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2716
2717 sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2718
2719 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2720 if (!a)
2721 return -ENOMEM;
2722
2723 for (i = 0; i < m->n_header_offsets; i++)
2724 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2725
2726 return 0;
2727 }
2728
2729 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2730 struct bus_body_part *part;
2731 size_t l, a;
2732 unsigned i;
2733 int r;
2734
2735 assert(m);
2736
2737 if (m->sealed)
2738 return -EPERM;
2739
2740 if (m->n_containers > 0)
2741 return -EBADMSG;
2742
2743 if (m->poisoned)
2744 return -ESTALE;
2745
2746 /* In vtables the return signature of method calls is listed,
2747 * let's check if they match if this is a response */
2748 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2749 m->enforced_reply_signature &&
2750 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2751 return -ENOMSG;
2752
2753 /* If gvariant marshalling is used we need to close the body structure */
2754 r = bus_message_close_struct(m, &m->root_container, false);
2755 if (r < 0)
2756 return r;
2757
2758 /* If there's a non-trivial signature set, then add it in here */
2759 if (!isempty(m->root_container.signature)) {
2760 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2761 if (r < 0)
2762 return r;
2763 }
2764
2765 if (m->n_fds > 0) {
2766 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2767 if (r < 0)
2768 return r;
2769 }
2770
2771 r = bus_message_close_header(m);
2772 if (r < 0)
2773 return r;
2774
2775 m->header->serial = (uint32_t) cookie;
2776 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2777
2778 /* Add padding at the end of the fields part, since we know
2779 * the body needs to start at an 8 byte alignment. We made
2780 * sure we allocated enough space for this, so all we need to
2781 * do here is to zero it out. */
2782 l = BUS_MESSAGE_FIELDS_SIZE(m);
2783 a = ALIGN8(l) - l;
2784 if (a > 0)
2785 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2786
2787 /* If this is something we can send as memfd, then let's seal
2788 the memfd now. Note that we can send memfds as payload only
2789 for directed messages, and not for broadcasts. */
2790 if (m->destination && m->bus->use_memfd) {
2791 MESSAGE_FOREACH_PART(part, i, m)
2792 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2793 uint64_t sz;
2794
2795 /* Try to seal it if that makes
2796 * sense. First, unmap our own map to
2797 * make sure we don't keep it busy. */
2798 bus_body_part_unmap(part);
2799
2800 /* Then, sync up real memfd size */
2801 sz = part->size;
2802 if (ftruncate(part->memfd, sz) < 0)
2803 return -errno;
2804
2805 /* Finally, try to seal */
2806 if (fcntl(part->memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE) >= 0)
2807 part->sealed = true;
2808 }
2809 }
2810
2811 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2812 m->root_container.index = 0;
2813 m->root_container.offset_index = 0;
2814 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2815
2816 m->sealed = true;
2817
2818 return 0;
2819 }
2820
2821 int bus_body_part_map(struct bus_body_part *part) {
2822 void *p;
2823 size_t psz;
2824
2825 assert_se(part);
2826
2827 if (part->data)
2828 return 0;
2829
2830 if (part->size <= 0)
2831 return 0;
2832
2833 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2834 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2835 static const uint8_t zeroes[7] = { };
2836 part->data = (void*) zeroes;
2837 return 0;
2838 }
2839
2840 psz = PAGE_ALIGN(part->size);
2841
2842 if (part->memfd >= 0)
2843 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
2844 else if (part->is_zero)
2845 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2846 else
2847 return -EINVAL;
2848
2849 if (p == MAP_FAILED)
2850 return -errno;
2851
2852 part->mapped = psz;
2853 part->data = p;
2854 part->munmap_this = true;
2855
2856 return 0;
2857 }
2858
2859 void bus_body_part_unmap(struct bus_body_part *part) {
2860
2861 assert_se(part);
2862
2863 if (part->memfd < 0)
2864 return;
2865
2866 if (!part->data)
2867 return;
2868
2869 if (!part->munmap_this)
2870 return;
2871
2872 assert_se(munmap(part->data, part->mapped) == 0);
2873
2874 part->data = NULL;
2875 part->mapped = 0;
2876 part->munmap_this = false;
2877
2878 return;
2879 }
2880
2881 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2882 size_t k, start, end;
2883
2884 assert(rindex);
2885 assert(align > 0);
2886
2887 start = ALIGN_TO((size_t) *rindex, align);
2888 end = start + nbytes;
2889
2890 if (end > sz)
2891 return -EBADMSG;
2892
2893 /* Verify that padding is 0 */
2894 for (k = *rindex; k < start; k++)
2895 if (((const uint8_t*) p)[k] != 0)
2896 return -EBADMSG;
2897
2898 if (r)
2899 *r = (uint8_t*) p + start;
2900
2901 *rindex = end;
2902
2903 return 1;
2904 }
2905
2906 static bool message_end_of_signature(sd_bus_message *m) {
2907 struct bus_container *c;
2908
2909 assert(m);
2910
2911 c = message_get_container(m);
2912 return !c->signature || c->signature[c->index] == 0;
2913 }
2914
2915 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2916 struct bus_container *c;
2917
2918 assert(m);
2919
2920 c = message_get_container(m);
2921 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2922 return false;
2923
2924 if (BUS_MESSAGE_IS_GVARIANT(m))
2925 return index >= c->end;
2926 else {
2927 assert(c->array_size);
2928 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2929 }
2930 }
2931
2932 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2933 assert_return(m, -EINVAL);
2934 assert_return(m->sealed, -EPERM);
2935
2936 if (complete && m->n_containers > 0)
2937 return false;
2938
2939 if (message_end_of_signature(m))
2940 return true;
2941
2942 if (message_end_of_array(m, m->rindex))
2943 return true;
2944
2945 return false;
2946 }
2947
2948 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2949 struct bus_body_part *part;
2950 size_t begin;
2951 int r;
2952
2953 assert(m);
2954
2955 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2956 part = m->cached_rindex_part;
2957 begin = m->cached_rindex_part_begin;
2958 } else {
2959 part = &m->body;
2960 begin = 0;
2961 }
2962
2963 while (part) {
2964 if (index < begin)
2965 return NULL;
2966
2967 if (index + sz <= begin + part->size) {
2968
2969 r = bus_body_part_map(part);
2970 if (r < 0)
2971 return NULL;
2972
2973 if (p)
2974 *p = (uint8_t*) part->data + index - begin;
2975
2976 m->cached_rindex_part = part;
2977 m->cached_rindex_part_begin = begin;
2978
2979 return part;
2980 }
2981
2982 begin += part->size;
2983 part = part->next;
2984 }
2985
2986 return NULL;
2987 }
2988
2989 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2990 int r;
2991
2992 assert(m);
2993 assert(c);
2994 assert(rindex);
2995
2996 if (!BUS_MESSAGE_IS_GVARIANT(m))
2997 return 0;
2998
2999 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3000 int sz;
3001
3002 sz = bus_gvariant_get_size(c->signature);
3003 if (sz < 0) {
3004 int alignment;
3005
3006 if (c->offset_index+1 >= c->n_offsets)
3007 goto end;
3008
3009 /* Variable-size array */
3010
3011 alignment = bus_gvariant_get_alignment(c->signature);
3012 assert(alignment > 0);
3013
3014 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3015 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3016 } else {
3017
3018 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3019 goto end;
3020
3021 /* Fixed-size array */
3022 *rindex = c->begin + (c->offset_index+1) * sz;
3023 c->item_size = sz;
3024 }
3025
3026 c->offset_index++;
3027
3028 } else if (c->enclosing == 0 ||
3029 c->enclosing == SD_BUS_TYPE_STRUCT ||
3030 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3031
3032 int alignment;
3033 size_t n, j;
3034
3035 if (c->offset_index+1 >= c->n_offsets)
3036 goto end;
3037
3038 r = signature_element_length(c->signature + c->index, &n);
3039 if (r < 0)
3040 return r;
3041
3042 r = signature_element_length(c->signature + c->index + n, &j);
3043 if (r < 0)
3044 return r;
3045 else {
3046 char t[j+1];
3047 memcpy(t, c->signature + c->index + n, j);
3048 t[j] = 0;
3049
3050 alignment = bus_gvariant_get_alignment(t);
3051 }
3052
3053 assert(alignment > 0);
3054
3055 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3056 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3057
3058 c->offset_index++;
3059
3060 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3061 goto end;
3062 else
3063 assert_not_reached("Unknown container type");
3064
3065 return 0;
3066
3067 end:
3068 /* Reached the end */
3069 *rindex = c->end;
3070 c->item_size = 0;
3071 return 0;
3072 }
3073
3074
3075 static int message_peek_body(
3076 sd_bus_message *m,
3077 size_t *rindex,
3078 size_t align,
3079 size_t nbytes,
3080 void **ret) {
3081
3082 size_t k, start, end, padding;
3083 struct bus_body_part *part;
3084 uint8_t *q;
3085
3086 assert(m);
3087 assert(rindex);
3088 assert(align > 0);
3089
3090 start = ALIGN_TO((size_t) *rindex, align);
3091 padding = start - *rindex;
3092 end = start + nbytes;
3093
3094 if (end > BUS_MESSAGE_BODY_SIZE(m))
3095 return -EBADMSG;
3096
3097 part = find_part(m, *rindex, padding, (void**) &q);
3098 if (!part)
3099 return -EBADMSG;
3100
3101 if (q) {
3102 /* Verify padding */
3103 for (k = 0; k < padding; k++)
3104 if (q[k] != 0)
3105 return -EBADMSG;
3106 }
3107
3108 part = find_part(m, start, nbytes, (void**) &q);
3109 if (!part || (nbytes > 0 && !q))
3110 return -EBADMSG;
3111
3112 *rindex = end;
3113
3114 if (ret)
3115 *ret = q;
3116
3117 return 0;
3118 }
3119
3120 static bool validate_nul(const char *s, size_t l) {
3121
3122 /* Check for NUL chars in the string */
3123 if (memchr(s, 0, l))
3124 return false;
3125
3126 /* Check for NUL termination */
3127 if (s[l] != 0)
3128 return false;
3129
3130 return true;
3131 }
3132
3133 static bool validate_string(const char *s, size_t l) {
3134
3135 if (!validate_nul(s, l))
3136 return false;
3137
3138 /* Check if valid UTF8 */
3139 if (!utf8_is_valid(s))
3140 return false;
3141
3142 return true;
3143 }
3144
3145 static bool validate_signature(const char *s, size_t l) {
3146
3147 if (!validate_nul(s, l))
3148 return false;
3149
3150 /* Check if valid signature */
3151 if (!signature_is_valid(s, true))
3152 return false;
3153
3154 return true;
3155 }
3156
3157 static bool validate_object_path(const char *s, size_t l) {
3158
3159 if (!validate_nul(s, l))
3160 return false;
3161
3162 if (!object_path_is_valid(s))
3163 return false;
3164
3165 return true;
3166 }
3167
3168 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3169 struct bus_container *c;
3170 size_t rindex;
3171 void *q;
3172 int r;
3173
3174 assert_return(m, -EINVAL);
3175 assert_return(m->sealed, -EPERM);
3176 assert_return(bus_type_is_basic(type), -EINVAL);
3177
3178 if (message_end_of_signature(m))
3179 return -ENXIO;
3180
3181 if (message_end_of_array(m, m->rindex))
3182 return 0;
3183
3184 c = message_get_container(m);
3185 if (c->signature[c->index] != type)
3186 return -ENXIO;
3187
3188 rindex = m->rindex;
3189
3190 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3191
3192 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3193 bool ok;
3194
3195 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3196 if (r < 0)
3197 return r;
3198
3199 if (type == SD_BUS_TYPE_STRING)
3200 ok = validate_string(q, c->item_size-1);
3201 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3202 ok = validate_object_path(q, c->item_size-1);
3203 else
3204 ok = validate_signature(q, c->item_size-1);
3205
3206 if (!ok)
3207 return -EBADMSG;
3208
3209 if (p)
3210 *(const char**) p = q;
3211 } else {
3212 int sz, align;
3213
3214 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3215 assert(sz > 0);
3216 if ((size_t) sz != c->item_size)
3217 return -EBADMSG;
3218
3219 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3220 assert(align > 0);
3221
3222 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3223 if (r < 0)
3224 return r;
3225
3226 switch (type) {
3227
3228 case SD_BUS_TYPE_BYTE:
3229 if (p)
3230 *(uint8_t*) p = *(uint8_t*) q;
3231 break;
3232
3233 case SD_BUS_TYPE_BOOLEAN:
3234 if (p)
3235 *(int*) p = !!*(uint8_t*) q;
3236 break;
3237
3238 case SD_BUS_TYPE_INT16:
3239 case SD_BUS_TYPE_UINT16:
3240 if (p)
3241 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3242 break;
3243
3244 case SD_BUS_TYPE_INT32:
3245 case SD_BUS_TYPE_UINT32:
3246 if (p)
3247 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3248 break;
3249
3250 case SD_BUS_TYPE_INT64:
3251 case SD_BUS_TYPE_UINT64:
3252 case SD_BUS_TYPE_DOUBLE:
3253 if (p)
3254 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3255 break;
3256
3257 case SD_BUS_TYPE_UNIX_FD: {
3258 uint32_t j;
3259
3260 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3261 if (j >= m->n_fds)
3262 return -EBADMSG;
3263
3264 if (p)
3265 *(int*) p = m->fds[j];
3266
3267 break;
3268 }
3269
3270 default:
3271 assert_not_reached("unexpected type");
3272 }
3273 }
3274
3275 r = container_next_item(m, c, &rindex);
3276 if (r < 0)
3277 return r;
3278 } else {
3279
3280 rindex = m->rindex;
3281
3282 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3283 uint32_t l;
3284 bool ok;
3285
3286 r = message_peek_body(m, &rindex, 4, 4, &q);
3287 if (r < 0)
3288 return r;
3289
3290 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3291 r = message_peek_body(m, &rindex, 1, l+1, &q);
3292 if (r < 0)
3293 return r;
3294
3295 if (type == SD_BUS_TYPE_OBJECT_PATH)
3296 ok = validate_object_path(q, l);
3297 else
3298 ok = validate_string(q, l);
3299 if (!ok)
3300 return -EBADMSG;
3301
3302 if (p)
3303 *(const char**) p = q;
3304
3305 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3306 uint8_t l;
3307
3308 r = message_peek_body(m, &rindex, 1, 1, &q);
3309 if (r < 0)
3310 return r;
3311
3312 l = *(uint8_t*) q;
3313 r = message_peek_body(m, &rindex, 1, l+1, &q);
3314 if (r < 0)
3315 return r;
3316
3317 if (!validate_signature(q, l))
3318 return -EBADMSG;
3319
3320 if (p)
3321 *(const char**) p = q;
3322
3323 } else {
3324 ssize_t sz, align;
3325
3326 align = bus_type_get_alignment(type);
3327 assert(align > 0);
3328
3329 sz = bus_type_get_size(type);
3330 assert(sz > 0);
3331
3332 r = message_peek_body(m, &rindex, align, sz, &q);
3333 if (r < 0)
3334 return r;
3335
3336 switch (type) {
3337
3338 case SD_BUS_TYPE_BYTE:
3339 if (p)
3340 *(uint8_t*) p = *(uint8_t*) q;
3341 break;
3342
3343 case SD_BUS_TYPE_BOOLEAN:
3344 if (p)
3345 *(int*) p = !!*(uint32_t*) q;
3346 break;
3347
3348 case SD_BUS_TYPE_INT16:
3349 case SD_BUS_TYPE_UINT16:
3350 if (p)
3351 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3352 break;
3353
3354 case SD_BUS_TYPE_INT32:
3355 case SD_BUS_TYPE_UINT32:
3356 if (p)
3357 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3358 break;
3359
3360 case SD_BUS_TYPE_INT64:
3361 case SD_BUS_TYPE_UINT64:
3362 case SD_BUS_TYPE_DOUBLE:
3363 if (p)
3364 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3365 break;
3366
3367 case SD_BUS_TYPE_UNIX_FD: {
3368 uint32_t j;
3369
3370 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3371 if (j >= m->n_fds)
3372 return -EBADMSG;
3373
3374 if (p)
3375 *(int*) p = m->fds[j];
3376 break;
3377 }
3378
3379 default:
3380 assert_not_reached("Unknown basic type...");
3381 }
3382 }
3383 }
3384
3385 m->rindex = rindex;
3386
3387 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3388 c->index++;
3389
3390 return 1;
3391 }
3392
3393 static int bus_message_enter_array(
3394 sd_bus_message *m,
3395 struct bus_container *c,
3396 const char *contents,
3397 uint32_t **array_size,
3398 size_t *item_size,
3399 size_t **offsets,
3400 size_t *n_offsets) {
3401
3402 size_t rindex;
3403 void *q;
3404 int r, alignment;
3405
3406 assert(m);
3407 assert(c);
3408 assert(contents);
3409 assert(array_size);
3410 assert(item_size);
3411 assert(offsets);
3412 assert(n_offsets);
3413
3414 if (!signature_is_single(contents, true))
3415 return -EINVAL;
3416
3417 if (!c->signature || c->signature[c->index] == 0)
3418 return -ENXIO;
3419
3420 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3421 return -ENXIO;
3422
3423 if (!startswith(c->signature + c->index + 1, contents))
3424 return -ENXIO;
3425
3426 rindex = m->rindex;
3427
3428 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3429 /* dbus1 */
3430
3431 r = message_peek_body(m, &rindex, 4, 4, &q);
3432 if (r < 0)
3433 return r;
3434
3435 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3436 return -EBADMSG;
3437
3438 alignment = bus_type_get_alignment(contents[0]);
3439 if (alignment < 0)
3440 return alignment;
3441
3442 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3443 if (r < 0)
3444 return r;
3445
3446 *array_size = (uint32_t*) q;
3447
3448 } else if (c->item_size <= 0) {
3449
3450 /* gvariant: empty array */
3451 *item_size = 0;
3452 *offsets = NULL;
3453 *n_offsets = 0;
3454
3455 } else if (bus_gvariant_is_fixed_size(contents)) {
3456
3457 /* gvariant: fixed length array */
3458 *item_size = bus_gvariant_get_size(contents);
3459 *offsets = NULL;
3460 *n_offsets = 0;
3461
3462 } else {
3463 size_t where, p = 0, framing, sz;
3464 unsigned i;
3465
3466 /* gvariant: variable length array */
3467 sz = determine_word_size(c->item_size, 0);
3468
3469 where = rindex + c->item_size - sz;
3470 r = message_peek_body(m, &where, 1, sz, &q);
3471 if (r < 0)
3472 return r;
3473
3474 framing = read_word_le(q, sz);
3475 if (framing > c->item_size - sz)
3476 return -EBADMSG;
3477 if ((c->item_size - framing) % sz != 0)
3478 return -EBADMSG;
3479
3480 *n_offsets = (c->item_size - framing) / sz;
3481
3482 where = rindex + framing;
3483 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3484 if (r < 0)
3485 return r;
3486
3487 *offsets = new(size_t, *n_offsets);
3488 if (!*offsets)
3489 return -ENOMEM;
3490
3491 for (i = 0; i < *n_offsets; i++) {
3492 size_t x;
3493
3494 x = read_word_le((uint8_t*) q + i * sz, sz);
3495 if (x > c->item_size - sz)
3496 return -EBADMSG;
3497 if (x < p)
3498 return -EBADMSG;
3499
3500 (*offsets)[i] = rindex + x;
3501 p = x;
3502 }
3503
3504 *item_size = (*offsets)[0] - rindex;
3505 }
3506
3507 m->rindex = rindex;
3508
3509 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3510 c->index += 1 + strlen(contents);
3511
3512 return 1;
3513 }
3514
3515 static int bus_message_enter_variant(
3516 sd_bus_message *m,
3517 struct bus_container *c,
3518 const char *contents,
3519 size_t *item_size) {
3520
3521 size_t rindex;
3522 uint8_t l;
3523 void *q;
3524 int r;
3525
3526 assert(m);
3527 assert(c);
3528 assert(contents);
3529 assert(item_size);
3530
3531 if (!signature_is_single(contents, false))
3532 return -EINVAL;
3533
3534 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3535 return -EINVAL;
3536
3537 if (!c->signature || c->signature[c->index] == 0)
3538 return -ENXIO;
3539
3540 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3541 return -ENXIO;
3542
3543 rindex = m->rindex;
3544
3545 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3546 size_t k, where;
3547
3548 k = strlen(contents);
3549 if (1+k > c->item_size)
3550 return -EBADMSG;
3551
3552 where = rindex + c->item_size - (1+k);
3553 r = message_peek_body(m, &where, 1, 1+k, &q);
3554 if (r < 0)
3555 return r;
3556
3557 if (*(char*) q != 0)
3558 return -EBADMSG;
3559
3560 if (memcmp((uint8_t*) q+1, contents, k))
3561 return -ENXIO;
3562
3563 *item_size = c->item_size - (1+k);
3564
3565 } else {
3566 r = message_peek_body(m, &rindex, 1, 1, &q);
3567 if (r < 0)
3568 return r;
3569
3570 l = *(uint8_t*) q;
3571 r = message_peek_body(m, &rindex, 1, l+1, &q);
3572 if (r < 0)
3573 return r;
3574
3575 if (!validate_signature(q, l))
3576 return -EBADMSG;
3577
3578 if (!streq(q, contents))
3579 return -ENXIO;
3580 }
3581
3582 m->rindex = rindex;
3583
3584 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3585 c->index++;
3586
3587 return 1;
3588 }
3589
3590 static int build_struct_offsets(
3591 sd_bus_message *m,
3592 const char *signature,
3593 size_t size,
3594 size_t *item_size,
3595 size_t **offsets,
3596 size_t *n_offsets) {
3597
3598 unsigned n_variable = 0, n_total = 0, v;
3599 size_t previous = 0, where;
3600 const char *p;
3601 size_t sz;
3602 void *q;
3603 int r;
3604
3605 assert(m);
3606 assert(item_size);
3607 assert(offsets);
3608 assert(n_offsets);
3609
3610 if (isempty(signature)) {
3611 *item_size = 0;
3612 *offsets = NULL;
3613 *n_offsets = 0;
3614 return 0;
3615 }
3616
3617 sz = determine_word_size(size, 0);
3618 if (sz <= 0)
3619 return -EBADMSG;
3620
3621 /* First, loop over signature and count variable elements and
3622 * elements in general. We use this to know how large the
3623 * offset array is at the end of the structure. Note that
3624 * GVariant only stores offsets for all variable size elements
3625 * that are not the last item. */
3626
3627 p = signature;
3628 while (*p != 0) {
3629 size_t n;
3630
3631 r = signature_element_length(p, &n);
3632 if (r < 0)
3633 return r;
3634 else {
3635 char t[n+1];
3636
3637 memcpy(t, p, n);
3638 t[n] = 0;
3639
3640 r = bus_gvariant_is_fixed_size(t);
3641 }
3642
3643 if (r < 0)
3644 return r;
3645 if (r == 0 && p[n] != 0) /* except the last item */
3646 n_variable ++;
3647 n_total++;
3648
3649 p += n;
3650 }
3651
3652 if (size < n_variable * sz)
3653 return -EBADMSG;
3654
3655 where = m->rindex + size - (n_variable * sz);
3656 r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3657 if (r < 0)
3658 return r;
3659
3660 v = n_variable;
3661
3662 *offsets = new(size_t, n_total);
3663 if (!*offsets)
3664 return -ENOMEM;
3665
3666 *n_offsets = 0;
3667
3668 /* Second, loop again and build an offset table */
3669 p = signature;
3670 while (*p != 0) {
3671 size_t n, offset;
3672 int k;
3673
3674 r = signature_element_length(p, &n);
3675 if (r < 0)
3676 return r;
3677 else {
3678 char t[n+1];
3679
3680 memcpy(t, p, n);
3681 t[n] = 0;
3682
3683 k = bus_gvariant_get_size(t);
3684 if (k < 0) {
3685 size_t x;
3686
3687 /* variable size */
3688 if (v > 0) {
3689 v--;
3690
3691 x = read_word_le((uint8_t*) q + v*sz, sz);
3692 if (x >= size)
3693 return -EBADMSG;
3694 if (m->rindex + x < previous)
3695 return -EBADMSG;
3696 } else
3697 /* The last item's end
3698 * is determined from
3699 * the start of the
3700 * offset array */
3701 x = size - (n_variable * sz);
3702
3703 offset = m->rindex + x;
3704
3705 } else {
3706 size_t align;
3707
3708 /* fixed size */
3709 align = bus_gvariant_get_alignment(t);
3710 assert(align > 0);
3711
3712 offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3713 }
3714 }
3715
3716 previous = (*offsets)[(*n_offsets)++] = offset;
3717 p += n;
3718 }
3719
3720 assert(v == 0);
3721 assert(*n_offsets == n_total);
3722
3723 *item_size = (*offsets)[0] - m->rindex;
3724 return 0;
3725 }
3726
3727 static int enter_struct_or_dict_entry(
3728 sd_bus_message *m,
3729 struct bus_container *c,
3730 const char *contents,
3731 size_t *item_size,
3732 size_t **offsets,
3733 size_t *n_offsets) {
3734
3735 int r;
3736
3737 assert(m);
3738 assert(c);
3739 assert(contents);
3740 assert(item_size);
3741 assert(offsets);
3742 assert(n_offsets);
3743
3744 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3745
3746 /* dbus1 */
3747 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3748 if (r < 0)
3749 return r;
3750
3751 } else if (c->item_size <= 0) {
3752
3753 /* gvariant empty struct */
3754 *item_size = 0;
3755 *offsets = NULL;
3756 *n_offsets = 0;
3757 } else
3758 /* gvariant with contents */
3759 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3760
3761 return 0;
3762 }
3763
3764 static int bus_message_enter_struct(
3765 sd_bus_message *m,
3766 struct bus_container *c,
3767 const char *contents,
3768 size_t *item_size,
3769 size_t **offsets,
3770 size_t *n_offsets) {
3771
3772 size_t l;
3773 int r;
3774
3775 assert(m);
3776 assert(c);
3777 assert(contents);
3778 assert(item_size);
3779 assert(offsets);
3780 assert(n_offsets);
3781
3782 if (!signature_is_valid(contents, false))
3783 return -EINVAL;
3784
3785 if (!c->signature || c->signature[c->index] == 0)
3786 return -ENXIO;
3787
3788 l = strlen(contents);
3789
3790 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3791 !startswith(c->signature + c->index + 1, contents) ||
3792 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3793 return -ENXIO;
3794
3795 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3796 if (r < 0)
3797 return r;
3798
3799 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3800 c->index += 1 + l + 1;
3801
3802 return 1;
3803 }
3804
3805 static int bus_message_enter_dict_entry(
3806 sd_bus_message *m,
3807 struct bus_container *c,
3808 const char *contents,
3809 size_t *item_size,
3810 size_t **offsets,
3811 size_t *n_offsets) {
3812
3813 size_t l;
3814 int r;
3815
3816 assert(m);
3817 assert(c);
3818 assert(contents);
3819
3820 if (!signature_is_pair(contents))
3821 return -EINVAL;
3822
3823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3824 return -ENXIO;
3825
3826 if (!c->signature || c->signature[c->index] == 0)
3827 return 0;
3828
3829 l = strlen(contents);
3830
3831 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3832 !startswith(c->signature + c->index + 1, contents) ||
3833 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3834 return -ENXIO;
3835
3836 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3837 if (r < 0)
3838 return r;
3839
3840 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3841 c->index += 1 + l + 1;
3842
3843 return 1;
3844 }
3845
3846 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3847 char type,
3848 const char *contents) {
3849 struct bus_container *c, *w;
3850 uint32_t *array_size = NULL;
3851 char *signature;
3852 size_t before;
3853 size_t *offsets = NULL;
3854 size_t n_offsets = 0, item_size = 0;
3855 int r;
3856
3857 assert_return(m, -EINVAL);
3858 assert_return(m->sealed, -EPERM);
3859 assert_return(type != 0 || !contents, -EINVAL);
3860
3861 if (type == 0 || !contents) {
3862 const char *cc;
3863 char tt;
3864
3865 /* Allow entering into anonymous containers */
3866 r = sd_bus_message_peek_type(m, &tt, &cc);
3867 if (r < 0)
3868 return r;
3869
3870 if (type != 0 && type != tt)
3871 return -ENXIO;
3872
3873 if (contents && !streq(contents, cc))
3874 return -ENXIO;
3875
3876 type = tt;
3877 contents = cc;
3878 }
3879
3880 /*
3881 * We enforce a global limit on container depth, that is much
3882 * higher than the 32 structs and 32 arrays the specification
3883 * mandates. This is simpler to implement for us, and we need
3884 * this only to ensure our container array doesn't grow
3885 * without bounds. We are happy to return any data from a
3886 * message as long as the data itself is valid, even if the
3887 * overall message might be not.
3888 *
3889 * Note that the message signature is validated when
3890 * parsing the headers, and that validation does check the
3891 * 32/32 limit.
3892 *
3893 * Note that the specification defines no limits on the depth
3894 * of stacked variants, but we do.
3895 */
3896 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3897 return -EBADMSG;
3898
3899 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3900 return -ENOMEM;
3901
3902 if (message_end_of_signature(m))
3903 return -ENXIO;
3904
3905 if (message_end_of_array(m, m->rindex))
3906 return 0;
3907
3908 c = message_get_container(m);
3909
3910 signature = strdup(contents);
3911 if (!signature)
3912 return -ENOMEM;
3913
3914 c->saved_index = c->index;
3915 before = m->rindex;
3916
3917 if (type == SD_BUS_TYPE_ARRAY)
3918 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3919 else if (type == SD_BUS_TYPE_VARIANT)
3920 r = bus_message_enter_variant(m, c, contents, &item_size);
3921 else if (type == SD_BUS_TYPE_STRUCT)
3922 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3923 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3924 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3925 else
3926 r = -EINVAL;
3927
3928 if (r <= 0) {
3929 free(signature);
3930 free(offsets);
3931 return r;
3932 }
3933
3934 /* OK, let's fill it in */
3935 w = m->containers + m->n_containers++;
3936 w->enclosing = type;
3937 w->signature = signature;
3938 w->peeked_signature = NULL;
3939 w->index = 0;
3940
3941 w->before = before;
3942 w->begin = m->rindex;
3943 w->end = m->rindex + c->item_size;
3944
3945 w->array_size = array_size;
3946 w->item_size = item_size;
3947 w->offsets = offsets;
3948 w->n_offsets = n_offsets;
3949 w->offset_index = 0;
3950
3951 return 1;
3952 }
3953
3954 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3955 struct bus_container *c;
3956 unsigned saved;
3957 int r;
3958
3959 assert_return(m, -EINVAL);
3960 assert_return(m->sealed, -EPERM);
3961 assert_return(m->n_containers > 0, -ENXIO);
3962
3963 c = message_get_container(m);
3964
3965 if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3966 if (c->signature && c->signature[c->index] != 0)
3967 return -EBUSY;
3968 }
3969
3970 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3971 if (m->rindex < c->end)
3972 return -EBUSY;
3973
3974 } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3975 uint32_t l;
3976
3977 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3978 if (c->begin + l != m->rindex)
3979 return -EBUSY;
3980 }
3981
3982 free(c->signature);
3983 free(c->peeked_signature);
3984 free(c->offsets);
3985 m->n_containers--;
3986
3987 c = message_get_container(m);
3988
3989 saved = c->index;
3990 c->index = c->saved_index;
3991 r = container_next_item(m, c, &m->rindex);
3992 c->index = saved;
3993 if (r < 0)
3994 return r;
3995
3996 return 1;
3997 }
3998
3999 static void message_quit_container(sd_bus_message *m) {
4000 struct bus_container *c;
4001
4002 assert(m);
4003 assert(m->sealed);
4004 assert(m->n_containers > 0);
4005
4006 c = message_get_container(m);
4007
4008 /* Undo seeks */
4009 assert(m->rindex >= c->before);
4010 m->rindex = c->before;
4011
4012 /* Free container */
4013 free(c->signature);
4014 free(c->offsets);
4015 m->n_containers--;
4016
4017 /* Correct index of new top-level container */
4018 c = message_get_container(m);
4019 c->index = c->saved_index;
4020 }
4021
4022 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4023 struct bus_container *c;
4024 int r;
4025
4026 assert_return(m, -EINVAL);
4027 assert_return(m->sealed, -EPERM);
4028
4029 if (message_end_of_signature(m))
4030 goto eof;
4031
4032 if (message_end_of_array(m, m->rindex))
4033 goto eof;
4034
4035 c = message_get_container(m);
4036
4037 if (bus_type_is_basic(c->signature[c->index])) {
4038 if (contents)
4039 *contents = NULL;
4040 if (type)
4041 *type = c->signature[c->index];
4042 return 1;
4043 }
4044
4045 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4046
4047 if (contents) {
4048 size_t l;
4049 char *sig;
4050
4051 r = signature_element_length(c->signature+c->index+1, &l);
4052 if (r < 0)
4053 return r;
4054
4055 assert(l >= 1);
4056
4057 sig = strndup(c->signature + c->index + 1, l);
4058 if (!sig)
4059 return -ENOMEM;
4060
4061 free(c->peeked_signature);
4062 *contents = c->peeked_signature = sig;
4063 }
4064
4065 if (type)
4066 *type = SD_BUS_TYPE_ARRAY;
4067
4068 return 1;
4069 }
4070
4071 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4072 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4073
4074 if (contents) {
4075 size_t l;
4076 char *sig;
4077
4078 r = signature_element_length(c->signature+c->index, &l);
4079 if (r < 0)
4080 return r;
4081
4082 assert(l >= 2);
4083 sig = strndup(c->signature + c->index + 1, l - 2);
4084 if (!sig)
4085 return -ENOMEM;
4086
4087 free(c->peeked_signature);
4088 *contents = c->peeked_signature = sig;
4089 }
4090
4091 if (type)
4092 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4093
4094 return 1;
4095 }
4096
4097 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4098 if (contents) {
4099 void *q;
4100
4101 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4102 size_t k;
4103
4104 if (c->item_size < 2)
4105 return -EBADMSG;
4106
4107 /* Look for the NUL delimiter that
4108 separates the payload from the
4109 signature. Since the body might be
4110 in a different part that then the
4111 signature we map byte by byte. */
4112
4113 for (k = 2; k <= c->item_size; k++) {
4114 size_t where;
4115
4116 where = m->rindex + c->item_size - k;
4117 r = message_peek_body(m, &where, 1, k, &q);
4118 if (r < 0)
4119 return r;
4120
4121 if (*(char*) q == 0)
4122 break;
4123 }
4124
4125 if (k > c->item_size)
4126 return -EBADMSG;
4127
4128 free(c->peeked_signature);
4129 c->peeked_signature = strndup((char*) q + 1, k - 1);
4130 if (!c->peeked_signature)
4131 return -ENOMEM;
4132
4133 if (!signature_is_valid(c->peeked_signature, true))
4134 return -EBADMSG;
4135
4136 *contents = c->peeked_signature;
4137 } else {
4138 size_t rindex, l;
4139
4140 rindex = m->rindex;
4141 r = message_peek_body(m, &rindex, 1, 1, &q);
4142 if (r < 0)
4143 return r;
4144
4145 l = *(uint8_t*) q;
4146 r = message_peek_body(m, &rindex, 1, l+1, &q);
4147 if (r < 0)
4148 return r;
4149
4150 if (!validate_signature(q, l))
4151 return -EBADMSG;
4152
4153 *contents = q;
4154 }
4155 }
4156
4157 if (type)
4158 *type = SD_BUS_TYPE_VARIANT;
4159
4160 return 1;
4161 }
4162
4163 return -EINVAL;
4164
4165 eof:
4166 if (type)
4167 *type = 0;
4168 if (contents)
4169 *contents = NULL;
4170 return 0;
4171 }
4172
4173 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4174 struct bus_container *c;
4175
4176 assert_return(m, -EINVAL);
4177 assert_return(m->sealed, -EPERM);
4178
4179 if (complete) {
4180 message_reset_containers(m);
4181 m->rindex = 0;
4182
4183 c = message_get_container(m);
4184 } else {
4185 c = message_get_container(m);
4186
4187 c->offset_index = 0;
4188 c->index = 0;
4189 m->rindex = c->begin;
4190 }
4191
4192 c->offset_index = 0;
4193 c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4194
4195 return !isempty(c->signature);
4196 }
4197
4198 static int message_read_ap(
4199 sd_bus_message *m,
4200 const char *types,
4201 va_list ap) {
4202
4203 unsigned n_array, n_struct;
4204 TypeStack stack[BUS_CONTAINER_DEPTH];
4205 unsigned stack_ptr = 0;
4206 unsigned n_loop = 0;
4207 int r;
4208
4209 assert(m);
4210
4211 if (isempty(types))
4212 return 0;
4213
4214 /* Ideally, we'd just call ourselves recursively on every
4215 * complex type. However, the state of a va_list that is
4216 * passed to a function is undefined after that function
4217 * returns. This means we need to docode the va_list linearly
4218 * in a single stackframe. We hence implement our own
4219 * home-grown stack in an array. */
4220
4221 n_array = (unsigned) -1; /* length of current array entries */
4222 n_struct = strlen(types); /* length of current struct contents signature */
4223
4224 for (;;) {
4225 const char *t;
4226
4227 n_loop++;
4228
4229 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4230 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4231 if (r < 0)
4232 return r;
4233 if (r == 0)
4234 break;
4235
4236 r = sd_bus_message_exit_container(m);
4237 if (r < 0)
4238 return r;
4239
4240 continue;
4241 }
4242
4243 t = types;
4244 if (n_array != (unsigned) -1)
4245 n_array --;
4246 else {
4247 types ++;
4248 n_struct--;
4249 }
4250
4251 switch (*t) {
4252
4253 case SD_BUS_TYPE_BYTE:
4254 case SD_BUS_TYPE_BOOLEAN:
4255 case SD_BUS_TYPE_INT16:
4256 case SD_BUS_TYPE_UINT16:
4257 case SD_BUS_TYPE_INT32:
4258 case SD_BUS_TYPE_UINT32:
4259 case SD_BUS_TYPE_INT64:
4260 case SD_BUS_TYPE_UINT64:
4261 case SD_BUS_TYPE_DOUBLE:
4262 case SD_BUS_TYPE_STRING:
4263 case SD_BUS_TYPE_OBJECT_PATH:
4264 case SD_BUS_TYPE_SIGNATURE:
4265 case SD_BUS_TYPE_UNIX_FD: {
4266 void *p;
4267
4268 p = va_arg(ap, void*);
4269 r = sd_bus_message_read_basic(m, *t, p);
4270 if (r < 0)
4271 return r;
4272 if (r == 0) {
4273 if (n_loop <= 1)
4274 return 0;
4275
4276 return -ENXIO;
4277 }
4278
4279 break;
4280 }
4281
4282 case SD_BUS_TYPE_ARRAY: {
4283 size_t k;
4284
4285 r = signature_element_length(t + 1, &k);
4286 if (r < 0)
4287 return r;
4288
4289 {
4290 char s[k + 1];
4291 memcpy(s, t + 1, k);
4292 s[k] = 0;
4293
4294 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4295 if (r < 0)
4296 return r;
4297 if (r == 0) {
4298 if (n_loop <= 1)
4299 return 0;
4300
4301 return -ENXIO;
4302 }
4303 }
4304
4305 if (n_array == (unsigned) -1) {
4306 types += k;
4307 n_struct -= k;
4308 }
4309
4310 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4311 if (r < 0)
4312 return r;
4313
4314 types = t + 1;
4315 n_struct = k;
4316 n_array = va_arg(ap, unsigned);
4317
4318 break;
4319 }
4320
4321 case SD_BUS_TYPE_VARIANT: {
4322 const char *s;
4323
4324 s = va_arg(ap, const char *);
4325 if (!s)
4326 return -EINVAL;
4327
4328 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4329 if (r < 0)
4330 return r;
4331 if (r == 0) {
4332 if (n_loop <= 1)
4333 return 0;
4334
4335 return -ENXIO;
4336 }
4337
4338 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4339 if (r < 0)
4340 return r;
4341
4342 types = s;
4343 n_struct = strlen(s);
4344 n_array = (unsigned) -1;
4345
4346 break;
4347 }
4348
4349 case SD_BUS_TYPE_STRUCT_BEGIN:
4350 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4351 size_t k;
4352
4353 r = signature_element_length(t, &k);
4354 if (r < 0)
4355 return r;
4356
4357 {
4358 char s[k - 1];
4359 memcpy(s, t + 1, k - 2);
4360 s[k - 2] = 0;
4361
4362 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4363 if (r < 0)
4364 return r;
4365 if (r == 0) {
4366 if (n_loop <= 1)
4367 return 0;
4368 return -ENXIO;
4369 }
4370 }
4371
4372 if (n_array == (unsigned) -1) {
4373 types += k - 1;
4374 n_struct -= k - 1;
4375 }
4376
4377 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4378 if (r < 0)
4379 return r;
4380
4381 types = t + 1;
4382 n_struct = k - 2;
4383 n_array = (unsigned) -1;
4384
4385 break;
4386 }
4387
4388 default:
4389 return -EINVAL;
4390 }
4391 }
4392
4393 return 1;
4394 }
4395
4396 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4397 va_list ap;
4398 int r;
4399
4400 assert_return(m, -EINVAL);
4401 assert_return(m->sealed, -EPERM);
4402 assert_return(types, -EINVAL);
4403
4404 va_start(ap, types);
4405 r = message_read_ap(m, types, ap);
4406 va_end(ap);
4407
4408 return r;
4409 }
4410
4411 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4412 int r;
4413
4414 assert_return(m, -EINVAL);
4415 assert_return(m->sealed, -EPERM);
4416 assert_return(types, -EINVAL);
4417
4418 if (isempty(types))
4419 return 0;
4420
4421 switch (*types) {
4422
4423 case SD_BUS_TYPE_BYTE:
4424 case SD_BUS_TYPE_BOOLEAN:
4425 case SD_BUS_TYPE_INT16:
4426 case SD_BUS_TYPE_UINT16:
4427 case SD_BUS_TYPE_INT32:
4428 case SD_BUS_TYPE_UINT32:
4429 case SD_BUS_TYPE_INT64:
4430 case SD_BUS_TYPE_UINT64:
4431 case SD_BUS_TYPE_DOUBLE:
4432 case SD_BUS_TYPE_STRING:
4433 case SD_BUS_TYPE_OBJECT_PATH:
4434 case SD_BUS_TYPE_SIGNATURE:
4435 case SD_BUS_TYPE_UNIX_FD:
4436
4437 r = sd_bus_message_read_basic(m, *types, NULL);
4438 if (r <= 0)
4439 return r;
4440
4441 r = sd_bus_message_skip(m, types + 1);
4442 if (r < 0)
4443 return r;
4444
4445 return 1;
4446
4447 case SD_BUS_TYPE_ARRAY: {
4448 size_t k;
4449
4450 r = signature_element_length(types + 1, &k);
4451 if (r < 0)
4452 return r;
4453
4454 {
4455 char s[k+1];
4456 memcpy(s, types+1, k);
4457 s[k] = 0;
4458
4459 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4460 if (r <= 0)
4461 return r;
4462
4463 for (;;) {
4464 r = sd_bus_message_skip(m, s);
4465 if (r < 0)
4466 return r;
4467 if (r == 0)
4468 break;
4469 }
4470
4471 r = sd_bus_message_exit_container(m);
4472 if (r < 0)
4473 return r;
4474 }
4475
4476 r = sd_bus_message_skip(m, types + 1 + k);
4477 if (r < 0)
4478 return r;
4479
4480 return 1;
4481 }
4482
4483 case SD_BUS_TYPE_VARIANT: {
4484 const char *contents;
4485 char x;
4486
4487 r = sd_bus_message_peek_type(m, &x, &contents);
4488 if (r <= 0)
4489 return r;
4490
4491 if (x != SD_BUS_TYPE_VARIANT)
4492 return -ENXIO;
4493
4494 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4495 if (r <= 0)
4496 return r;
4497
4498 r = sd_bus_message_skip(m, contents);
4499 if (r < 0)
4500 return r;
4501 assert(r != 0);
4502
4503 r = sd_bus_message_exit_container(m);
4504 if (r < 0)
4505 return r;
4506
4507 r = sd_bus_message_skip(m, types + 1);
4508 if (r < 0)
4509 return r;
4510
4511 return 1;
4512 }
4513
4514 case SD_BUS_TYPE_STRUCT_BEGIN:
4515 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4516 size_t k;
4517
4518 r = signature_element_length(types, &k);
4519 if (r < 0)
4520 return r;
4521
4522 {
4523 char s[k-1];
4524 memcpy(s, types+1, k-2);
4525 s[k-2] = 0;
4526
4527 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4528 if (r <= 0)
4529 return r;
4530
4531 r = sd_bus_message_skip(m, s);
4532 if (r < 0)
4533 return r;
4534 assert(r != 0);
4535
4536 r = sd_bus_message_exit_container(m);
4537 if (r < 0)
4538 return r;
4539 }
4540
4541 r = sd_bus_message_skip(m, types + k);
4542 if (r < 0)
4543 return r;
4544
4545 return 1;
4546 }
4547
4548 default:
4549 return -EINVAL;
4550 }
4551 }
4552
4553 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4554 char type,
4555 const void **ptr,
4556 size_t *size) {
4557 struct bus_container *c;
4558 void *p;
4559 size_t sz;
4560 ssize_t align;
4561 int r;
4562
4563 assert_return(m, -EINVAL);
4564 assert_return(m->sealed, -EPERM);
4565 assert_return(bus_type_is_trivial(type), -EINVAL);
4566 assert_return(ptr, -EINVAL);
4567 assert_return(size, -EINVAL);
4568 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4569
4570 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4571 if (r <= 0)
4572 return r;
4573
4574 c = message_get_container(m);
4575
4576 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4577 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4578 if (align < 0)
4579 return align;
4580
4581 sz = c->end - c->begin;
4582 } else {
4583 align = bus_type_get_alignment(type);
4584 if (align < 0)
4585 return align;
4586
4587 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4588 }
4589
4590 if (sz == 0)
4591 /* Zero length array, let's return some aligned
4592 * pointer that is not NULL */
4593 p = (uint8_t*) NULL + align;
4594 else {
4595 r = message_peek_body(m, &m->rindex, align, sz, &p);
4596 if (r < 0)
4597 goto fail;
4598 }
4599
4600 r = sd_bus_message_exit_container(m);
4601 if (r < 0)
4602 goto fail;
4603
4604 *ptr = (const void*) p;
4605 *size = sz;
4606
4607 return 1;
4608
4609 fail:
4610 message_quit_container(m);
4611 return r;
4612 }
4613
4614 static int message_peek_fields(
4615 sd_bus_message *m,
4616 size_t *rindex,
4617 size_t align,
4618 size_t nbytes,
4619 void **ret) {
4620
4621 assert(m);
4622 assert(rindex);
4623 assert(align > 0);
4624
4625 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4626 }
4627
4628 static int message_peek_field_uint32(
4629 sd_bus_message *m,
4630 size_t *ri,
4631 size_t item_size,
4632 uint32_t *ret) {
4633
4634 int r;
4635 void *q;
4636
4637 assert(m);
4638 assert(ri);
4639
4640 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4641 return -EBADMSG;
4642
4643 /* identical for gvariant and dbus1 */
4644
4645 r = message_peek_fields(m, ri, 4, 4, &q);
4646 if (r < 0)
4647 return r;
4648
4649 if (ret)
4650 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4651
4652 return 0;
4653 }
4654
4655 static int message_peek_field_string(
4656 sd_bus_message *m,
4657 bool (*validate)(const char *p),
4658 size_t *ri,
4659 size_t item_size,
4660 const char **ret) {
4661
4662 uint32_t l;
4663 int r;
4664 void *q;
4665
4666 assert(m);
4667 assert(ri);
4668
4669 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4670
4671 if (item_size <= 0)
4672 return -EBADMSG;
4673
4674 r = message_peek_fields(m, ri, 1, item_size, &q);
4675 if (r < 0)
4676 return r;
4677
4678 l = item_size - 1;
4679 } else {
4680 r = message_peek_field_uint32(m, ri, 4, &l);
4681 if (r < 0)
4682 return r;
4683
4684 r = message_peek_fields(m, ri, 1, l+1, &q);
4685 if (r < 0)
4686 return r;
4687 }
4688
4689 if (validate) {
4690 if (!validate_nul(q, l))
4691 return -EBADMSG;
4692
4693 if (!validate(q))
4694 return -EBADMSG;
4695 } else {
4696 if (!validate_string(q, l))
4697 return -EBADMSG;
4698 }
4699
4700 if (ret)
4701 *ret = q;
4702
4703 return 0;
4704 }
4705
4706 static int message_peek_field_signature(
4707 sd_bus_message *m,
4708 size_t *ri,
4709 size_t item_size,
4710 const char **ret) {
4711
4712 size_t l;
4713 int r;
4714 void *q;
4715
4716 assert(m);
4717 assert(ri);
4718
4719 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4720
4721 if (item_size <= 0)
4722 return -EBADMSG;
4723
4724 r = message_peek_fields(m, ri, 1, item_size, &q);
4725 if (r < 0)
4726 return r;
4727
4728 l = item_size - 1;
4729 } else {
4730 r = message_peek_fields(m, ri, 1, 1, &q);
4731 if (r < 0)
4732 return r;
4733
4734 l = *(uint8_t*) q;
4735 r = message_peek_fields(m, ri, 1, l+1, &q);
4736 if (r < 0)
4737 return r;
4738 }
4739
4740 if (!validate_signature(q, l))
4741 return -EBADMSG;
4742
4743 if (ret)
4744 *ret = q;
4745
4746 return 0;
4747 }
4748
4749 static int message_skip_fields(
4750 sd_bus_message *m,
4751 size_t *ri,
4752 uint32_t array_size,
4753 const char **signature) {
4754
4755 size_t original_index;
4756 int r;
4757
4758 assert(m);
4759 assert(ri);
4760 assert(signature);
4761 assert(!BUS_MESSAGE_IS_GVARIANT(m));
4762
4763 original_index = *ri;
4764
4765 for (;;) {
4766 char t;
4767 size_t l;
4768
4769 if (array_size != (uint32_t) -1 &&
4770 array_size <= *ri - original_index)
4771 return 0;
4772
4773 t = **signature;
4774 if (!t)
4775 return 0;
4776
4777 if (t == SD_BUS_TYPE_STRING) {
4778
4779 r = message_peek_field_string(m, NULL, ri, 0, NULL);
4780 if (r < 0)
4781 return r;
4782
4783 (*signature)++;
4784
4785 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4786
4787 r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4788 if (r < 0)
4789 return r;
4790
4791 (*signature)++;
4792
4793 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4794
4795 r = message_peek_field_signature(m, ri, 0, NULL);
4796 if (r < 0)
4797 return r;
4798
4799 (*signature)++;
4800
4801 } else if (bus_type_is_basic(t)) {
4802 ssize_t align, k;
4803
4804 align = bus_type_get_alignment(t);
4805 k = bus_type_get_size(t);
4806 assert(align > 0 && k > 0);
4807
4808 r = message_peek_fields(m, ri, align, k, NULL);
4809 if (r < 0)
4810 return r;
4811
4812 (*signature)++;
4813
4814 } else if (t == SD_BUS_TYPE_ARRAY) {
4815
4816 r = signature_element_length(*signature+1, &l);
4817 if (r < 0)
4818 return r;
4819
4820 assert(l >= 1);
4821 {
4822 char sig[l-1], *s;
4823 uint32_t nas;
4824 int alignment;
4825
4826 strncpy(sig, *signature + 1, l-1);
4827 s = sig;
4828
4829 alignment = bus_type_get_alignment(sig[0]);
4830 if (alignment < 0)
4831 return alignment;
4832
4833 r = message_peek_field_uint32(m, ri, 0, &nas);
4834 if (r < 0)
4835 return r;
4836 if (nas > BUS_ARRAY_MAX_SIZE)
4837 return -EBADMSG;
4838
4839 r = message_peek_fields(m, ri, alignment, 0, NULL);
4840 if (r < 0)
4841 return r;
4842
4843 r = message_skip_fields(m, ri, nas, (const char**) &s);
4844 if (r < 0)
4845 return r;
4846 }
4847
4848 (*signature) += 1 + l;
4849
4850 } else if (t == SD_BUS_TYPE_VARIANT) {
4851 const char *s;
4852
4853 r = message_peek_field_signature(m, ri, 0, &s);
4854 if (r < 0)
4855 return r;
4856
4857 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4858 if (r < 0)
4859 return r;
4860
4861 (*signature)++;
4862
4863 } else if (t == SD_BUS_TYPE_STRUCT ||
4864 t == SD_BUS_TYPE_DICT_ENTRY) {
4865
4866 r = signature_element_length(*signature, &l);
4867 if (r < 0)
4868 return r;
4869
4870 assert(l >= 2);
4871 {
4872 char sig[l-1], *s;
4873 strncpy(sig, *signature + 1, l-1);
4874 s = sig;
4875
4876 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4877 if (r < 0)
4878 return r;
4879 }
4880
4881 *signature += l;
4882 } else
4883 return -EINVAL;
4884 }
4885 }
4886
4887 int bus_message_parse_fields(sd_bus_message *m) {
4888 size_t ri;
4889 int r;
4890 uint32_t unix_fds = 0;
4891 bool unix_fds_set = false;
4892 void *offsets = NULL;
4893 unsigned n_offsets = 0;
4894 size_t sz = 0;
4895 unsigned i = 0;
4896
4897 assert(m);
4898
4899 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4900 void *q;
4901
4902 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4903 if (sz > 0) {
4904 size_t framing;
4905
4906 ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4907 r = message_peek_fields(m, &ri, 1, sz, &q);
4908 if (r < 0)
4909 return r;
4910
4911 framing = read_word_le(q, sz);
4912 if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4913 return -EBADMSG;
4914 if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4915 return -EBADMSG;
4916
4917 ri = framing;
4918 r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4919 if (r < 0)
4920 return r;
4921
4922 n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4923 }
4924 }
4925
4926 ri = 0;
4927 while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4928 _cleanup_free_ char *sig = NULL;
4929 const char *signature;
4930 uint8_t *header;
4931 size_t item_size = (size_t) -1;
4932
4933 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4934 if (i >= n_offsets)
4935 break;
4936
4937 if (i == 0)
4938 ri = 0;
4939 else
4940 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4941 }
4942
4943 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4944 if (r < 0)
4945 return r;
4946
4947 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4948 size_t where, end;
4949 char *b;
4950 void *q;
4951
4952 end = read_word_le((uint8_t*) offsets + i*sz, sz);
4953
4954 if (end < ri)
4955 return -EBADMSG;
4956
4957 where = ri = ALIGN_TO(ri, 8);
4958 item_size = end - ri;
4959 r = message_peek_fields(m, &where, 1, item_size, &q);
4960 if (r < 0)
4961 return r;
4962
4963 b = memrchr(q, 0, item_size);
4964 if (!b)
4965 return -EBADMSG;
4966
4967 sig = strndup(b+1, item_size - (b+1-(char*) q));
4968 if (!sig)
4969 return -ENOMEM;
4970
4971 signature = sig;
4972 item_size = b - (char*) q;
4973 } else {
4974 r = message_peek_field_signature(m, &ri, 0, &signature);
4975 if (r < 0)
4976 return r;
4977 }
4978
4979 switch (*header) {
4980 case _BUS_MESSAGE_HEADER_INVALID:
4981 return -EBADMSG;
4982
4983 case BUS_MESSAGE_HEADER_PATH:
4984
4985 if (m->path)
4986 return -EBADMSG;
4987
4988 if (!streq(signature, "o"))
4989 return -EBADMSG;
4990
4991 r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4992 break;
4993
4994 case BUS_MESSAGE_HEADER_INTERFACE:
4995
4996 if (m->interface)
4997 return -EBADMSG;
4998
4999 if (!streq(signature, "s"))
5000 return -EBADMSG;
5001
5002 r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5003 break;
5004
5005 case BUS_MESSAGE_HEADER_MEMBER:
5006
5007 if (m->member)
5008 return -EBADMSG;
5009
5010 if (!streq(signature, "s"))
5011 return -EBADMSG;
5012
5013 r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5014 break;
5015
5016 case BUS_MESSAGE_HEADER_ERROR_NAME:
5017
5018 if (m->error.name)
5019 return -EBADMSG;
5020
5021 if (!streq(signature, "s"))
5022 return -EBADMSG;
5023
5024 r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5025 if (r >= 0)
5026 m->error._need_free = -1;
5027
5028 break;
5029
5030 case BUS_MESSAGE_HEADER_DESTINATION:
5031
5032 if (m->destination)
5033 return -EBADMSG;
5034
5035 if (!streq(signature, "s"))
5036 return -EBADMSG;
5037
5038 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5039 break;
5040
5041 case BUS_MESSAGE_HEADER_SENDER:
5042
5043 if (m->sender)
5044 return -EBADMSG;
5045
5046 if (!streq(signature, "s"))
5047 return -EBADMSG;
5048
5049 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5050
5051 if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5052 m->creds.unique_name = (char*) m->sender;
5053 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5054 }
5055
5056 break;
5057
5058
5059 case BUS_MESSAGE_HEADER_SIGNATURE: {
5060 const char *s;
5061 char *c;
5062
5063 if (m->root_container.signature)
5064 return -EBADMSG;
5065
5066 if (!streq(signature, "g"))
5067 return -EBADMSG;
5068
5069 r = message_peek_field_signature(m, &ri, item_size, &s);
5070 if (r < 0)
5071 return r;
5072
5073 c = strdup(s);
5074 if (!c)
5075 return -ENOMEM;
5076
5077 free(m->root_container.signature);
5078 m->root_container.signature = c;
5079 break;
5080 }
5081
5082 case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
5083 uint32_t serial;
5084
5085 if (m->reply_cookie != 0)
5086 return -EBADMSG;
5087
5088 if (!streq(signature, "u"))
5089 return -EBADMSG;
5090
5091 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5092 if (r < 0)
5093 return r;
5094
5095 m->reply_cookie = serial;
5096
5097 if (m->reply_cookie == 0)
5098 return -EBADMSG;
5099
5100 break;
5101 }
5102
5103 case BUS_MESSAGE_HEADER_UNIX_FDS:
5104 if (unix_fds_set)
5105 return -EBADMSG;
5106
5107 if (!streq(signature, "u"))
5108 return -EBADMSG;
5109
5110 r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5111 if (r < 0)
5112 return -EBADMSG;
5113
5114 unix_fds_set = true;
5115 break;
5116
5117 default:
5118 if (!BUS_MESSAGE_IS_GVARIANT(m))
5119 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5120 }
5121
5122 if (r < 0)
5123 return r;
5124
5125 i++;
5126 }
5127
5128 if (m->n_fds != unix_fds)
5129 return -EBADMSG;
5130
5131 switch (m->header->type) {
5132
5133 case SD_BUS_MESSAGE_SIGNAL:
5134 if (!m->path || !m->interface || !m->member)
5135 return -EBADMSG;
5136 break;
5137
5138 case SD_BUS_MESSAGE_METHOD_CALL:
5139
5140 if (!m->path || !m->member)
5141 return -EBADMSG;
5142
5143 break;
5144
5145 case SD_BUS_MESSAGE_METHOD_RETURN:
5146
5147 if (m->reply_cookie == 0)
5148 return -EBADMSG;
5149 break;
5150
5151 case SD_BUS_MESSAGE_METHOD_ERROR:
5152
5153 if (m->reply_cookie == 0 || !m->error.name)
5154 return -EBADMSG;
5155 break;
5156 }
5157
5158 /* Refuse non-local messages that claim they are local */
5159 if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5160 return -EBADMSG;
5161 if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5162 return -EBADMSG;
5163 if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5164 return -EBADMSG;
5165
5166 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5167
5168 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5169 r = build_struct_offsets(
5170 m,
5171 m->root_container.signature,
5172 BUS_MESSAGE_BODY_SIZE(m),
5173 &m->root_container.item_size,
5174 &m->root_container.offsets,
5175 &m->root_container.n_offsets);
5176 if (r < 0)
5177 return r;
5178 }
5179
5180 /* Try to read the error message, but if we can't it's a non-issue */
5181 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5182 sd_bus_message_read(m, "s", &m->error.message);
5183
5184 return 0;
5185 }
5186
5187 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5188 assert_return(m, -EINVAL);
5189 assert_return(destination, -EINVAL);
5190 assert_return(!m->sealed, -EPERM);
5191 assert_return(!m->destination, -EEXIST);
5192
5193 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5194 }
5195
5196 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5197 size_t total;
5198 void *p, *e;
5199 unsigned i;
5200 struct bus_body_part *part;
5201
5202 assert(m);
5203 assert(buffer);
5204 assert(sz);
5205
5206 total = BUS_MESSAGE_SIZE(m);
5207
5208 p = malloc(total);
5209 if (!p)
5210 return -ENOMEM;
5211
5212 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5213 MESSAGE_FOREACH_PART(part, i, m)
5214 e = mempcpy(e, part->data, part->size);
5215
5216 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5217
5218 *buffer = p;
5219 *sz = total;
5220
5221 return 0;
5222 }
5223
5224 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5225 int r;
5226
5227 assert(m);
5228 assert(l);
5229
5230 r = sd_bus_message_enter_container(m, 'a', "s");
5231 if (r <= 0)
5232 return r;
5233
5234 for (;;) {
5235 const char *s;
5236
5237 r = sd_bus_message_read_basic(m, 's', &s);
5238 if (r < 0)
5239 return r;
5240 if (r == 0)
5241 break;
5242
5243 r = strv_extend(l, s);
5244 if (r < 0)
5245 return r;
5246 }
5247
5248 r = sd_bus_message_exit_container(m);
5249 if (r < 0)
5250 return r;
5251
5252 return 1;
5253 }
5254
5255 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5256 char **strv = NULL;
5257 int r;
5258
5259 assert_return(m, -EINVAL);
5260 assert_return(m->sealed, -EPERM);
5261 assert_return(l, -EINVAL);
5262
5263 r = bus_message_read_strv_extend(m, &strv);
5264 if (r <= 0) {
5265 strv_free(strv);
5266 return r;
5267 }
5268
5269 *l = strv;
5270 return 1;
5271 }
5272
5273 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5274 int r;
5275 const char *t = NULL;
5276 unsigned j;
5277
5278 assert(m);
5279
5280 r = sd_bus_message_rewind(m, true);
5281 if (r < 0)
5282 return NULL;
5283
5284 for (j = 0; j <= i; j++) {
5285 char type;
5286
5287 r = sd_bus_message_peek_type(m, &type, NULL);
5288 if (r < 0)
5289 return NULL;
5290
5291 if (type != SD_BUS_TYPE_STRING &&
5292 type != SD_BUS_TYPE_OBJECT_PATH &&
5293 type != SD_BUS_TYPE_SIGNATURE)
5294 return NULL;
5295
5296 r = sd_bus_message_read_basic(m, type, &t);
5297 if (r < 0)
5298 return NULL;
5299 }
5300
5301 return t;
5302 }
5303
5304 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5305 size_t full;
5306
5307 assert(h);
5308 assert(size);
5309
5310 if (size < sizeof(struct bus_header))
5311 return false;
5312
5313 full = sizeof(struct bus_header) +
5314 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5315
5316 return size >= full;
5317 }
5318
5319 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5320 size_t fs, bs;
5321
5322 assert(h);
5323 assert(sum);
5324
5325 if (h->endian == BUS_NATIVE_ENDIAN) {
5326 fs = h->fields_size;
5327 bs = h->body_size;
5328 } else if (h->endian == BUS_REVERSE_ENDIAN) {
5329 fs = bswap_32(h->fields_size);
5330 bs = bswap_32(h->body_size);
5331 } else
5332 return -EBADMSG;
5333
5334 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5335 return 0;
5336 }
5337
5338 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5339 assert_return(m, -EINVAL);
5340
5341 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5342 return 0;
5343
5344 return sd_bus_error_get_errno(&m->error);
5345 }
5346
5347 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5348 struct bus_container *c;
5349
5350 assert_return(m, NULL);
5351
5352 c = complete ? &m->root_container : message_get_container(m);
5353 return strempty(c->signature);
5354 }
5355
5356 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5357 bool done_something = false;
5358 int r;
5359
5360 assert_return(m, -EINVAL);
5361 assert_return(source, -EINVAL);
5362 assert_return(!m->sealed, -EPERM);
5363 assert_return(source->sealed, -EPERM);
5364
5365 do {
5366 const char *contents;
5367 char type;
5368 union {
5369 uint8_t u8;
5370 uint16_t u16;
5371 int16_t s16;
5372 uint32_t u32;
5373 int32_t s32;
5374 uint64_t u64;
5375 int64_t s64;
5376 double d64;
5377 const char *string;
5378 int i;
5379 } basic;
5380
5381 r = sd_bus_message_peek_type(source, &type, &contents);
5382 if (r < 0)
5383 return r;
5384 if (r == 0)
5385 break;
5386
5387 done_something = true;
5388
5389 if (bus_type_is_container(type) > 0) {
5390
5391 r = sd_bus_message_enter_container(source, type, contents);
5392 if (r < 0)
5393 return r;
5394
5395 r = sd_bus_message_open_container(m, type, contents);
5396 if (r < 0)
5397 return r;
5398
5399 r = sd_bus_message_copy(m, source, true);
5400 if (r < 0)
5401 return r;
5402
5403 r = sd_bus_message_close_container(m);
5404 if (r < 0)
5405 return r;
5406
5407 r = sd_bus_message_exit_container(source);
5408 if (r < 0)
5409 return r;
5410
5411 continue;
5412 }
5413
5414 r = sd_bus_message_read_basic(source, type, &basic);
5415 if (r < 0)
5416 return r;
5417
5418 assert(r > 0);
5419
5420 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5421 type == SD_BUS_TYPE_SIGNATURE ||
5422 type == SD_BUS_TYPE_STRING)
5423 r = sd_bus_message_append_basic(m, type, basic.string);
5424 else
5425 r = sd_bus_message_append_basic(m, type, &basic);
5426
5427 if (r < 0)
5428 return r;
5429
5430 } while (all);
5431
5432 return done_something;
5433 }
5434
5435 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5436 const char *c;
5437 char t;
5438 int r;
5439
5440 assert_return(m, -EINVAL);
5441 assert_return(m->sealed, -EPERM);
5442 assert_return(!type || bus_type_is_valid(type), -EINVAL);
5443 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5444 assert_return(type || contents, -EINVAL);
5445 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5446
5447 r = sd_bus_message_peek_type(m, &t, &c);
5448 if (r <= 0)
5449 return r;
5450
5451 if (type != 0 && type != t)
5452 return 0;
5453
5454 if (contents && !streq_ptr(contents, c))
5455 return 0;
5456
5457 return 1;
5458 }
5459
5460 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5461 assert_return(m, NULL);
5462
5463 return m->bus;
5464 }
5465
5466 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5467 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5468 usec_t timeout;
5469 int r;
5470
5471 assert(bus);
5472 assert(m);
5473 assert(*m);
5474
5475 switch ((*m)->header->type) {
5476
5477 case SD_BUS_MESSAGE_SIGNAL:
5478 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5479 if (r < 0)
5480 return r;
5481
5482 break;
5483
5484 case SD_BUS_MESSAGE_METHOD_CALL:
5485 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5486 if (r < 0)
5487 return r;
5488
5489 break;
5490
5491 case SD_BUS_MESSAGE_METHOD_RETURN:
5492 case SD_BUS_MESSAGE_METHOD_ERROR:
5493
5494 n = message_new(bus, (*m)->header->type);
5495 if (!n)
5496 return -ENOMEM;
5497
5498 n->reply_cookie = (*m)->reply_cookie;
5499 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
5500 if (r < 0)
5501 return r;
5502
5503 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5504 r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5505 if (r < 0)
5506 return r;
5507
5508 n->error._need_free = -1;
5509 }
5510
5511 break;
5512
5513 default:
5514 return -EINVAL;
5515 }
5516
5517 if ((*m)->destination && !n->destination) {
5518 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5519 if (r < 0)
5520 return r;
5521 }
5522
5523 if ((*m)->sender && !n->sender) {
5524 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5525 if (r < 0)
5526 return r;
5527 }
5528
5529 n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5530
5531 r = sd_bus_message_copy(n, *m, true);
5532 if (r < 0)
5533 return r;
5534
5535 timeout = (*m)->timeout;
5536 if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5537 timeout = BUS_DEFAULT_TIMEOUT;
5538
5539 r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5540 if (r < 0)
5541 return r;
5542
5543 sd_bus_message_unref(*m);
5544 *m = n;
5545 n = NULL;
5546
5547 return 0;
5548 }
5549
5550 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5551 assert(m);
5552 assert(sender);
5553
5554 assert_return(!m->sealed, -EPERM);
5555 assert_return(!m->sender, -EPERM);
5556
5557 return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5558 }
5559
5560 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5561 assert_return(m, -EINVAL);
5562 assert_return(priority, -EINVAL);
5563
5564 *priority = m->priority;
5565 return 0;
5566 }
5567
5568 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5569 assert_return(m, -EINVAL);
5570 assert_return(!m->sealed, -EPERM);
5571
5572 m->priority = priority;
5573 return 0;
5574 }