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