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