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