chiark / gitweb /
f7759b6fb498ea9f8c9926504124b86137139b80
[elogind.git] / src / libsystemd-bus / bus-kernel.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 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
24 #endif
25
26 #include <fcntl.h>
27 #include <malloc.h>
28 #include <sys/mman.h>
29
30 #include "util.h"
31
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-kernel.h"
35 #include "bus-bloom.h"
36
37 #define KDBUS_ITEM_NEXT(item) \
38         (typeof(item))(((uint8_t *)item) + ALIGN8((item)->size))
39
40 #define KDBUS_ITEM_FOREACH(item, head)                                          \
41         for (item = (head)->items;                                              \
42              (uint8_t *)(item) < (uint8_t *)(head) + (head)->size;              \
43              item = KDBUS_ITEM_NEXT(item))
44
45 #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
46 #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
47
48 #define KDBUS_POOL_SIZE (4*1024*1024)
49
50 static int parse_unique_name(const char *s, uint64_t *id) {
51         int r;
52
53         assert(s);
54         assert(id);
55
56         if (!startswith(s, ":1."))
57                 return 0;
58
59         r = safe_atou64(s + 3, id);
60         if (r < 0)
61                 return r;
62
63         return 1;
64 }
65
66 static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
67         assert(d);
68         assert(sz > 0);
69
70         *d = ALIGN8_PTR(*d);
71
72         (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
73         (*d)->type = KDBUS_MSG_PAYLOAD_VEC;
74         (*d)->vec.address = PTR_TO_UINT64(p);
75         (*d)->vec.size = sz;
76
77         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
78 }
79
80 static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
81         assert(d);
82         assert(memfd >= 0);
83         assert(sz > 0);
84
85         *d = ALIGN8_PTR(*d);
86         (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
87         (*d)->type = KDBUS_MSG_PAYLOAD_MEMFD;
88         (*d)->memfd.fd = memfd;
89         (*d)->memfd.size = sz;
90
91         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
92 }
93
94 static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
95         assert(d);
96         assert(s);
97
98         *d = ALIGN8_PTR(*d);
99
100         (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
101         (*d)->type = KDBUS_MSG_DST_NAME;
102         memcpy((*d)->str, s, length + 1);
103
104         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
105 }
106
107 static void* append_bloom(struct kdbus_item **d, size_t length) {
108         void *r;
109
110         assert(d);
111
112         *d = ALIGN8_PTR(*d);
113
114         (*d)->size = offsetof(struct kdbus_item, data) + length;
115         (*d)->type = KDBUS_MSG_BLOOM;
116         r = (*d)->data;
117
118         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
119
120         return r;
121 }
122
123 static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
124         assert(d);
125         assert(fds);
126         assert(n_fds > 0);
127
128         *d = ALIGN8_PTR(*d);
129         (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
130         (*d)->type = KDBUS_MSG_FDS;
131         memcpy((*d)->fds, fds, sizeof(int) * n_fds);
132
133         *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
134 }
135
136 static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) {
137         unsigned i;
138         int r;
139
140         assert(m);
141         assert(bloom);
142
143         memset(bloom, 0, BLOOM_SIZE);
144
145         bloom_add_pair(bloom, "message-type", bus_message_type_to_string(m->header->type));
146
147         if (m->interface)
148                 bloom_add_pair(bloom, "interface", m->interface);
149         if (m->member)
150                 bloom_add_pair(bloom, "member", m->member);
151         if (m->path) {
152                 bloom_add_pair(bloom, "path", m->path);
153                 bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/');
154         }
155
156         r = sd_bus_message_rewind(m, true);
157         if (r < 0)
158                 return r;
159
160         for (i = 0; i < 64; i++) {
161                 char type;
162                 const char *t;
163                 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
164                 char *e;
165
166                 r = sd_bus_message_peek_type(m, &type, NULL);
167                 if (r < 0)
168                         return r;
169
170                 if (type != SD_BUS_TYPE_STRING &&
171                     type != SD_BUS_TYPE_OBJECT_PATH &&
172                     type != SD_BUS_TYPE_SIGNATURE)
173                         break;
174
175                 r = sd_bus_message_read_basic(m, type, &t);
176                 if (r < 0)
177                         return r;
178
179                 e = stpcpy(buf, "arg");
180                 if (i < 10)
181                         *(e++) = '0' + i;
182                 else {
183                         *(e++) = '0' + (i / 10);
184                         *(e++) = '0' + (i % 10);
185                 }
186
187                 *e = 0;
188                 bloom_add_pair(bloom, buf, t);
189
190                 strcpy(e, "-dot-prefix");
191                 bloom_add_prefixes(bloom, buf, t, '.');
192                 strcpy(e, "-slash-prefix");
193                 bloom_add_prefixes(bloom, buf, t, '/');
194         }
195
196         return 0;
197 }
198
199 static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
200         struct bus_body_part *part;
201         struct kdbus_item *d;
202         bool well_known;
203         uint64_t unique;
204         size_t sz, dl;
205         unsigned i;
206         int r;
207
208         assert(b);
209         assert(m);
210         assert(m->sealed);
211
212         if (m->kdbus)
213                 return 0;
214
215         if (m->destination) {
216                 r = parse_unique_name(m->destination, &unique);
217                 if (r < 0)
218                         return r;
219
220                 well_known = r == 0;
221         } else
222                 well_known = false;
223
224         sz = offsetof(struct kdbus_msg, items);
225
226         assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
227                   ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
228
229         /* Add in fixed header, fields header and payload */
230         sz += (1 + m->n_body_parts) *
231                 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
232
233         /* Add space for bloom filter */
234         sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE);
235
236         /* Add in well-known destination header */
237         if (well_known) {
238                 dl = strlen(m->destination);
239                 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
240         }
241
242         /* Add space for unix fds */
243         if (m->n_fds > 0)
244                 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
245
246         m->kdbus = memalign(8, sz);
247         if (!m->kdbus)
248                 return -ENOMEM;
249
250         memset(m->kdbus, 0, sz);
251
252         m->kdbus->flags =
253                 ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
254                 ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
255         m->kdbus->dst_id =
256                 well_known ? 0 :
257                 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
258         m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS1;
259         m->kdbus->cookie = m->header->serial;
260
261         m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
262
263         d = m->kdbus->items;
264
265         if (well_known)
266                 append_destination(&d, m->destination, dl);
267
268         append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
269
270         MESSAGE_FOREACH_PART(part, i, m) {
271                 if (part->is_zero) {
272                         append_payload_vec(&d, NULL, part->size);
273                         continue;
274                 }
275
276                 if (part->memfd >= 0 && part->sealed) {
277                         bus_body_part_unmap(part);
278
279                         if (!part->data) {
280                                 append_payload_memfd(&d, part->memfd, part->size);
281                                 continue;
282                         }
283                 }
284
285                 if (part->memfd >= 0) {
286                         r = bus_body_part_map(part);
287                         if (r < 0)
288                                 goto fail;
289                 }
290
291                 append_payload_vec(&d, part->data, part->size);
292         }
293
294         if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
295                 void *p;
296
297                 p = append_bloom(&d, BLOOM_SIZE);
298                 r = bus_message_setup_bloom(m, p);
299                 if (r < 0)
300                         goto fail;
301         }
302
303         if (m->n_fds > 0)
304                 append_fds(&d, m->fds, m->n_fds);
305
306         m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
307         assert(m->kdbus->size <= sz);
308
309         m->free_kdbus = true;
310
311         return 0;
312
313 fail:
314         free(m->kdbus);
315         m->kdbus = NULL;
316         return r;
317 }
318
319 int bus_kernel_take_fd(sd_bus *b) {
320         uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
321                   ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
322                   ALIGN8(sizeof(struct kdbus_vec))] = {};
323
324         struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
325
326         int r;
327
328         assert(b);
329
330         if (b->is_server)
331                 return -EINVAL;
332
333         if (!b->kdbus_buffer) {
334                 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
335                 if (b->kdbus_buffer == MAP_FAILED) {
336                         b->kdbus_buffer = NULL;
337                         return -errno;
338                 }
339         }
340
341         hello->size = sizeof(h);
342         hello->conn_flags =
343                 KDBUS_HELLO_ACCEPT_FD|
344                 KDBUS_HELLO_ATTACH_COMM|
345                 KDBUS_HELLO_ATTACH_EXE|
346                 KDBUS_HELLO_ATTACH_CMDLINE|
347                 KDBUS_HELLO_ATTACH_CGROUP|
348                 KDBUS_HELLO_ATTACH_CAPS|
349                 KDBUS_HELLO_ATTACH_SECLABEL|
350                 KDBUS_HELLO_ATTACH_AUDIT;
351
352         hello->items[0].type = KDBUS_HELLO_POOL;
353         hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
354         hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
355         hello->items[0].vec.size = KDBUS_POOL_SIZE;
356
357         r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
358         if (r < 0)
359                 return -errno;
360
361         /* The higher 32bit of both flags fields are considered
362          * 'incompatible flags'. Refuse them all for now. */
363         if (hello->bus_flags > 0xFFFFFFFFULL ||
364             hello->conn_flags > 0xFFFFFFFFULL)
365                 return -ENOTSUP;
366
367         if (hello->bloom_size != BLOOM_SIZE)
368                 return -ENOTSUP;
369
370         if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
371                 return -ENOMEM;
372
373         b->is_kernel = true;
374         b->bus_client = true;
375         b->can_fds = true;
376
377         r = bus_start_running(b);
378         if (r < 0)
379                 return r;
380
381         return 1;
382 }
383
384 int bus_kernel_connect(sd_bus *b) {
385         assert(b);
386         assert(b->input_fd < 0);
387         assert(b->output_fd < 0);
388         assert(b->kernel);
389
390         if (b->is_server)
391                 return -EINVAL;
392
393         b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
394         if (b->input_fd < 0)
395                 return -errno;
396
397         b->output_fd = b->input_fd;
398
399         return bus_kernel_take_fd(b);
400 }
401
402 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
403         int r;
404
405         assert(bus);
406         assert(m);
407         assert(bus->state == BUS_RUNNING);
408
409         r = bus_message_setup_kmsg(bus, m);
410         if (r < 0)
411                 return r;
412
413         r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
414         if (r < 0)
415                 return errno == EAGAIN ? 0 : -errno;
416
417         return 1;
418 }
419
420 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
421         struct kdbus_item *d;
422
423         assert(bus);
424         assert(k);
425
426         ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
427
428         KDBUS_ITEM_FOREACH(d, k) {
429
430                 if (d->type == KDBUS_MSG_FDS)
431                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
432                 else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD)
433                         close_nointr_nofail(d->memfd.fd);
434         }
435 }
436
437 static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) {
438         sd_bus_message *m = NULL;
439         struct kdbus_item *d;
440         unsigned n_fds = 0;
441         _cleanup_free_ int *fds = NULL;
442         struct bus_header *h = NULL;
443         size_t total, n_bytes = 0, idx = 0;
444         const char *destination = NULL, *seclabel = NULL;
445         int r;
446
447         assert(bus);
448         assert(k);
449         assert(ret);
450
451         if (k->payload_type != KDBUS_PAYLOAD_DBUS1)
452                 return 0;
453
454         KDBUS_ITEM_FOREACH(d, k) {
455                 size_t l;
456
457                 l = d->size - offsetof(struct kdbus_item, data);
458
459                 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
460
461                         if (!h) {
462                                 h = UINT64_TO_PTR(d->vec.address);
463
464                                 if (!bus_header_is_complete(h, d->vec.size))
465                                         return -EBADMSG;
466                         }
467
468                         n_bytes += d->vec.size;
469
470                 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
471
472                         if (!h)
473                                 return -EBADMSG;
474
475                         n_bytes += d->memfd.size;
476
477                 } else if (d->type == KDBUS_MSG_FDS) {
478                         int *f;
479                         unsigned j;
480
481                         j = l / sizeof(int);
482                         f = realloc(fds, sizeof(int) * (n_fds + j));
483                         if (!f)
484                                 return -ENOMEM;
485
486                         fds = f;
487                         memcpy(fds + n_fds, d->fds, sizeof(int) * j);
488                         n_fds += j;
489
490                 } else if (d->type == KDBUS_MSG_SRC_SECLABEL)
491                         seclabel = d->str;
492         }
493
494         if (!h)
495                 return -EBADMSG;
496
497         r = bus_header_message_size(h, &total);
498         if (r < 0)
499                 return r;
500
501         if (n_bytes != total)
502                 return -EBADMSG;
503
504         r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
505         if (r < 0)
506                 return r;
507
508         KDBUS_ITEM_FOREACH(d, k) {
509                 size_t l;
510
511                 l = d->size - offsetof(struct kdbus_item, data);
512
513                 if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
514                         size_t begin_body;
515
516                         begin_body = BUS_MESSAGE_BODY_BEGIN(m);
517
518                         if (idx + d->vec.size > begin_body) {
519                                 struct bus_body_part *part;
520
521                                 /* Contains body material */
522
523                                 part = message_append_part(m);
524                                 if (!part) {
525                                         r = -ENOMEM;
526                                         goto fail;
527                                 }
528
529                                 if (idx >= begin_body) {
530                                         part->data = UINT64_TO_PTR(d->vec.address);
531                                         part->size = d->vec.size;
532                                 } else {
533                                         part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
534                                         part->size = d->vec.size - (begin_body - idx);
535                                 }
536
537                                 part->is_zero = d->vec.address == 0;
538                                 part->sealed = true;
539                         }
540
541                         idx += d->vec.size;
542                 } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) {
543                         struct bus_body_part *part;
544
545                         if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
546                                 r = -EBADMSG;
547                                 goto fail;
548                         }
549
550                         part = message_append_part(m);
551                         if (!part) {
552                                 r = -ENOMEM;
553                                 goto fail;
554                         }
555
556                         part->memfd = d->memfd.fd;
557                         part->size = d->memfd.size;
558                         part->sealed = true;
559
560                         idx += d->memfd.size;
561
562                 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
563                         m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
564                         m->uid = d->creds.uid;
565                         m->gid = d->creds.gid;
566                         m->pid = d->creds.pid;
567                         m->tid = d->creds.tid;
568                         m->uid_valid = m->gid_valid = true;
569                 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
570                         m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
571                         m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
572                 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
573                         m->comm = d->str;
574                 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
575                         m->tid_comm = d->str;
576                 else if (d->type == KDBUS_MSG_SRC_EXE)
577                         m->exe = d->str;
578                 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
579                         m->cmdline = d->str;
580                         m->cmdline_length = l;
581                 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
582                         m->cgroup = d->str;
583                 else if (d->type == KDBUS_MSG_SRC_AUDIT)
584                         m->audit = &d->audit;
585                 else if (d->type == KDBUS_MSG_SRC_CAPS) {
586                         m->capability = d->data;
587                         m->capability_size = l;
588                 } else if (d->type == KDBUS_MSG_DST_NAME)
589                         destination = d->str;
590                 else if (d->type != KDBUS_MSG_FDS &&
591                            d->type != KDBUS_MSG_SRC_SECLABEL)
592                         log_debug("Got unknown field from kernel %llu", d->type);
593         }
594
595         r = bus_message_parse_fields(m);
596         if (r < 0)
597                 goto fail;
598
599         if (k->src_id == KDBUS_SRC_ID_KERNEL)
600                 m->sender = "org.freedesktop.DBus";
601         else {
602                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
603                 m->sender = m->sender_buffer;
604         }
605
606         if (!m->destination) {
607                 if (destination)
608                         m->destination = destination;
609                 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
610                          k->dst_id != KDBUS_DST_ID_BROADCAST) {
611                         snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
612                         m->destination = m->destination_buffer;
613                 }
614         }
615
616         /* We take possession of the kmsg struct now */
617         m->kdbus = k;
618         m->bus = sd_bus_ref(bus);
619         m->release_kdbus = true;
620         m->free_fds = true;
621
622         fds = NULL;
623
624         *ret = m;
625         return 1;
626
627 fail:
628         if (m) {
629                 struct bus_body_part *part;
630                 unsigned i;
631
632                 /* Make sure the memfds are not freed twice */
633                 MESSAGE_FOREACH_PART(part, i, m)
634                         if (part->memfd >= 0)
635                                 part->memfd = -1;
636
637                 sd_bus_message_unref(m);
638         }
639
640         return r;
641 }
642
643 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
644         struct kdbus_msg *k;
645         int r;
646
647         assert(bus);
648         assert(m);
649
650         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k);
651         if (r < 0) {
652                 if (errno == EAGAIN)
653                         return 0;
654
655                 return -errno;
656         }
657
658         r = bus_kernel_make_message(bus, k, m);
659         if (r <= 0)
660                 close_kdbus_msg(bus, k);
661
662         return r < 0 ? r : 1;
663 }
664
665 int bus_kernel_create(const char *name, char **s) {
666         struct kdbus_cmd_bus_make *make;
667         struct kdbus_item *n, *cg;
668         size_t l;
669         int fd;
670         char *p;
671
672         assert(name);
673         assert(s);
674
675         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
676         if (fd < 0)
677                 return -errno;
678
679         l = strlen(name);
680         make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
681                        KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
682                        KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
683
684         cg = make->items;
685         cg->type = KDBUS_MAKE_CGROUP;
686         cg->data64[0] = 1;
687         cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
688
689         n = KDBUS_ITEM_NEXT(cg);
690         n->type = KDBUS_MAKE_NAME;
691         sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
692         n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
693
694         make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
695         make->flags = KDBUS_MAKE_POLICY_OPEN;
696         make->bus_flags = 0;
697         make->bloom_size = BLOOM_SIZE;
698         assert_cc(BLOOM_SIZE % 8 == 0);
699
700         p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
701         if (!p)
702                 return -ENOMEM;
703
704         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
705                 close_nointr_nofail(fd);
706                 free(p);
707                 return -errno;
708         }
709
710         if (s)
711                 *s = p;
712
713         return fd;
714 }
715
716 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
717         struct memfd_cache *c;
718
719         assert(address);
720         assert(size);
721
722         if (!bus || !bus->is_kernel)
723                 return -ENOTSUP;
724
725         if (bus->n_memfd_cache <= 0) {
726                 int fd, r;
727
728                 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
729                 if (r < 0)
730                         return -errno;
731
732                 *address = NULL;
733                 *size = 0;
734                 return fd;
735         }
736
737         c = &bus->memfd_cache[-- bus->n_memfd_cache];
738
739         assert(c->fd >= 0);
740         assert(c->size == 0 || c->address);
741
742         *address = c->address;
743         *size = c->size;
744
745         return c->fd;
746 }
747
748 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
749         struct memfd_cache *c;
750
751         assert(fd >= 0);
752         assert(size == 0 || address);
753
754         if (!bus || !bus->is_kernel ||
755             bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
756
757                 if (size > 0)
758                         assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
759
760                 close_nointr_nofail(fd);
761                 return;
762         }
763
764         c = &bus->memfd_cache[bus->n_memfd_cache++];
765         c->fd = fd;
766         c->address = address;
767
768         /* If overly long, let's return a bit to the OS */
769         if (size > MEMFD_CACHE_ITEM_SIZE_MAX) {
770                 uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX;
771
772                 ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
773
774                 c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
775         } else
776                 c->size = size;
777 }
778
779 void bus_kernel_flush_memfd(sd_bus *b) {
780         unsigned i;
781
782         assert(b);
783
784         for (i = 0; i < b->n_memfd_cache; i++) {
785                 if (b->memfd_cache[i].size > 0)
786                         assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
787
788                 close_nointr_nofail(b->memfd_cache[i].fd);
789         }
790 }