]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-kernel.c
core: by default .busname units should be activating
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-kernel.c
CommitLineData
6629161f
LP
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
7211f918
LP
22#ifdef HAVE_VALGRIND_MEMCHECK_H
23#include <valgrind/memcheck.h>
24#endif
25
6629161f 26#include <fcntl.h>
c556fe79 27#include <malloc.h>
fd8d62d9 28#include <sys/mman.h>
5972fe95 29#include <sys/prctl.h>
6629161f
LP
30
31#include "util.h"
65dae17a 32#include "strv.h"
6629161f
LP
33
34#include "bus-internal.h"
35#include "bus-message.h"
36#include "bus-kernel.h"
a56f19c4 37#include "bus-bloom.h"
777d7a61 38#include "bus-util.h"
a6278b88 39#include "bus-label.h"
751bc6ac 40#include "cgroup-util.h"
777d7a61
LP
41
42#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
6629161f 43
c7819669 44int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
6629161f
LP
45 int r;
46
47 assert(s);
48 assert(id);
49
50 if (!startswith(s, ":1."))
51 return 0;
52
53 r = safe_atou64(s + 3, id);
54 if (r < 0)
55 return r;
56
57 return 1;
58}
59
febfd508 60static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
6629161f 61 assert(d);
6629161f
LP
62 assert(sz > 0);
63
e86b80b8
LP
64 *d = ALIGN8_PTR(*d);
65
66b26c5c
LP
66 /* Note that p can be NULL, which encodes a region full of
67 * zeroes, which is useful to optimize certain padding
68 * conditions */
69
febfd508 70 (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
ea1edece 71 (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
a392d361 72 (*d)->vec.address = PTR_TO_UINT64(p);
6629161f
LP
73 (*d)->vec.size = sz;
74
febfd508 75 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
6629161f
LP
76}
77
a392d361
LP
78static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
79 assert(d);
80 assert(memfd >= 0);
81 assert(sz > 0);
82
83 *d = ALIGN8_PTR(*d);
84 (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
ea1edece 85 (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
a392d361
LP
86 (*d)->memfd.fd = memfd;
87 (*d)->memfd.size = sz;
88
89 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
90}
91
febfd508 92static void append_destination(struct kdbus_item **d, const char *s, size_t length) {
6629161f 93 assert(d);
b5baa8fe 94 assert(s);
6629161f 95
e86b80b8
LP
96 *d = ALIGN8_PTR(*d);
97
febfd508 98 (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
ea1edece 99 (*d)->type = KDBUS_ITEM_DST_NAME;
51038c03 100 memcpy((*d)->str, s, length + 1);
6629161f 101
febfd508 102 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
6629161f
LP
103}
104
18a28147
KS
105static struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
106 struct kdbus_item *i;
a56f19c4 107
b5baa8fe 108 assert(d);
b5baa8fe 109
18a28147 110 i = ALIGN8_PTR(*d);
b5baa8fe 111
18a28147
KS
112 i->size = offsetof(struct kdbus_item, bloom_filter) +
113 offsetof(struct kdbus_bloom_filter, data) +
114 length;
115 i->type = KDBUS_ITEM_BLOOM_FILTER;
b5baa8fe 116
18a28147 117 *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
a56f19c4 118
18a28147 119 return &i->bloom_filter;
a56f19c4
LP
120}
121
febfd508 122static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
9097fe29
LP
123 assert(d);
124 assert(fds);
125 assert(n_fds > 0);
126
127 *d = ALIGN8_PTR(*d);
febfd508 128 (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
ea1edece 129 (*d)->type = KDBUS_ITEM_FDS;
9097fe29
LP
130 memcpy((*d)->fds, fds, sizeof(int) * n_fds);
131
febfd508 132 *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
9097fe29
LP
133}
134
18a28147
KS
135static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
136 void *data;
a56f19c4
LP
137 unsigned i;
138 int r;
139
140 assert(m);
141 assert(bloom);
142
18a28147 143 data = bloom->data;
29804cc1 144 memzero(data, m->bus->bloom_size);
18a28147 145 bloom->generation = 0;
a56f19c4 146
b28ff39f 147 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
a56f19c4
LP
148
149 if (m->interface)
b28ff39f 150 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
a56f19c4 151 if (m->member)
b28ff39f 152 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
a56f19c4 153 if (m->path) {
b28ff39f
LP
154 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
155 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
156 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
a56f19c4
LP
157 }
158
159 r = sd_bus_message_rewind(m, true);
160 if (r < 0)
161 return r;
162
163 for (i = 0; i < 64; i++) {
164 char type;
165 const char *t;
166 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
167 char *e;
168
169 r = sd_bus_message_peek_type(m, &type, NULL);
170 if (r < 0)
171 return r;
172
173 if (type != SD_BUS_TYPE_STRING &&
174 type != SD_BUS_TYPE_OBJECT_PATH &&
175 type != SD_BUS_TYPE_SIGNATURE)
176 break;
177
178 r = sd_bus_message_read_basic(m, type, &t);
179 if (r < 0)
180 return r;
181
182 e = stpcpy(buf, "arg");
183 if (i < 10)
693eb9a2 184 *(e++) = '0' + (char) i;
a56f19c4 185 else {
693eb9a2
LP
186 *(e++) = '0' + (char) (i / 10);
187 *(e++) = '0' + (char) (i % 10);
a56f19c4
LP
188 }
189
190 *e = 0;
b28ff39f 191 bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
a56f19c4
LP
192
193 strcpy(e, "-dot-prefix");
b28ff39f 194 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
a56f19c4 195 strcpy(e, "-slash-prefix");
b28ff39f 196 bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
a56f19c4
LP
197 }
198
199 return 0;
b5baa8fe
LP
200}
201
5b7d4c1c 202static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
9b29bb68 203 struct bus_body_part *part;
febfd508 204 struct kdbus_item *d;
6629161f
LP
205 bool well_known;
206 uint64_t unique;
207 size_t sz, dl;
9b29bb68 208 unsigned i;
6629161f
LP
209 int r;
210
5b7d4c1c 211 assert(b);
6629161f
LP
212 assert(m);
213 assert(m->sealed);
e9a967f9 214
069f5e61
LP
215 /* We put this together only once, if this message is reused
216 * we reuse the earlier-built version */
e9a967f9
LP
217 if (m->kdbus)
218 return 0;
6629161f
LP
219
220 if (m->destination) {
c7819669 221 r = bus_kernel_parse_unique_name(m->destination, &unique);
6629161f
LP
222 if (r < 0)
223 return r;
224
225 well_known = r == 0;
226 } else
227 well_known = false;
228
b1454bf0 229 sz = offsetof(struct kdbus_msg, items);
6629161f 230
a392d361
LP
231 assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
232 ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
233
69aec65c 234 /* Add in fixed header, fields header and payload */
c91cb83c 235 sz += (1 + m->n_body_parts) *
bc7fd8cd 236 ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
6629161f 237
69aec65c 238 /* Add space for bloom filter */
18a28147
KS
239 sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
240 offsetof(struct kdbus_bloom_filter, data) +
b28ff39f 241 m->bus->bloom_size);
b5baa8fe 242
6629161f
LP
243 /* Add in well-known destination header */
244 if (well_known) {
245 dl = strlen(m->destination);
febfd508 246 sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
6629161f
LP
247 }
248
9097fe29
LP
249 /* Add space for unix fds */
250 if (m->n_fds > 0)
febfd508 251 sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
9097fe29 252
c556fe79 253 m->kdbus = memalign(8, sz);
66b26c5c
LP
254 if (!m->kdbus) {
255 r = -ENOMEM;
256 goto fail;
257 }
6629161f 258
66b26c5c 259 m->free_kdbus = true;
29804cc1 260 memzero(m->kdbus, sz);
d9115e18 261
6629161f 262 m->kdbus->flags =
0461f8cd 263 ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
97f82db3 264 ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
6629161f
LP
265 m->kdbus->dst_id =
266 well_known ? 0 :
b5baa8fe 267 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
6647dc66 268 m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
42c4ebcb 269 m->kdbus->cookie = (uint64_t) m->header->serial;
ca7b42c8 270 m->kdbus->priority = m->priority;
80a33f11
KS
271
272 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
693eb9a2 273 m->kdbus->cookie_reply = m->reply_cookie;
80a33f11
KS
274 else
275 m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
6629161f 276
b1454bf0 277 d = m->kdbus->items;
6629161f
LP
278
279 if (well_known)
280 append_destination(&d, m->destination, dl);
281
c91cb83c 282 append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
a392d361
LP
283
284 MESSAGE_FOREACH_PART(part, i, m) {
285 if (part->is_zero) {
66b26c5c
LP
286 /* If this is padding then simply send a
287 * vector with a NULL data pointer which the
288 * kernel will just pass through. This is the
289 * most efficient way to encode zeroes */
290
a392d361
LP
291 append_payload_vec(&d, NULL, part->size);
292 continue;
293 }
294
66b26c5c
LP
295 if (part->memfd >= 0 && part->sealed && m->destination) {
296 /* Try to send a memfd, if the part is
297 * sealed and this is not a broadcast. Since we can only */
a392d361 298
66b26c5c
LP
299 append_payload_memfd(&d, part->memfd, part->size);
300 continue;
a392d361
LP
301 }
302
73e231ab
JE
303 /* Otherwise, let's send a vector to the actual data.
304 * For that, we need to map it first. */
66b26c5c
LP
305 r = bus_body_part_map(part);
306 if (r < 0)
307 goto fail;
a392d361 308
bc7fd8cd 309 append_payload_vec(&d, part->data, part->size);
a392d361 310 }
6629161f 311
5b7d4c1c 312 if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
18a28147 313 struct kdbus_bloom_filter *bloom;
5b7d4c1c 314
b28ff39f 315 bloom = append_bloom(&d, m->bus->bloom_size);
18a28147 316 r = bus_message_setup_bloom(m, bloom);
a392d361
LP
317 if (r < 0)
318 goto fail;
5b7d4c1c 319 }
b5baa8fe 320
9097fe29
LP
321 if (m->n_fds > 0)
322 append_fds(&d, m->fds, m->n_fds);
323
e9a967f9 324 m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
6629161f
LP
325 assert(m->kdbus->size <= sz);
326
327 return 0;
a392d361
LP
328
329fail:
66b26c5c 330 m->poisoned = true;
a392d361 331 return r;
6629161f
LP
332}
333
cb67f718
DM
334static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
335 sd_bus_message *m = NULL;
336 struct kdbus_item *d;
337 unsigned n_fds = 0;
338 _cleanup_free_ int *fds = NULL;
339 struct bus_header *h = NULL;
340 size_t total, n_bytes = 0, idx = 0;
341 const char *destination = NULL, *seclabel = NULL;
6629161f
LP
342 int r;
343
cb67f718
DM
344 assert(bus);
345 assert(k);
346 assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
35460afc 347
cb67f718
DM
348 KDBUS_ITEM_FOREACH(d, k, items) {
349 size_t l;
f08838da 350
cb67f718 351 l = d->size - offsetof(struct kdbus_item, data);
8f155917 352
cb67f718 353 switch (d->type) {
62b3e928 354
cb67f718
DM
355 case KDBUS_ITEM_PAYLOAD_OFF:
356 if (!h) {
357 h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
8a0e0ed9 358
cb67f718
DM
359 if (!bus_header_is_complete(h, d->vec.size))
360 return -EBADMSG;
361 }
8a0e0ed9 362
cb67f718
DM
363 n_bytes += d->vec.size;
364 break;
8a0e0ed9 365
cb67f718
DM
366 case KDBUS_ITEM_PAYLOAD_MEMFD:
367 if (!h)
368 return -EBADMSG;
8a0e0ed9 369
cb67f718
DM
370 n_bytes += d->memfd.size;
371 break;
8a0e0ed9 372
cb67f718
DM
373 case KDBUS_ITEM_FDS: {
374 int *f;
375 unsigned j;
8a0e0ed9 376
cb67f718
DM
377 j = l / sizeof(int);
378 f = realloc(fds, sizeof(int) * (n_fds + j));
379 if (!f)
380 return -ENOMEM;
8a0e0ed9 381
cb67f718
DM
382 fds = f;
383 memcpy(fds + n_fds, d->fds, sizeof(int) * j);
384 n_fds += j;
385 break;
386 }
62b3e928 387
cb67f718
DM
388 case KDBUS_ITEM_SECLABEL:
389 seclabel = d->str;
390 break;
fd8d62d9
LP
391 }
392 }
393
cb67f718
DM
394 if (!h)
395 return -EBADMSG;
de297575 396
cb67f718
DM
397 r = bus_header_message_size(h, &total);
398 if (r < 0)
399 return r;
219728b3 400
cb67f718
DM
401 if (n_bytes != total)
402 return -EBADMSG;
6629161f 403
cb67f718
DM
404 /* on kdbus we only speak native endian gvariant, never dbus1
405 * marshalling or reverse endian */
406 if (h->version != 2 ||
407 h->endian != BUS_NATIVE_ENDIAN)
408 return -EPROTOTYPE;
c58dea19 409
cb67f718
DM
410 r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
411 if (r < 0)
412 return r;
6629161f 413
cb67f718
DM
414 /* The well-known names list is different from the other
415 credentials. If we asked for it, but nothing is there, this
416 means that the list of well-known names is simply empty, not
417 that we lack any data */
35460afc 418
cb67f718 419 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
f08838da 420
cb67f718
DM
421 KDBUS_ITEM_FOREACH(d, k, items) {
422 size_t l;
6629161f 423
cb67f718 424 l = d->size - offsetof(struct kdbus_item, data);
6629161f 425
cb67f718 426 switch (d->type) {
6629161f 427
cb67f718
DM
428 case KDBUS_ITEM_PAYLOAD_OFF: {
429 size_t begin_body;
6629161f 430
cb67f718 431 begin_body = BUS_MESSAGE_BODY_BEGIN(m);
6629161f 432
cb67f718
DM
433 if (idx + d->vec.size > begin_body) {
434 struct bus_body_part *part;
a43b9ca3 435
cb67f718 436 /* Contains body material */
6629161f 437
cb67f718
DM
438 part = message_append_part(m);
439 if (!part) {
440 r = -ENOMEM;
441 goto fail;
442 }
a43b9ca3 443
cb67f718
DM
444 /* A -1 offset is NUL padding. */
445 part->is_zero = d->vec.offset == ~0ULL;
a43b9ca3 446
cb67f718
DM
447 if (idx >= begin_body) {
448 if (!part->is_zero)
449 part->data = (uint8_t *)k + d->vec.offset;
450 part->size = d->vec.size;
451 } else {
452 if (!part->is_zero)
453 part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
454 part->size = d->vec.size - (begin_body - idx);
455 }
a43b9ca3 456
cb67f718 457 part->sealed = true;
ff4994c5 458 }
a43b9ca3 459
cb67f718
DM
460 idx += d->vec.size;
461 break;
462 }
a43b9ca3 463
cb67f718
DM
464 case KDBUS_ITEM_PAYLOAD_MEMFD: {
465 struct bus_body_part *part;
a43b9ca3 466
cb67f718
DM
467 if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
468 r = -EBADMSG;
469 goto fail;
ff4994c5 470 }
a43b9ca3 471
cb67f718
DM
472 part = message_append_part(m);
473 if (!part) {
474 r = -ENOMEM;
475 goto fail;
476 }
a43b9ca3 477
cb67f718
DM
478 part->memfd = d->memfd.fd;
479 part->size = d->memfd.size;
480 part->sealed = true;
a43b9ca3 481
cb67f718
DM
482 idx += d->memfd.size;
483 break;
484 }
a43b9ca3 485
cb67f718
DM
486 case KDBUS_ITEM_CREDS:
487 /* UID/GID/PID are always valid */
488 m->creds.uid = (uid_t) d->creds.uid;
489 m->creds.gid = (gid_t) d->creds.gid;
490 m->creds.pid = (pid_t) d->creds.pid;
491 m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
a43b9ca3 492
cb67f718
DM
493 /* The PID starttime/TID might be missing
494 * however, when the data is faked by some
495 * data bus proxy and it lacks that
496 * information about the real client since
497 * SO_PEERCRED is used for that */
6629161f 498
cb67f718
DM
499 if (d->creds.starttime > 0) {
500 m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
501 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
502 }
6629161f 503
cb67f718
DM
504 if (d->creds.tid > 0) {
505 m->creds.tid = (pid_t) d->creds.tid;
506 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
507 }
508 break;
6629161f 509
cb67f718 510 case KDBUS_ITEM_TIMESTAMP:
41add995
LP
511
512 if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
513 m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
514 m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
515 m->seqnum = d->timestamp.seqnum;
516 }
517
cb67f718 518 break;
fd8d62d9 519
cb67f718
DM
520 case KDBUS_ITEM_PID_COMM:
521 m->creds.comm = d->str;
522 m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
523 break;
fd8d62d9 524
cb67f718
DM
525 case KDBUS_ITEM_TID_COMM:
526 m->creds.tid_comm = d->str;
527 m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
528 break;
6629161f 529
cb67f718
DM
530 case KDBUS_ITEM_EXE:
531 m->creds.exe = d->str;
532 m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
533 break;
6629161f 534
cb67f718
DM
535 case KDBUS_ITEM_CMDLINE:
536 m->creds.cmdline = d->str;
537 m->creds.cmdline_size = l;
538 m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
539 break;
777d7a61 540
cb67f718
DM
541 case KDBUS_ITEM_CGROUP:
542 m->creds.cgroup = d->str;
543 m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask;
777d7a61 544
cb67f718
DM
545 if (!bus->cgroup_root) {
546 r = cg_get_root_path(&bus->cgroup_root);
547 if (r < 0)
548 goto fail;
549 }
777d7a61 550
cb67f718 551 m->creds.cgroup_root = bus->cgroup_root;
777d7a61 552
cb67f718 553 break;
777d7a61 554
cb67f718
DM
555 case KDBUS_ITEM_AUDIT:
556 m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
557 m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
558 m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
559 break;
777d7a61 560
cb67f718
DM
561 case KDBUS_ITEM_CAPS:
562 m->creds.capability = d->data;
563 m->creds.capability_size = l;
564 m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask;
565 break;
219728b3 566
cb67f718
DM
567 case KDBUS_ITEM_DST_NAME:
568 if (!service_name_is_valid(d->str))
569 return -EBADMSG;
219728b3 570
cb67f718
DM
571 destination = d->str;
572 break;
777d7a61 573
cb67f718
DM
574 case KDBUS_ITEM_NAME:
575 if (!service_name_is_valid(d->name.name))
576 return -EBADMSG;
777d7a61 577
cb67f718
DM
578 r = strv_extend(&m->creds.well_known_names, d->name.name);
579 if (r < 0)
580 goto fail;
581 break;
777d7a61 582
cccb0b2c
LP
583 case KDBUS_ITEM_CONN_NAME:
584 m->creds.conn_name = d->str;
585 m->creds.mask |= SD_BUS_CREDS_CONNECTION_NAME & bus->creds_mask;
586 break;
587
cb67f718
DM
588 case KDBUS_ITEM_FDS:
589 case KDBUS_ITEM_SECLABEL:
590 break;
d78bf250 591
cb67f718
DM
592 default:
593 log_debug("Got unknown field from kernel %llu", d->type);
594 }
595 }
d78bf250 596
cb67f718
DM
597 r = bus_message_parse_fields(m);
598 if (r < 0)
599 goto fail;
777d7a61 600
cb67f718
DM
601 /* Override information from the user header with data from the kernel */
602 if (k->src_id == KDBUS_SRC_ID_KERNEL)
603 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
604 else {
605 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
606 m->sender = m->creds.unique_name = m->sender_buffer;
607 }
777d7a61 608
cb67f718
DM
609 if (destination)
610 m->destination = destination;
611 else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
612 m->destination = NULL;
613 else if (k->dst_id == KDBUS_DST_ID_NAME)
614 m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
615 else {
616 snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
617 m->destination = m->destination_buffer;
618 }
777d7a61 619
cb67f718
DM
620 /* We take possession of the kmsg struct now */
621 m->kdbus = k;
622 m->release_kdbus = true;
623 m->free_fds = true;
624 fds = NULL;
777d7a61 625
cb67f718 626 bus->rqueue[bus->rqueue_size++] = m;
777d7a61 627
cb67f718 628 return 1;
777d7a61 629
cb67f718
DM
630fail:
631 if (m) {
632 struct bus_body_part *part;
633 unsigned i;
777d7a61 634
cb67f718
DM
635 /* Make sure the memfds are not freed twice */
636 MESSAGE_FOREACH_PART(part, i, m)
637 if (part->memfd >= 0)
638 part->memfd = -1;
777d7a61 639
cb67f718
DM
640 sd_bus_message_unref(m);
641 }
777d7a61 642
cb67f718
DM
643 return r;
644}
777d7a61 645
cb67f718
DM
646int bus_kernel_take_fd(sd_bus *b) {
647 struct kdbus_cmd_hello *hello;
648 struct kdbus_item *item;
5972fe95
LP
649 _cleanup_free_ char *g = NULL;
650 const char *name;
651 size_t l = 0, m = 0, sz;
cb67f718 652 int r;
777d7a61 653
cb67f718 654 assert(b);
7adc46fc 655
cb67f718
DM
656 if (b->is_server)
657 return -EINVAL;
777d7a61 658
cb67f718 659 b->use_memfd = 1;
777d7a61 660
5972fe95 661 if (b->connection_name) {
a6278b88 662 g = bus_label_escape(b->connection_name);
5972fe95
LP
663 if (!g)
664 return -ENOMEM;
665
666 name = g;
667 } else {
668 char pr[17] = {};
669
670 /* If no name is explicitly set, we'll include a hint
671 * indicating the library implementation, a hint which
672 * kind of bus this is and the thread name */
673
674 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
675
676 if (isempty(pr)) {
677 name = b->is_system ? "sd-system" :
678 b->is_user ? "sd-user" : "sd";
679 } else {
680 _cleanup_free_ char *e = NULL;
681
a6278b88 682 e = bus_label_escape(pr);
5972fe95
LP
683 if (!e)
684 return -ENOMEM;
685
686 g = strappend(b->is_system ? "sd-system-" :
687 b->is_user ? "sd-user-" : "sd-",
688 e);
689 if (!g)
690 return -ENOMEM;
691
692 name = g;
693 }
694
a6278b88 695 b->connection_name = bus_label_unescape(name);
5972fe95
LP
696 if (!b->connection_name)
697 return -ENOMEM;
698 }
699
700 m = strlen(name);
701
702 sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
703 ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
777d7a61 704
cb67f718 705 if (b->fake_creds_valid)
5972fe95 706 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
777d7a61 707
cb67f718
DM
708 if (b->fake_label) {
709 l = strlen(b->fake_label);
710 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
711 }
777d7a61 712
cb67f718
DM
713 hello = alloca0(sz);
714 hello->size = sz;
715 hello->conn_flags = b->hello_flags;
716 hello->attach_flags = b->attach_flags;
717 hello->pool_size = KDBUS_POOL_SIZE;
777d7a61 718
cb67f718
DM
719 item = hello->items;
720
5972fe95
LP
721 item->size = offsetof(struct kdbus_item, str) + m + 1;
722 item->type = KDBUS_ITEM_CONN_NAME;
723 memcpy(item->str, name, m + 1);
724 item = KDBUS_ITEM_NEXT(item);
725
cb67f718
DM
726 if (b->fake_creds_valid) {
727 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
728 item->type = KDBUS_ITEM_CREDS;
729 item->creds = b->fake_creds;
730
731 item = KDBUS_ITEM_NEXT(item);
777d7a61
LP
732 }
733
cb67f718
DM
734 if (b->fake_label) {
735 item->size = offsetof(struct kdbus_item, str) + l + 1;
5972fe95 736 item->type = KDBUS_ITEM_SECLABEL;
cb67f718 737 memcpy(item->str, b->fake_label, l+1);
777d7a61
LP
738 }
739
cb67f718
DM
740 r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
741 if (r < 0)
742 return -errno;
777d7a61 743
cb67f718
DM
744 if (!b->kdbus_buffer) {
745 b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
746 if (b->kdbus_buffer == MAP_FAILED) {
747 b->kdbus_buffer = NULL;
748 return -errno;
749 }
750 }
6629161f 751
cb67f718
DM
752 /* The higher 32bit of both flags fields are considered
753 * 'incompatible flags'. Refuse them all for now. */
754 if (hello->bus_flags > 0xFFFFFFFFULL ||
755 hello->conn_flags > 0xFFFFFFFFULL)
756 return -ENOTSUP;
6629161f 757
b28ff39f 758 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
cb67f718 759 return -ENOTSUP;
6629161f 760
b28ff39f
LP
761 b->bloom_size = (size_t) hello->bloom.size;
762 b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
763
cb67f718
DM
764 if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
765 return -ENOMEM;
6629161f 766
cb67f718 767 b->unique_id = hello->id;
6629161f 768
cb67f718
DM
769 b->is_kernel = true;
770 b->bus_client = true;
771 b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
772 b->message_version = 2;
773 b->message_endian = BUS_NATIVE_ENDIAN;
c91cb83c 774
cb67f718
DM
775 /* the kernel told us the UUID of the underlying bus */
776 memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
6629161f 777
cb67f718
DM
778 return bus_start_running(b);
779}
6629161f 780
cb67f718
DM
781int bus_kernel_connect(sd_bus *b) {
782 assert(b);
783 assert(b->input_fd < 0);
784 assert(b->output_fd < 0);
785 assert(b->kernel);
1307c3ff 786
cb67f718
DM
787 if (b->is_server)
788 return -EINVAL;
1307c3ff 789
cb67f718
DM
790 b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
791 if (b->input_fd < 0)
792 return -errno;
6629161f 793
cb67f718 794 b->output_fd = b->input_fd;
6629161f 795
cb67f718
DM
796 return bus_kernel_take_fd(b);
797}
f9be01f3 798
069f5e61
LP
799static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
800 uint64_t off;
801 struct kdbus_item *d;
802
803 assert(bus);
804 assert(k);
805
806 off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
807 ioctl(bus->input_fd, KDBUS_CMD_FREE, &off);
808
809 KDBUS_ITEM_FOREACH(d, k, items) {
810
811 if (d->type == KDBUS_ITEM_FDS)
812 close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
813 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
03e334a1 814 safe_close(d->memfd.fd);
069f5e61
LP
815 }
816}
817
818int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
cb67f718 819 int r;
6629161f 820
cb67f718
DM
821 assert(bus);
822 assert(m);
823 assert(bus->state == BUS_RUNNING);
6629161f 824
cb67f718
DM
825 /* If we can't deliver, we want room for the error message */
826 r = bus_rqueue_make_room(bus);
6629161f
LP
827 if (r < 0)
828 return r;
829
cb67f718 830 r = bus_message_setup_kmsg(bus, m);
6629161f
LP
831 if (r < 0)
832 return r;
833
069f5e61
LP
834 /* If this is a synchronous method call, then let's tell the
835 * kernel, so that it can pass CPU time/scheduling to the
836 * destination for the time, if it wants to. If we
837 * synchronously wait for the result anyway, we won't need CPU
838 * anyway. */
839 if (hint_sync_call)
840 m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
841
cb67f718
DM
842 r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
843 if (r < 0) {
844 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
845 sd_bus_message *reply;
253ce82b 846
cb67f718
DM
847 if (errno == EAGAIN || errno == EINTR)
848 return 0;
849 else if (errno == ENXIO || errno == ESRCH) {
6629161f 850
cb67f718
DM
851 /* ENXIO: unique name not known
852 * ESRCH: well-known name not known */
6629161f 853
cb67f718
DM
854 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
855 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
856 else {
857 log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
858 return 0;
859 }
777d7a61 860
cb67f718 861 } else if (errno == EADDRNOTAVAIL) {
fd8d62d9 862
cb67f718 863 /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
bc7fd8cd 864
cb67f718
DM
865 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
866 sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
867 else {
868 log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
869 return 0;
870 }
871 } else
872 return -errno;
bc7fd8cd 873
cb67f718
DM
874 r = bus_message_new_synthetic_error(
875 bus,
876 BUS_MESSAGE_COOKIE(m),
877 &error,
878 &reply);
bc7fd8cd 879
cb67f718
DM
880 if (r < 0)
881 return r;
bc7fd8cd 882
cb67f718
DM
883 r = bus_seal_synthetic_message(bus, reply);
884 if (r < 0)
885 return r;
62b3e928 886
cb67f718 887 bus->rqueue[bus->rqueue_size++] = reply;
bc7fd8cd 888
069f5e61
LP
889 } else if (hint_sync_call) {
890 struct kdbus_msg *k;
fd8d62d9 891
069f5e61
LP
892 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
893 assert(k);
777d7a61 894
069f5e61 895 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
1307c3ff 896
069f5e61
LP
897 r = bus_kernel_make_message(bus, k);
898 if (r < 0) {
899 close_kdbus_msg(bus, k);
1307c3ff 900
069f5e61
LP
901 /* Anybody can send us invalid messages, let's just drop them. */
902 if (r == -EBADMSG || r == -EPROTOTYPE)
903 log_debug("Ignoring invalid message: %s", strerror(-r));
904 else
905 return r;
906 }
907 } else {
908 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
909 close_kdbus_msg(bus, k);
910 }
cb67f718 911 }
069f5e61
LP
912
913 return 1;
cb67f718 914}
69aec65c 915
cb67f718
DM
916static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
917 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
918 int r;
2dc9970b 919
cb67f718 920 assert(bus);
2dc9970b 921
cb67f718
DM
922 r = sd_bus_message_new_signal(
923 bus,
151b9b96 924 &m,
cb67f718
DM
925 "/org/freedesktop/DBus",
926 "org.freedesktop.DBus",
151b9b96 927 "NameOwnerChanged");
cb67f718
DM
928 if (r < 0)
929 return r;
2dc9970b 930
cb67f718
DM
931 r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
932 if (r < 0)
933 return r;
5b12334d 934
cb67f718 935 m->sender = "org.freedesktop.DBus";
5b12334d 936
cb67f718
DM
937 r = bus_seal_synthetic_message(bus, m);
938 if (r < 0)
939 return r;
5b12334d 940
cb67f718
DM
941 bus->rqueue[bus->rqueue_size++] = m;
942 m = NULL;
5b12334d 943
cb67f718
DM
944 return 1;
945}
5b12334d 946
cb67f718
DM
947static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
948 char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
5b12334d 949
cb67f718
DM
950 assert(bus);
951 assert(k);
952 assert(d);
751bc6ac 953
cb67f718
DM
954 if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
955 old_owner[0] = 0;
956 else
957 sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old.id);
751bc6ac 958
cb67f718 959 if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
751bc6ac 960
cb67f718
DM
961 if (isempty(old_owner))
962 return 0;
5b12334d 963
cb67f718
DM
964 new_owner[0] = 0;
965 } else
966 sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new.id);
5b12334d 967
cb67f718
DM
968 return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner);
969}
5b12334d 970
cb67f718
DM
971static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
972 char owner[UNIQUE_NAME_MAX];
2e2ec0ea 973
cb67f718
DM
974 assert(bus);
975 assert(k);
976 assert(d);
777d7a61 977
cb67f718 978 sprintf(owner, ":1.%llu", d->id_change.id);
2e2ec0ea 979
cb67f718
DM
980 return push_name_owner_changed(
981 bus, owner,
982 d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
983 d->type == KDBUS_ITEM_ID_ADD ? owner : NULL);
984}
49b832c5 985
cb67f718
DM
986static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
987 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
988 int r;
777d7a61 989
cb67f718
DM
990 assert(bus);
991 assert(k);
992 assert(d);
acb5a3cb 993
cb67f718
DM
994 r = bus_message_new_synthetic_error(
995 bus,
996 k->cookie_reply,
997 d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
998 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
999 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
1000 &m);
1307c3ff 1001 if (r < 0)
cb67f718 1002 return r;
51038c03 1003
cb67f718 1004 m->sender = "org.freedesktop.DBus";
51038c03 1005
cb67f718
DM
1006 r = bus_seal_synthetic_message(bus, m);
1007 if (r < 0)
1008 return r;
6629161f 1009
7adc46fc 1010 bus->rqueue[bus->rqueue_size++] = m;
cb67f718 1011 m = NULL;
7d22c717 1012
6629161f 1013 return 1;
cb67f718 1014}
1307c3ff 1015
cb67f718
DM
1016static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
1017 struct kdbus_item *d, *found = NULL;
1307c3ff 1018
cb67f718
DM
1019 static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
1020 [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1021 [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1022 [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
1307c3ff 1023
cb67f718
DM
1024 [KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1025 [KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
1026
1027 [KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1028 [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
1029 };
1030
1031 assert(bus);
1032 assert(k);
1033 assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
1034
1035 KDBUS_ITEM_FOREACH(d, k, items) {
1036 if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
1037 if (found)
1038 return -EBADMSG;
1039 found = d;
1040 } else
1041 log_debug("Got unknown field from kernel %llu", d->type);
1307c3ff
LP
1042 }
1043
cb67f718
DM
1044 if (!found) {
1045 log_debug("Didn't find a kernel message to translate.");
1046 return 0;
1047 }
1048
1049 return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found);
6629161f
LP
1050}
1051
766c5809 1052int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
9ff1897b 1053 struct kdbus_cmd_recv recv = {};
6629161f 1054 struct kdbus_msg *k;
6629161f
LP
1055 int r;
1056
1057 assert(bus);
7d22c717 1058
7adc46fc 1059 r = bus_rqueue_make_room(bus);
7d22c717
LP
1060 if (r < 0)
1061 return r;
6629161f 1062
766c5809
LP
1063 if (hint_priority) {
1064 recv.flags |= KDBUS_RECV_USE_PRIORITY;
1065 recv.priority = priority;
1066 }
1067
9ff1897b 1068 r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &recv);
fd8d62d9 1069 if (r < 0) {
6629161f
LP
1070 if (errno == EAGAIN)
1071 return 0;
1072
fd8d62d9 1073 return -errno;
6629161f
LP
1074 }
1075
069f5e61 1076 k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.offset);
e1d337d4 1077 if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
7d22c717 1078 r = bus_kernel_make_message(bus, k);
e1d337d4
LP
1079
1080 /* Anybody can send us invalid messages, let's just drop them. */
1081 if (r == -EBADMSG || r == -EPROTOTYPE) {
ff4994c5 1082 log_debug("Ignoring invalid message: %s", strerror(-r));
e1d337d4
LP
1083 r = 0;
1084 }
1085
1086 } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
7d22c717 1087 r = bus_kernel_translate_message(bus, k);
069f5e61
LP
1088 else {
1089 log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
777d7a61 1090 r = 0;
069f5e61 1091 }
777d7a61 1092
fd8d62d9
LP
1093 if (r <= 0)
1094 close_kdbus_msg(bus, k);
6629161f 1095
51038c03 1096 return r < 0 ? r : 1;
6629161f
LP
1097}
1098
8e959fbf 1099int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
bc7fd8cd 1100 struct memfd_cache *c;
45fbe937 1101 int fd;
bc7fd8cd
LP
1102
1103 assert(address);
8e959fbf
LP
1104 assert(mapped);
1105 assert(allocated);
35460afc
LP
1106
1107 if (!bus || !bus->is_kernel)
1108 return -ENOTSUP;
bc7fd8cd 1109
76b7742c 1110 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
45fbe937 1111
bc7fd8cd 1112 if (bus->n_memfd_cache <= 0) {
8d1db1d1
LP
1113 _cleanup_free_ char *g = NULL;
1114 struct kdbus_cmd_memfd_make *cmd;
1115 struct kdbus_item *item;
1116 size_t l, sz;
45fbe937
LP
1117 int r;
1118
76b7742c 1119 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
bc7fd8cd 1120
8d1db1d1
LP
1121 assert(bus->connection_name);
1122
a6278b88 1123 g = bus_label_escape(bus->connection_name);
8d1db1d1
LP
1124 if (!g)
1125 return -ENOMEM;
1126
1127 l = strlen(g);
1128 sz = ALIGN8(offsetof(struct kdbus_cmd_memfd_make, items)) +
1129 ALIGN8(offsetof(struct kdbus_item, str)) +
1130 l + 1;
1131 cmd = alloca0(sz);
1132 cmd->size = sz;
1133
1134 item = cmd->items;
1135 item->size = ALIGN8(offsetof(struct kdbus_item, str)) + l + 1;
1136 item->type = KDBUS_ITEM_MEMFD_NAME;
1137 memcpy(item->str, g, l + 1);
1138
1139 r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, cmd);
9b05bc48 1140 if (r < 0)
bc7fd8cd
LP
1141 return -errno;
1142
1143 *address = NULL;
8e959fbf
LP
1144 *mapped = 0;
1145 *allocated = 0;
8d1db1d1 1146 return cmd->fd;
bc7fd8cd
LP
1147 }
1148
bf30e48f 1149 c = &bus->memfd_cache[--bus->n_memfd_cache];
bc7fd8cd
LP
1150
1151 assert(c->fd >= 0);
8e959fbf 1152 assert(c->mapped == 0 || c->address);
bc7fd8cd
LP
1153
1154 *address = c->address;
8e959fbf
LP
1155 *mapped = c->mapped;
1156 *allocated = c->allocated;
45fbe937
LP
1157 fd = c->fd;
1158
76b7742c 1159 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
bc7fd8cd 1160
45fbe937
LP
1161 return fd;
1162}
1163
1164static void close_and_munmap(int fd, void *address, size_t size) {
1165 if (size > 0)
76b7742c 1166 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
45fbe937 1167
03e334a1 1168 safe_close(fd);
bc7fd8cd
LP
1169}
1170
8e959fbf 1171void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
bc7fd8cd 1172 struct memfd_cache *c;
8e959fbf 1173 uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
bc7fd8cd
LP
1174
1175 assert(fd >= 0);
8e959fbf 1176 assert(mapped == 0 || address);
bc7fd8cd 1177
45fbe937 1178 if (!bus || !bus->is_kernel) {
8e959fbf 1179 close_and_munmap(fd, address, mapped);
45fbe937
LP
1180 return;
1181 }
1182
76b7742c 1183 assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
bc7fd8cd 1184
45fbe937 1185 if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
76b7742c 1186 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
bc7fd8cd 1187
8e959fbf 1188 close_and_munmap(fd, address, mapped);
bc7fd8cd
LP
1189 return;
1190 }
1191
1192 c = &bus->memfd_cache[bus->n_memfd_cache++];
1193 c->fd = fd;
1194 c->address = address;
1195
1196 /* If overly long, let's return a bit to the OS */
8e959fbf
LP
1197 if (mapped > max_mapped) {
1198 assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_mapped) >= 0);
1199 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
1200 c->mapped = c->allocated = max_mapped;
1201 } else {
1202 c->mapped = mapped;
1203 c->allocated = allocated;
1204 }
45fbe937 1205
76b7742c 1206 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
bc7fd8cd
LP
1207}
1208
1209void bus_kernel_flush_memfd(sd_bus *b) {
1210 unsigned i;
1211
1212 assert(b);
1213
76b7742c 1214 for (i = 0; i < b->n_memfd_cache; i++)
8e959fbf 1215 close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
bc7fd8cd 1216}
0253ddcc 1217
e3dd987c
LP
1218int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
1219 uint64_t f = 0;
0253ddcc 1220
e3dd987c 1221 assert(kdbus_flags);
0253ddcc 1222
e3dd987c
LP
1223 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
1224 f |= KDBUS_NAME_ALLOW_REPLACEMENT;
0253ddcc 1225
e3dd987c
LP
1226 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
1227 f |= KDBUS_NAME_REPLACE_EXISTING;
0253ddcc 1228
d90bb669 1229 if (flags & SD_BUS_NAME_QUEUE)
e3dd987c 1230 f |= KDBUS_NAME_QUEUE;
0253ddcc 1231
e3dd987c
LP
1232 *kdbus_flags = f;
1233 return 0;
1234}
1235
1236int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
1237 uint64_t m = 0;
1238
1239 assert(kdbus_mask);
1240
1241 if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
1242 m |= KDBUS_ATTACH_CREDS;
1243
1244 if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
1245 m |= KDBUS_ATTACH_COMM;
1246
1247 if (mask & SD_BUS_CREDS_EXE)
1248 m |= KDBUS_ATTACH_EXE;
1249
1250 if (mask & SD_BUS_CREDS_CMDLINE)
1251 m |= KDBUS_ATTACH_CMDLINE;
1252
1253 if (mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID))
1254 m |= KDBUS_ATTACH_CGROUP;
1255
1256 if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
1257 m |= KDBUS_ATTACH_CAPS;
1258
1259 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
1260 m |= KDBUS_ATTACH_SECLABEL;
0253ddcc 1261
e3dd987c
LP
1262 if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
1263 m |= KDBUS_ATTACH_AUDIT;
1264
49b832c5
LP
1265 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
1266 m |= KDBUS_ATTACH_NAMES;
1267
cccb0b2c
LP
1268 if (mask & SD_BUS_CREDS_CONNECTION_NAME)
1269 m |= KDBUS_ATTACH_CONN_NAME;
1270
e3dd987c 1271 *kdbus_mask = m;
0253ddcc
DM
1272 return 0;
1273}
e3dd987c 1274
f2769777 1275int bus_kernel_create_bus(const char *name, bool world, char **s) {
816a3f9e 1276 struct kdbus_cmd_make *make;
e3dd987c
LP
1277 struct kdbus_item *n;
1278 int fd;
1279
1280 assert(name);
1281 assert(s);
1282
1283 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1284 if (fd < 0)
1285 return -errno;
1286
816a3f9e
DM
1287 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
1288 offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
e3dd987c
LP
1289 offsetof(struct kdbus_item, str) +
1290 DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
1291
816a3f9e
DM
1292 make->size = offsetof(struct kdbus_cmd_make, items);
1293
e3dd987c 1294 n = make->items;
18a28147
KS
1295 n->size = offsetof(struct kdbus_item, bloom_parameter) +
1296 sizeof(struct kdbus_bloom_parameter);
1297 n->type = KDBUS_ITEM_BLOOM_PARAMETER;
b28ff39f
LP
1298
1299 n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
1300 n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
1301
1302 assert_cc(DEFAULT_BLOOM_SIZE > 0);
1303 assert_cc(DEFAULT_BLOOM_N_HASH > 0);
1304
816a3f9e
DM
1305 make->size += ALIGN8(n->size);
1306
1307 n = KDBUS_ITEM_NEXT(n);
e3dd987c
LP
1308 sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
1309 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
5e16c257 1310 n->type = KDBUS_ITEM_MAKE_NAME;
816a3f9e 1311 make->size += ALIGN8(n->size);
e3dd987c 1312
f7c7cd03 1313 make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
e3dd987c
LP
1314
1315 if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
03e334a1 1316 safe_close(fd);
e3dd987c
LP
1317 return -errno;
1318 }
1319
f9638db8
LP
1320 /* The higher 32bit of the flags field are considered
1321 * 'incompatible flags'. Refuse them all for now. */
1322 if (make->flags > 0xFFFFFFFFULL) {
03e334a1 1323 safe_close(fd);
f9638db8
LP
1324 return -ENOTSUP;
1325 }
1326
e3dd987c
LP
1327 if (s) {
1328 char *p;
1329
1330 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
1331 if (!p) {
03e334a1 1332 safe_close(fd);
e3dd987c
LP
1333 return -ENOMEM;
1334 }
1335
1336 *s = p;
1337 }
1338
1339 return fd;
1340}
9bd37b40 1341
1683342a
DM
1342static void bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item)
1343{
1344 switch (policy->type) {
1345 case BUSNAME_POLICY_TYPE_USER:
1346 item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
1347 item->policy_access.id = policy->uid;
1348 break;
1349
1350 case BUSNAME_POLICY_TYPE_GROUP:
1351 item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
1352 item->policy_access.id = policy->gid;
1353 break;
1354
1355 case BUSNAME_POLICY_TYPE_WORLD:
1356 item->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
1357 break;
1358
1359 default:
1360 assert_not_reached("Unknown policy type");
1361 }
1362
1363 switch (policy->access) {
1364 case BUSNAME_POLICY_ACCESS_SEE:
1365 item->policy_access.access = KDBUS_POLICY_SEE;
1366 break;
1367
1368 case BUSNAME_POLICY_ACCESS_TALK:
1369 item->policy_access.access = KDBUS_POLICY_TALK;
1370 break;
1371
1372 case BUSNAME_POLICY_ACCESS_OWN:
1373 item->policy_access.access = KDBUS_POLICY_OWN;
1374 break;
1375
1376 default:
1377 assert_not_reached("Unknown policy access");
1378 }
1379}
1380
5892a914 1381int bus_kernel_create_starter(const char *bus, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy) {
e821075a
LP
1382 struct kdbus_cmd_hello *hello;
1383 struct kdbus_item *n;
1683342a
DM
1384 size_t policy_cnt = 0;
1385 BusNamePolicy *po;
1386 size_t size;
e821075a
LP
1387 char *p;
1388 int fd;
1389
1390 assert(bus);
1391 assert(name);
1392
f8294e41 1393 p = alloca(strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1);
e821075a
LP
1394 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
1395
1396 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1397 if (fd < 0)
1398 return -errno;
1399
1683342a
DM
1400 LIST_FOREACH(policy, po, policy)
1401 policy_cnt++;
1402
1403 size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
1404 ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
1405 policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
1406
1407 hello = alloca0(size);
e821075a
LP
1408
1409 n = hello->items;
1410 strcpy(n->str, name);
1411 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
613ec4b8 1412 n->type = KDBUS_ITEM_NAME;
1683342a
DM
1413 n = KDBUS_ITEM_NEXT(n);
1414
1415 LIST_FOREACH(policy, po, policy) {
1416 n->type = KDBUS_ITEM_POLICY_ACCESS;
1417 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
1418 bus_kernel_translate_policy(po, n);
1419 n = KDBUS_ITEM_NEXT(n);
1420 }
e821075a 1421
1683342a 1422 hello->size = size;
5892a914
DM
1423 hello->conn_flags =
1424 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
1425 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
e821075a 1426 hello->pool_size = KDBUS_POOL_SIZE;
d2e7b05f 1427 hello->attach_flags = _KDBUS_ATTACH_ALL;
e821075a
LP
1428
1429 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
03e334a1 1430 safe_close(fd);
e821075a
LP
1431 return -errno;
1432 }
1433
1434 /* The higher 32bit of both flags fields are considered
1435 * 'incompatible flags'. Refuse them all for now. */
1436 if (hello->bus_flags > 0xFFFFFFFFULL ||
1437 hello->conn_flags > 0xFFFFFFFFULL) {
03e334a1 1438 safe_close(fd);
e821075a
LP
1439 return -ENOTSUP;
1440 }
1441
b28ff39f 1442 if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash)) {
03e334a1 1443 safe_close(fd);
e821075a
LP
1444 return -ENOTSUP;
1445 }
1446
1447 return fd;
1448}
1449
486e99a3 1450int bus_kernel_create_domain(const char *name, char **s) {
816a3f9e 1451 struct kdbus_cmd_make *make;
9bd37b40
LP
1452 struct kdbus_item *n;
1453 int fd;
1454
1455 assert(name);
1456 assert(s);
1457
1458 fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
1459 if (fd < 0)
1460 return -errno;
1461
816a3f9e 1462 make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
9bd37b40
LP
1463 offsetof(struct kdbus_item, str) +
1464 strlen(name) + 1));
1465
1466 n = make->items;
1467 strcpy(n->str, name);
1468 n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
5e16c257 1469 n->type = KDBUS_ITEM_MAKE_NAME;
9bd37b40 1470
816a3f9e 1471 make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
f7c7cd03 1472 make->flags = KDBUS_MAKE_ACCESS_WORLD;
9bd37b40 1473
486e99a3 1474 if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
03e334a1 1475 safe_close(fd);
9bd37b40
LP
1476 return -errno;
1477 }
1478
f9638db8
LP
1479 /* The higher 32bit of the flags field are considered
1480 * 'incompatible flags'. Refuse them all for now. */
1481 if (make->flags > 0xFFFFFFFFULL) {
03e334a1 1482 safe_close(fd);
f9638db8
LP
1483 return -ENOTSUP;
1484 }
1485
9bd37b40
LP
1486 if (s) {
1487 char *p;
1488
486e99a3 1489 p = strappend("/dev/kdbus/domain/", name);
9bd37b40 1490 if (!p) {
03e334a1 1491 safe_close(fd);
9bd37b40
LP
1492 return -ENOMEM;
1493 }
1494
1495 *s = p;
1496 }
1497
1498 return fd;
1499}
c8fa3f60 1500
b6c631f3
KS
1501int bus_kernel_create_monitor(const char *bus) {
1502 struct kdbus_cmd_hello *hello;
1503 char *p;
1504 int fd;
c8fa3f60
LS
1505
1506 assert(bus);
1507
f8294e41 1508 p = alloca(strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1);
b6c631f3 1509 sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
c8fa3f60 1510
b6c631f3
KS
1511 fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
1512 if (fd < 0)
c8fa3f60
LS
1513 return -errno;
1514
b6c631f3
KS
1515 hello = alloca0(sizeof(struct kdbus_cmd_hello));
1516 hello->size = sizeof(struct kdbus_cmd_hello);
1517 hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
1518 hello->pool_size = KDBUS_POOL_SIZE;
1519
1520 if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
03e334a1 1521 safe_close(fd);
b6c631f3
KS
1522 return -errno;
1523 }
1524
1525 /* The higher 32bit of both flags fields are considered
1526 * 'incompatible flags'. Refuse them all for now. */
1527 if (hello->bus_flags > 0xFFFFFFFFULL ||
1528 hello->conn_flags > 0xFFFFFFFFULL) {
03e334a1 1529 safe_close(fd);
b6c631f3
KS
1530 return -ENOTSUP;
1531 }
1532
1533 return fd;
c8fa3f60 1534}
ae095f86
LP
1535
1536int bus_kernel_try_close(sd_bus *bus) {
1537 assert(bus);
1538 assert(bus->is_kernel);
1539
1540 if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
1541 return -errno;
1542
1543 return 0;
1544}
ff975efb
LP
1545
1546int bus_kernel_drop_one(int fd) {
1547 struct kdbus_cmd_recv recv = {
1548 .flags = KDBUS_RECV_DROP
1549 };
1550
1551 assert(fd >= 0);
1552
1553 if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1554 return -errno;
1555
1556 return 0;
1557}