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