bus-kernel.c revision 606303a93ea52a70ebba55bb3152820e630f2164
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2013 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#ifdef HAVE_VALGRIND_MEMCHECK_H
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <valgrind/memcheck.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#endif
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <fcntl.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <malloc.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/mman.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/prctl.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering/* When we include libgen.h because we need dirname() we immediately
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * undefine basename() since libgen.h defines it as a macro to the XDG
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * version which is really broken. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <libgen.h>
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#undef basename
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "strv.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "memfd-util.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "capability.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "fileio.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-internal.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-message.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "bus-kernel.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-bloom.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-label.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
4f10118016f9b2fd7e1d26c9ef7d91eb33fba694Lennart Poettering assert(s);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!startswith(s, ":1."))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atou64(s + 3, id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(sz > 0);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = ALIGN8_PTR(*d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Note that p can be NULL, which encodes a region full of
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * zeroes, which is useful to optimize certain padding
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * conditions */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->vec.address = PTR_TO_UINT64(p);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->vec.size = sz;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void append_payload_memfd(struct kdbus_item **d, int memfd, size_t start, size_t sz) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(memfd >= 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(sz > 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *d = ALIGN8_PTR(*d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->memfd.fd = memfd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->memfd.start = start;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->memfd.size = sz;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void append_destination(struct kdbus_item **d, const char *s, size_t length) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(s);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = ALIGN8_PTR(*d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering (*d)->type = KDBUS_ITEM_DST_NAME;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering memcpy((*d)->str, s, length + 1);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct kdbus_item *i;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering i = ALIGN8_PTR(*d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering i->size = offsetof(struct kdbus_item, bloom_filter) +
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering offsetof(struct kdbus_bloom_filter, data) +
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering length;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering i->type = KDBUS_ITEM_BLOOM_FILTER;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return &i->bloom_filter;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(fds);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(n_fds > 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *d = ALIGN8_PTR(*d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (*d)->type = KDBUS_ITEM_FDS;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering memcpy((*d)->fds, fds, sizeof(int) * n_fds);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char *e;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(data);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(size > 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(i < 64);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering e = stpcpy(buf, "arg");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (i < 10)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *(e++) = '0' + (char) i;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *(e++) = '0' + (char) (i / 10);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *(e++) = '0' + (char) (i % 10);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *e = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, size, n_hash, buf, t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering strcpy(e, "-dot-prefix");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_prefixes(data, size, n_hash, buf, t, '.');
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering strcpy(e, "-slash-prefix");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_prefixes(data, size, n_hash, buf, t, '/');
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack void *data;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned i;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(m);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(bloom);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack data = bloom->data;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack memzero(data, m->bus->bloom_size);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack bloom->generation = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->interface)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->member)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->path) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_rewind(m, true);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering for (i = 0; i < 64; i++) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *t, *contents;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char type;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_peek_type(m, &type, &contents);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* The bloom filter includes simple strings of any kind */
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering r = sd_bus_message_read_basic(m, type, &t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* As well as array of simple strings of any kinds */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_enter_container(m, type, contents);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_exit_container(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Stop adding to bloom filter as soon as we
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * run into the first argument we cannot add
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * to it. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct bus_body_part *part;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct kdbus_item *d;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *destination;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bool well_known;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering uint64_t unique;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering size_t sz, dl;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack unsigned i;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(b);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering assert(m);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(m->sealed);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* We put this together only once, if this message is reused
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * we reuse the earlier-built version */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (m->kdbus)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering destination = m->destination ?: m->destination_ptr;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (destination) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = bus_kernel_parse_unique_name(destination, &unique);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering well_known = r == 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering well_known = false;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz = offsetof(struct kdbus_msg, items);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Add in fixed header, fields header and payload */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) +
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MAX(sizeof(struct kdbus_vec),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sizeof(struct kdbus_memfd)));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Add space for bloom filter */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering offsetof(struct kdbus_bloom_filter, data) +
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->bus->bloom_size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Add in well-known destination header */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (well_known) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dl = strlen(destination);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Add space for unix fds */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->n_fds > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus = memalign(8, sz);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!m->kdbus) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek }
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek m->free_kdbus = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering memzero(m->kdbus, sz);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->flags =
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) |
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0);
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (well_known)
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering /* verify_destination_id will usually be 0, which makes the kernel driver only look
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * at the provided well-known name. Otherwise, the kernel will make sure the provided
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * destination id matches the owner of the provided weel-known-name, and fail if they
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * differ. Currently, this is only needed for bus-proxyd. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->dst_id = m->verify_destination_id;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->cookie = m->header->dbus2.cookie;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->priority = m->priority;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->cookie_reply = m->reply_cookie;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct timespec now;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->timeout * NSEC_PER_USEC;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering d = m->kdbus->items;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (well_known)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering append_destination(&d, destination, dl);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MESSAGE_FOREACH_PART(part, i, m) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (part->is_zero) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* If this is padding then simply send a
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * vector with a NULL data pointer which the
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * kernel will just pass through. This is the
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * most efficient way to encode zeroes */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering append_payload_vec(&d, NULL, part->size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (part->memfd >= 0 && part->sealed && destination) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Try to send a memfd, if the part is
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * sealed and this is not a broadcast. Since we can only */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering append_payload_memfd(&d, part->memfd, part->memfd_offset, part->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering continue;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Otherwise, let's send a vector to the actual data.
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * For that, we need to map it first. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = bus_body_part_map(part);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering append_payload_vec(&d, part->data, part->size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->header->type == SD_BUS_MESSAGE_SIGNAL) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct kdbus_bloom_filter *bloom;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom = append_bloom(&d, m->bus->bloom_size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = bus_message_setup_bloom(m, bloom);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->n_fds > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering append_fds(&d, m->fds, m->n_fds);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m->kdbus->size <= sz);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringfail:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->poisoned = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void unset_memfds(struct sd_bus_message *m) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct bus_body_part *part;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned i;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Make sure the memfds are not freed twice */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering MESSAGE_FOREACH_PART(part, i, m)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (part->memfd >= 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering part->memfd = -1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!ts)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!(bus->attach_flags & KDBUS_ATTACH_TIMESTAMP))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->realtime = ts->realtime_ns / NSEC_PER_USEC;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->monotonic = ts->monotonic_ns / NSEC_PER_USEC;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->seqnum = ts->seqnum;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_message *m = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct kdbus_item *d;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned n_fds = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_free_ int *fds = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct bus_header *header = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering void *footer = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t header_size = 0, footer_size = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t n_bytes = 0, idx = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *destination = NULL, *seclabel = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering bool last_was_memfd = false;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(k);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering KDBUS_ITEM_FOREACH(d, k, items) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t l;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering l = d->size - offsetof(struct kdbus_item, data);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering switch (d->type) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_PAYLOAD_OFF:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!header) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering header = (struct bus_header*)((uint8_t*) k + d->vec.offset);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering header_size = d->vec.size;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering footer = (uint8_t*) k + d->vec.offset;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering footer_size = d->vec.size;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n_bytes += d->vec.size;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering last_was_memfd = false;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_PAYLOAD_MEMFD:
db2cb23b5b179707000d28a11efb3d888d06ee80Umut Tezduyar Lindskog if (!header) /* memfd cannot be first part */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EBADMSG;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n_bytes += d->memfd.size;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering last_was_memfd = true;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_FDS: {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int *f;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned j;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering j = l / sizeof(int);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering f = realloc(fds, sizeof(int) * (n_fds + j));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!f)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering fds = f;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering memcpy(fds + n_fds, d->fds, sizeof(int) * j);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n_fds += j;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_SECLABEL:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering seclabel = d->str;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (last_was_memfd) /* memfd cannot be last part */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EBADMSG;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!header)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EBADMSG;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (header_size < sizeof(struct bus_header))
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return -EBADMSG;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack /* on kdbus we only speak native endian gvariant, never dbus1
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack * marshalling or reverse endian */
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (header->version != 2 ||
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack header->endian != BUS_NATIVE_ENDIAN)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return -EPROTOTYPE;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = bus_message_from_header(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering header, header_size,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering footer, footer_size,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n_bytes,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering fds, n_fds,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering NULL,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering seclabel, 0, &m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* The well-known names list is different from the other
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering credentials. If we asked for it, but nothing is there, this
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering means that the list of well-known names is simply empty, not
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering that we lack any data */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering KDBUS_ITEM_FOREACH(d, k, items) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t l;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering l = d->size - offsetof(struct kdbus_item, data);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering switch (d->type) {
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_PAYLOAD_OFF: {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t begin_body;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering begin_body = BUS_MESSAGE_BODY_BEGIN(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt if (idx + d->vec.size > begin_body) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct bus_body_part *part;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Contains body material */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering part = message_append_part(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!part) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* A -1 offset is NUL padding. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering part->is_zero = d->vec.offset == ~0ULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (idx >= begin_body) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!part->is_zero)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->data = (uint8_t* )k + d->vec.offset;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->size = d->vec.size;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!part->is_zero)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->data = (uint8_t*) k + d->vec.offset + (begin_body - idx);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->size = d->vec.size - (begin_body - idx);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->sealed = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack idx += d->vec.size;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack break;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_PAYLOAD_MEMFD: {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct bus_body_part *part;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering r = -EBADMSG;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering goto fail;
ff975efb2e88dcd5221a2f0d76c4c87e85b821a8Lennart Poettering }
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering part = message_append_part(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!part) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->memfd = d->memfd.fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->memfd_offset = d->memfd.start;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->size = d->memfd.size;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering part->sealed = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering idx += d->memfd.size;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_PIDS:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* The PID/TID might be missing, when the data
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * is faked by a bus proxy and it lacks that
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * information about the real client (since
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * SO_PEERCRED is used for that). Also kernel
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * namespacing might make some of this data
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering * unavailable when untranslatable. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (d->pids.pid > 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.pid = (pid_t) d->pids.pid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (d->pids.tid > 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.tid = (pid_t) d->pids.tid;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_CREDS:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* EUID/SUID/FSUID/EGID/SGID/FSGID might be
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * missing too (see above). */
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((uid_t) d->creds.uid != UID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.uid = (uid_t) d->creds.uid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if ((uid_t) d->creds.euid != UID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.euid = (uid_t) d->creds.euid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((uid_t) d->creds.suid != UID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.suid = (uid_t) d->creds.suid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((uid_t) d->creds.fsuid != UID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.fsuid = (uid_t) d->creds.fsuid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((gid_t) d->creds.gid != GID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.gid = (gid_t) d->creds.gid;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if ((gid_t) d->creds.egid != GID_INVALID) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.egid = (gid_t) d->creds.egid;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if ((gid_t) d->creds.sgid != GID_INVALID) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.sgid = (gid_t) d->creds.sgid;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if ((gid_t) d->creds.fsgid != GID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.fsgid = (gid_t) d->creds.fsgid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_TIMESTAMP:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering message_set_timestamp(bus, m, &d->timestamp);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_PID_COMM:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.comm = d->str;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_TID_COMM:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.tid_comm = d->str;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_EXE:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.exe = d->str;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_CMDLINE:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.cmdline = d->str;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.cmdline_size = l;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_CGROUP:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.cgroup = d->str;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering 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;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = bus_get_root_path(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.cgroup_root = bus->cgroup_root;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_AUDIT:
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((uid_t) d->audit.loginuid != UID_INVALID) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_CAPS:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (d->caps.last_cap != cap_last_cap() ||
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = -EBADMSG;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->creds.capability = d->caps.caps;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering 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;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_DST_NAME:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!service_name_is_valid(d->str)) {
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering r = -EBADMSG;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering destination = d->str;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KDBUS_ITEM_OWNED_NAME:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!service_name_is_valid(d->name.name)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -EBADMSG;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char **wkn;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t n;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* We just extend the array here, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * do not allocate the strings inside
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * of it, instead we just point to our
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * buffer directly. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering n = strv_length(m->creds.well_known_names);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*));
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!wkn) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = -ENOMEM;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering wkn[n] = d->name.name;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering wkn[n+1] = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.well_known_names = wkn;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering break;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering case KDBUS_ITEM_CONN_DESCRIPTION:
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering m->creds.description = d->str;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering break;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering case KDBUS_ITEM_AUXGROUPS:
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering size_t i, n;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering gid_t *g;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering g = new(gid_t, n);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!g) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = -ENOMEM;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering for (i = 0; i < n; i++)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering g[i] = d->data64[i];
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.supplementary_gids = g;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.n_supplementary_gids = n;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering break;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering case KDBUS_ITEM_FDS:
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering case KDBUS_ITEM_SECLABEL:
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering break;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering default:
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering log_debug("Got unknown field from kernel %llu", d->type);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* If we requested the list of well-known names to be appended
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * and the sender had none no item for it will be
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * attached. However, this does *not* mean that the kernel
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * didn't want to provide this information to us. Hence, let's
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * explicitly mark this information as available if it was
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * requested. */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->creds.mask |= bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = bus_message_parse_fields(m);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* Refuse messages if kdbus and dbus1 cookie doesn't match up */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if ((uint64_t) m->header->dbus2.cookie != k->cookie) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = -EBADMSG;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* Refuse messages where the reply flag doesn't match up */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_EXPECT_REPLY)) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = -EBADMSG;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* Refuse reply messages where the reply cookie doesn't match up */
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) {
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering r = -EBADMSG;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering goto fail;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* Refuse messages where the autostart flag doesn't match up */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_NO_AUTO_START)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -EBADMSG;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Override information from the user header with data from the kernel */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k->src_id == KDBUS_SRC_ID_KERNEL)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bus_message_set_sender_driver(bus, m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering m->sender = m->creds.unique_name = m->sender_buffer;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (destination)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->destination = destination;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->destination = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else if (k->dst_id == KDBUS_DST_ID_NAME)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->destination = m->destination_buffer;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* We take possession of the kmsg struct now */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->kdbus = k;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->release_kdbus = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->free_fds = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering fds = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering bus->rqueue[bus->rqueue_size++] = m;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringfail:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unset_memfds(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_message_unref(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringint bus_kernel_take_fd(sd_bus *b) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct kdbus_bloom_parameter *bloom = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct kdbus_item *items, *item;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering struct kdbus_cmd_hello *hello;
deffddf1df29a5ed047feff3a0f2b765006fb71bLukas Nykryn _cleanup_free_ char *g = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t l = 0, m = 0, sz;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering assert(b);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (b->is_server)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->use_memfd = 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (b->description) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering g = bus_label_escape(b->description);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!g)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering name = g;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char pr[17] = {};
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* If no name is explicitly set, we'll include a hint
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * indicating the library implementation, a hint which
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * kind of bus this is and the thread name */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (isempty(pr)) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering name = b->is_system ? "sd-system" :
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->is_user ? "sd-user" : "sd";
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_free_ char *e = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e = bus_label_escape(pr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!e)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering g = strappend(b->is_system ? "sd-system-" :
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->is_user ? "sd-user-" : "sd-",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!g)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering name = g;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->description = bus_label_unescape(name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!b->description)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m = strlen(name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (b->fake_creds_valid)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (b->fake_pids_valid)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (b->fake_label) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering l = strlen(b->fake_label);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello = alloca0_align(sz, 8);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello->size = sz;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello->flags = b->hello_flags;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello->attach_flags_send = _KDBUS_ATTACH_ANY;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello->attach_flags_recv = b->attach_flags;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering hello->pool_size = KDBUS_POOL_SIZE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item = hello->items;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->size = offsetof(struct kdbus_item, str) + m + 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->type = KDBUS_ITEM_CONN_DESCRIPTION;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering memcpy(item->str, name, m + 1);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item = KDBUS_ITEM_NEXT(item);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (b->fake_creds_valid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->type = KDBUS_ITEM_CREDS;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->creds = b->fake_creds;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item = KDBUS_ITEM_NEXT(item);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (b->fake_pids_valid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering item->type = KDBUS_ITEM_PIDS;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering item->pids = b->fake_pids;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering item = KDBUS_ITEM_NEXT(item);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering }
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering if (b->fake_label) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->size = offsetof(struct kdbus_item, str) + l + 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering item->type = KDBUS_ITEM_SECLABEL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering memcpy(item->str, b->fake_label, l+1);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -errno;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!b->kdbus_buffer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (b->kdbus_buffer == MAP_FAILED) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->kdbus_buffer = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = -errno;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* The higher 32bit of the bus_flags fields are considered
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * 'incompatible flags'. Refuse them all for now. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (hello->bus_flags > 0xFFFFFFFFULL) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -ENOTSUP;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* extract bloom parameters from items */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering KDBUS_FOREACH(item, items, hello->items_size) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering switch (item->type) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case KDBUS_ITEM_BLOOM_PARAMETER:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bloom = &item->bloom_parameter;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -ENOTSUP;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->bloom_size = (size_t) bloom->size;
700ff4d97311902a440109a2c081731ab6ae8a20Lennart Poettering b->bloom_n_hash = (unsigned) bloom->n_hash;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->unique_id = hello->id;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->is_kernel = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->bus_client = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->message_version = 2;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->message_endian = BUS_NATIVE_ENDIAN;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* the kernel told us the UUID of the underlying bus */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* free returned items */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (void) bus_kernel_cmd_free(b, hello->offset);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return bus_start_running(b);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (void) bus_kernel_cmd_free(b, hello->offset);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringint bus_kernel_connect(sd_bus *b) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(b);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(b->input_fd < 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(b->output_fd < 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(b->kernel);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (b->is_server)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (b->input_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering b->output_fd = b->input_fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return bus_kernel_take_fd(b);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct kdbus_cmd_free cmd = {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .size = sizeof(cmd),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .offset = offset,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering };
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus->is_kernel);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
return 0;
}
static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
struct kdbus_item *d;
assert(bus);
assert(k);
KDBUS_ITEM_FOREACH(d, k, items) {
if (d->type == KDBUS_ITEM_FDS)
close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
safe_close(d->memfd.fd);
}
bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer);
}
int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
struct kdbus_cmd_send cmd = { };
int r;
assert(bus);
assert(m);
assert(bus->state == BUS_RUNNING);
/* If we can't deliver, we want room for the error message */
r = bus_rqueue_make_room(bus);
if (r < 0)
return r;
r = bus_message_setup_kmsg(bus, m);
if (r < 0)
return r;
cmd.size = sizeof(cmd);
cmd.msg_address = (uintptr_t)m->kdbus;
/* If this is a synchronous method call, then let's tell the
* kernel, so that it can pass CPU time/scheduling to the
* destination for the time, if it wants to. If we
* synchronously wait for the result anyway, we won't need CPU
* anyway. */
if (hint_sync_call) {
m->kdbus->flags |= KDBUS_MSG_EXPECT_REPLY;
cmd.flags |= KDBUS_SEND_SYNC_REPLY;
}
r = ioctl(bus->output_fd, KDBUS_CMD_SEND, &cmd);
if (r < 0) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *reply;
if (errno == EAGAIN || errno == EINTR)
return 0;
else if (errno == ENXIO || errno == ESRCH) {
/* ENXIO: unique name not known
* ESRCH: well-known name not known */
if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
else {
log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
return 0;
}
} else if (errno == EADDRNOTAVAIL) {
/* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
else {
log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
return 0;
}
} else
return -errno;
r = bus_message_new_synthetic_error(
bus,
BUS_MESSAGE_COOKIE(m),
&error,
&reply);
if (r < 0)
return r;
r = bus_seal_synthetic_message(bus, reply);
if (r < 0)
return r;
bus->rqueue[bus->rqueue_size++] = reply;
} else if (hint_sync_call) {
struct kdbus_msg *k;
k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + cmd.reply.offset);
assert(k);
if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
r = bus_kernel_make_message(bus, k);
if (r < 0) {
close_kdbus_msg(bus, k);
/* Anybody can send us invalid messages, let's just drop them. */
if (r == -EBADMSG || r == -EPROTOTYPE)
log_debug_errno(r, "Ignoring invalid synchronous reply: %m");
else
return r;
}
} else {
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
close_kdbus_msg(bus, k);
}
}
return 1;
}
static int push_name_owner_changed(
sd_bus *bus,
const char *name,
const char *old_owner,
const char *new_owner,
const struct kdbus_timestamp *ts) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
int r;
assert(bus);
r = sd_bus_message_new_signal(
bus,
&m,
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"NameOwnerChanged");
if (r < 0)
return r;
r = sd_bus_message_append(m, "sss", name, old_owner, new_owner);
if (r < 0)
return r;
bus_message_set_sender_driver(bus, m);
message_set_timestamp(bus, m, ts);
r = bus_seal_synthetic_message(bus, m);
if (r < 0)
return r;
bus->rqueue[bus->rqueue_size++] = m;
m = NULL;
return 1;
}
static int translate_name_change(
sd_bus *bus,
const struct kdbus_msg *k,
const struct kdbus_item *d,
const struct kdbus_timestamp *ts) {
char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX];
assert(bus);
assert(k);
assert(d);
if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
old_owner[0] = 0;
else
sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
if (isempty(old_owner))
return 0;
new_owner[0] = 0;
} else
sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts);
}
static int translate_id_change(
sd_bus *bus,
const struct kdbus_msg *k,
const struct kdbus_item *d,
const struct kdbus_timestamp *ts) {
char owner[UNIQUE_NAME_MAX];
assert(bus);
assert(k);
assert(d);
sprintf(owner, ":1.%llu", d->id_change.id);
return push_name_owner_changed(
bus, owner,
d->type == KDBUS_ITEM_ID_ADD ? NULL : owner,
d->type == KDBUS_ITEM_ID_ADD ? owner : NULL,
ts);
}
static int translate_reply(
sd_bus *bus,
const struct kdbus_msg *k,
const struct kdbus_item *d,
const struct kdbus_timestamp *ts) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
int r;
assert(bus);
assert(k);
assert(d);
r = bus_message_new_synthetic_error(
bus,
k->cookie_reply,
d->type == KDBUS_ITEM_REPLY_TIMEOUT ?
&SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out") :
&SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call peer died"),
&m);
if (r < 0)
return r;
message_set_timestamp(bus, m, ts);
r = bus_seal_synthetic_message(bus, m);
if (r < 0)
return r;
bus->rqueue[bus->rqueue_size++] = m;
m = NULL;
return 1;
}
static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = {
[KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
[KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
[KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change,
[KDBUS_ITEM_ID_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
[KDBUS_ITEM_ID_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_id_change,
[KDBUS_ITEM_REPLY_TIMEOUT - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
[KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply,
};
struct kdbus_item *d, *found = NULL;
struct kdbus_timestamp *ts = NULL;
assert(bus);
assert(k);
assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
KDBUS_ITEM_FOREACH(d, k, items) {
if (d->type == KDBUS_ITEM_TIMESTAMP)
ts = &d->timestamp;
if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
if (found)
return -EBADMSG;
found = d;
} else
log_debug("Got unknown field from kernel %llu", d->type);
}
if (!found) {
log_debug("Didn't find a kernel message to translate.");
return 0;
}
return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found, ts);
}
int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
struct kdbus_msg *k;
int r;
assert(bus);
r = bus_rqueue_make_room(bus);
if (r < 0)
return r;
if (hint_priority) {
recv.flags |= KDBUS_RECV_USE_PRIORITY;
recv.priority = priority;
}
r = ioctl(bus->input_fd, KDBUS_CMD_RECV, &recv);
if (recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS)
log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
if (r < 0) {
if (errno == EAGAIN)
return 0;
return -errno;
}
k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.msg.offset);
if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
r = bus_kernel_make_message(bus, k);
/* Anybody can send us invalid messages, let's just drop them. */
if (r == -EBADMSG || r == -EPROTOTYPE) {
log_debug_errno(r, "Ignoring invalid message: %m");
r = 0;
}
} else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
r = bus_kernel_translate_message(bus, k);
else {
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
r = 0;
}
if (r <= 0)
close_kdbus_msg(bus, k);
return r < 0 ? r : 1;
}
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
struct memfd_cache *c;
int fd;
assert(address);
assert(mapped);
assert(allocated);
if (!bus || !bus->is_kernel)
return -ENOTSUP;
assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
if (bus->n_memfd_cache <= 0) {
int r;
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
r = memfd_new(bus->description);
if (r < 0)
return r;
*address = NULL;
*mapped = 0;
*allocated = 0;
return r;
}
c = &bus->memfd_cache[--bus->n_memfd_cache];
assert(c->fd >= 0);
assert(c->mapped == 0 || c->address);
*address = c->address;
*mapped = c->mapped;
*allocated = c->allocated;
fd = c->fd;
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
return fd;
}
static void close_and_munmap(int fd, void *address, size_t size) {
if (size > 0)
assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
safe_close(fd);
}
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
struct memfd_cache *c;
uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
assert(fd >= 0);
assert(mapped == 0 || address);
if (!bus || !bus->is_kernel) {
close_and_munmap(fd, address, mapped);
return;
}
assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
close_and_munmap(fd, address, mapped);
return;
}
c = &bus->memfd_cache[bus->n_memfd_cache++];
c->fd = fd;
c->address = address;
/* If overly long, let's return a bit to the OS */
if (mapped > max_mapped) {
assert_se(memfd_set_size(fd, max_mapped) >= 0);
assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
c->mapped = c->allocated = max_mapped;
} else {
c->mapped = mapped;
c->allocated = allocated;
}
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
}
void bus_kernel_flush_memfd(sd_bus *b) {
unsigned i;
assert(b);
for (i = 0; i < b->n_memfd_cache; i++)
close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
}
uint64_t request_name_flags_to_kdbus(uint64_t flags) {
uint64_t f = 0;
if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
f |= KDBUS_NAME_ALLOW_REPLACEMENT;
if (flags & SD_BUS_NAME_REPLACE_EXISTING)
f |= KDBUS_NAME_REPLACE_EXISTING;
if (flags & SD_BUS_NAME_QUEUE)
f |= KDBUS_NAME_QUEUE;
return f;
}
uint64_t attach_flags_to_kdbus(uint64_t mask) {
uint64_t m = 0;
if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
m |= KDBUS_ATTACH_CREDS;
if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID))
m |= KDBUS_ATTACH_PIDS;
if (mask & SD_BUS_CREDS_COMM)
m |= KDBUS_ATTACH_PID_COMM;
if (mask & SD_BUS_CREDS_TID_COMM)
m |= KDBUS_ATTACH_TID_COMM;
if (mask & SD_BUS_CREDS_EXE)
m |= KDBUS_ATTACH_EXE;
if (mask & SD_BUS_CREDS_CMDLINE)
m |= KDBUS_ATTACH_CMDLINE;
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))
m |= KDBUS_ATTACH_CGROUP;
if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS))
m |= KDBUS_ATTACH_CAPS;
if (mask & SD_BUS_CREDS_SELINUX_CONTEXT)
m |= KDBUS_ATTACH_SECLABEL;
if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
m |= KDBUS_ATTACH_AUDIT;
if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
m |= KDBUS_ATTACH_NAMES;
if (mask & SD_BUS_CREDS_DESCRIPTION)
m |= KDBUS_ATTACH_CONN_DESCRIPTION;
if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
m |= KDBUS_ATTACH_AUXGROUPS;
return m;
}
int bus_kernel_create_bus(const char *name, bool world, char **s) {
struct kdbus_cmd *make;
struct kdbus_item *n;
size_t l;
int fd;
assert(name);
assert(s);
fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
l = strlen(name);
make = alloca0_align(offsetof(struct kdbus_cmd, items) +
ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
8);
make->size = offsetof(struct kdbus_cmd, items);
/* Set the bloom parameters */
n = make->items;
n->size = offsetof(struct kdbus_item, bloom_parameter) +
sizeof(struct kdbus_bloom_parameter);
n->type = KDBUS_ITEM_BLOOM_PARAMETER;
n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
assert_cc(DEFAULT_BLOOM_SIZE > 0);
assert_cc(DEFAULT_BLOOM_N_HASH > 0);
make->size += ALIGN8(n->size);
/* The busses we create make no restrictions on what metadata
* peers can read from incoming messages. */
n = KDBUS_ITEM_NEXT(n);
n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
n->data64[0] = _KDBUS_ATTACH_ANY;
make->size += ALIGN8(n->size);
/* Provide all metadata via bus-owner queries */
n = KDBUS_ITEM_NEXT(n);
n->type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
n->data64[0] = _KDBUS_ATTACH_ANY;
make->size += ALIGN8(n->size);
/* Set the a good name */
n = KDBUS_ITEM_NEXT(n);
sprintf(n->str, UID_FMT "-%s", getuid(), name);
n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
n->type = KDBUS_ITEM_MAKE_NAME;
make->size += ALIGN8(n->size);
make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
safe_close(fd);
return -errno;
}
if (s) {
char *p;
p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
}
*s = p;
}
return fd;
}
int bus_kernel_open_bus_fd(const char *bus, char **path) {
char *p;
int fd;
size_t len;
assert(bus);
len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
if (path) {
p = new(char, len);
if (!p)
return -ENOMEM;
} else
p = newa(char, len);
sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0) {
if (path)
free(p);
return -errno;
}
if (path)
*path = p;
return fd;
}
int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
_cleanup_free_ char *path = NULL;
struct kdbus_cmd *make;
struct kdbus_item *n;
const char *name;
int fd;
fd = bus_kernel_open_bus_fd(bus_name, &path);
if (fd < 0)
return fd;
make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd, items)) +
ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
8);
make->size = ALIGN8(offsetof(struct kdbus_cmd, items));
make->flags = KDBUS_MAKE_ACCESS_WORLD;
n = make->items;
sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
n->type = KDBUS_ITEM_MAKE_NAME;
make->size += ALIGN8(n->size);
name = n->str;
if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
safe_close(fd);
return -errno;
}
if (ep_path) {
char *p;
p = strjoin(dirname(path), "/", name, NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
}
*ep_path = p;
}
return fd;
}
int bus_kernel_try_close(sd_bus *bus) {
struct kdbus_cmd byebye = { .size = sizeof(byebye) };
assert(bus);
assert(bus->is_kernel);
if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE, &byebye) < 0)
return -errno;
return 0;
}
int bus_kernel_drop_one(int fd) {
struct kdbus_cmd_recv recv = {
.size = sizeof(recv),
.flags = KDBUS_RECV_DROP,
};
assert(fd >= 0);
if (ioctl(fd, KDBUS_CMD_RECV, &recv) < 0)
return -errno;
return 0;
}
int bus_kernel_realize_attach_flags(sd_bus *bus) {
struct kdbus_cmd *update;
struct kdbus_item *n;
assert(bus);
assert(bus->is_kernel);
update = alloca0_align(offsetof(struct kdbus_cmd, items) +
ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
8);
n = update->items;
n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
n->data64[0] = bus->attach_flags;
update->size =
offsetof(struct kdbus_cmd, items) +
ALIGN8(n->size);
if (ioctl(bus->input_fd, KDBUS_CMD_UPDATE, update) < 0)
return -errno;
return 0;
}
int bus_kernel_fix_attach_mask(void) {
_cleanup_free_ char *mask = NULL;
uint64_t m = (uint64_t) -1;
char buf[2+16+2];
int r;
/* By default we don't want any kdbus metadata fields to be
* suppressed, hence we reset the kernel mask for it to
* (uint64_t) -1. If the module argument was overwritten by
* the kernel cmdline, we leave it as is. */
r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask);
if (r < 0)
return log_warning_errno(r, "Failed to read kernel command line: %m");
if (r == 0) {
sprintf(buf, "0x%" PRIx64 "\n", m);
r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf);
if (r < 0)
return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
"Failed to write kdbus attach mask: %m");
}
return 0;
}
int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
struct kdbus_cmd_info cmd = {
.size = sizeof(struct kdbus_cmd_info),
};
struct kdbus_info *info;
struct kdbus_item *item;
char *n = NULL;
int r;
assert(bus);
assert(name);
assert(bus->is_kernel);
r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
if (r < 0)
return -errno;
info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset);
KDBUS_ITEM_FOREACH(item, info, items)
if (item->type == KDBUS_ITEM_MAKE_NAME) {
r = free_and_strdup(&n, item->str);
break;
}
bus_kernel_cmd_free(bus, cmd.offset);
if (r < 0)
return r;
if (!n)
return -EIO;
*name = n;
return 0;
}