chiark / gitweb /
81469365f0ffdbd3ecae743e80a26feee3425d15
[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 = (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx);
490                                         part->size = d->vec.size - (begin_body - idx);
491                                 }
492
493                                 part->sealed = true;
494                         }
495
496                         idx += d->vec.size;
497
498                 } else if (d->type == KDBUS_MSG_SRC_CREDS) {
499                         m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
500                         m->uid = d->creds.uid;
501                         m->gid = d->creds.gid;
502                         m->pid = d->creds.pid;
503                         m->tid = d->creds.tid;
504                         m->uid_valid = m->gid_valid = true;
505                 } else if (d->type == KDBUS_MSG_TIMESTAMP) {
506                         m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
507                         m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
508                 } else if (d->type == KDBUS_MSG_SRC_PID_COMM)
509                         m->comm = d->str;
510                 else if (d->type == KDBUS_MSG_SRC_TID_COMM)
511                         m->tid_comm = d->str;
512                 else if (d->type == KDBUS_MSG_SRC_EXE)
513                         m->exe = d->str;
514                 else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
515                         m->cmdline = d->str;
516                         m->cmdline_length = l;
517                 } else if (d->type == KDBUS_MSG_SRC_CGROUP)
518                         m->cgroup = d->str;
519                 else if (d->type == KDBUS_MSG_SRC_AUDIT)
520                         m->audit = &d->audit;
521                 else if (d->type == KDBUS_MSG_SRC_CAPS) {
522                         m->capability = d->data;
523                         m->capability_size = l;
524                 } else if (d->type != KDBUS_MSG_FDS &&
525                            d->type != KDBUS_MSG_DST_NAME &&
526                            d->type != KDBUS_MSG_SRC_SECLABEL)
527                         log_debug("Got unknown field from kernel %llu", d->type);
528         }
529
530         r = bus_message_parse_fields(m);
531         if (r < 0) {
532                 sd_bus_message_unref(m);
533                 return r;
534         }
535
536         if (k->src_id == KDBUS_SRC_ID_KERNEL)
537                 m->sender = "org.freedesktop.DBus";
538         else {
539                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
540                 m->sender = m->sender_buffer;
541         }
542
543         if (!m->destination) {
544                 if (destination)
545                         m->destination = destination;
546                 else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME &&
547                          k->dst_id != KDBUS_DST_ID_BROADCAST) {
548                         snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
549                         m->destination = m->destination_buffer;
550                 }
551         }
552
553         /* We take possession of the kmsg struct now */
554         m->kdbus = k;
555         m->bus = sd_bus_ref(bus);
556         m->release_kdbus = true;
557         m->free_fds = true;
558
559         fds = NULL;
560
561         *ret = m;
562         return 1;
563 }
564
565 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
566         struct kdbus_msg *k;
567         int r;
568
569         assert(bus);
570         assert(m);
571
572         r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k);
573         if (r < 0) {
574                 if (errno == EAGAIN)
575                         return 0;
576
577                 return -errno;
578         }
579
580
581 /*                 /\* Let's tell valgrind that there's really no need to */
582 /*                  * initialize this fully. This should be removed again */
583 /*                  * when valgrind learned the kdbus ioctls natively. *\/ */
584 /* #ifdef HAVE_VALGRIND_MEMCHECK_H */
585 /*                 VALGRIND_MAKE_MEM_DEFINED(k, sz); */
586 /* #endif */
587
588
589         r = bus_kernel_make_message(bus, k, m);
590         if (r <= 0)
591                 close_kdbus_msg(bus, k);
592
593         return r < 0 ? r : 1;
594 }
595
596 int bus_kernel_create(const char *name, char **s) {
597         struct kdbus_cmd_bus_make *make;
598         struct kdbus_item *n, *cg;
599         size_t l;
600         int fd;
601         char *p;
602
603         assert(name);
604         assert(s);
605
606         fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
607         if (fd < 0)
608                 return -errno;
609
610         l = strlen(name);
611         make = alloca0(offsetof(struct kdbus_cmd_bus_make, items) +
612                        KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) +
613                        KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1);
614
615         cg = make->items;
616         cg->type = KDBUS_MAKE_CGROUP;
617         cg->data64[0] = 1;
618         cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
619
620         n = KDBUS_ITEM_NEXT(cg);
621         n->type = KDBUS_MAKE_NAME;
622         sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
623         n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1;
624
625         make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size;
626         make->flags = KDBUS_MAKE_POLICY_OPEN;
627         make->bus_flags = 0;
628         make->bloom_size = BLOOM_SIZE;
629         assert_cc(BLOOM_SIZE % 8 == 0);
630
631         p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
632         if (!p)
633                 return -ENOMEM;
634
635         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
636                 close_nointr_nofail(fd);
637                 free(p);
638                 return -errno;
639         }
640
641         if (s)
642                 *s = p;
643
644         return fd;
645 }
646
647 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
648         struct memfd_cache *c;
649
650         assert(address);
651         assert(size);
652
653         if (!bus || !bus->is_kernel)
654                 return -ENOTSUP;
655
656         if (bus->n_memfd_cache <= 0) {
657                 int fd, r;
658
659                 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd);
660                 if (r < 0)
661                         return -errno;
662
663                 *address = NULL;
664                 *size = 0;
665                 return fd;
666         }
667
668         c = &bus->memfd_cache[-- bus->n_memfd_cache];
669
670         assert(c->fd >= 0);
671         assert(c->size == 0 || c->address);
672
673         *address = c->address;
674         *size = c->size;
675
676         return c->fd;
677 }
678
679 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
680         struct memfd_cache *c;
681
682         assert(fd >= 0);
683         assert(size == 0 || address);
684
685         if (!bus || !bus->is_kernel ||
686             bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
687
688                 if (size > 0)
689                         assert_se(munmap(address, PAGE_ALIGN(size)) == 0);
690
691                 close_nointr_nofail(fd);
692                 return;
693         }
694
695         c = &bus->memfd_cache[bus->n_memfd_cache++];
696         c->fd = fd;
697         c->address = address;
698
699         /* If overly long, let's return a bit to the OS */
700         if (size > MEMFD_CACHE_ITEM_SIZE_MAX) {
701                 uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX;
702
703                 ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
704
705                 c->size = MEMFD_CACHE_ITEM_SIZE_MAX;
706         } else
707                 c->size = size;
708 }
709
710 void bus_kernel_flush_memfd(sd_bus *b) {
711         unsigned i;
712
713         assert(b);
714
715         for (i = 0; i < b->n_memfd_cache; i++) {
716                 if (b->memfd_cache[i].size > 0)
717                         assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0);
718
719                 close_nointr_nofail(b->memfd_cache[i].fd);
720         }
721 }