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