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