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