bus-kernel.c revision b5dae4c7f77f7c87b91e0afb60a31c690dda4a1f
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen/***
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen This file is part of systemd.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen Copyright 2013 Lennart Poettering
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen systemd is free software; you can redistribute it and/or modify it
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen under the terms of the GNU Lesser General Public License as published by
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen (at your option) any later version.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen systemd is distributed in the hope that it will be useful, but
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen Lesser General Public License for more details.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen You should have received a copy of the GNU Lesser General Public License
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen***/
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen#ifdef HAVE_VALGRIND_MEMCHECK_H
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen#include <valgrind/memcheck.h>
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen#endif
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <fcntl.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <malloc.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <libgen.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <sys/mman.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <sys/prctl.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "util.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "strv.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "memfd-util.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-internal.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-message.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-kernel.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-bloom.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-util.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "bus-label.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "cgroup-util.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(s);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(id);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!startswith(s, ":1."))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = safe_atou64(s + 3, id);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(sz > 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = ALIGN8_PTR(*d);
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Note that p can be NULL, which encodes a region full of
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * zeroes, which is useful to optimize certain padding
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * conditions */
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->type = KDBUS_ITEM_PAYLOAD_VEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->vec.address = PTR_TO_UINT64(p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->vec.size = sz;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmek
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardtstatic void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) {
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt assert(d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(memfd >= 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(sz > 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = ALIGN8_PTR(*d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->memfd.fd = memfd;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->memfd.size = sz;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
a22e1850c36e52cb9d593b99be59b6ba7639d80aLennart Poettering}
a22e1850c36e52cb9d593b99be59b6ba7639d80aLennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void append_destination(struct kdbus_item **d, const char *s, size_t length) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(s);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = ALIGN8_PTR(*d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->type = KDBUS_ITEM_DST_NAME;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek memcpy((*d)->str, s, length + 1);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct kdbus_item *i;
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen assert(d);
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek i = ALIGN8_PTR(*d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek i->size = offsetof(struct kdbus_item, bloom_filter) +
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek offsetof(struct kdbus_bloom_filter, data) +
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek length;
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen i->type = KDBUS_ITEM_BLOOM_FILTER;
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return &i->bloom_filter;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(fds);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(n_fds > 0);
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen *d = ALIGN8_PTR(*d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (*d)->type = KDBUS_ITEM_FDS;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek memcpy((*d)->fds, fds, sizeof(int) * n_fds);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersenstatic int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen void *data;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(bloom);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek data = bloom->data;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek memzero(data, m->bus->bloom_size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom->generation = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->interface)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->member)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->path) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_bus_message_rewind(m, true);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < 64; i++) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char type;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *t;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *e;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_bus_message_peek_type(m, &type, NULL);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (type != SD_BUS_TYPE_STRING &&
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek type != SD_BUS_TYPE_OBJECT_PATH &&
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek type != SD_BUS_TYPE_SIGNATURE)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_bus_message_read_basic(m, type, &t);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek e = stpcpy(buf, "arg");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (i < 10)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *(e++) = '0' + (char) i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *(e++) = '0' + (char) (i / 10);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *(e++) = '0' + (char) (i % 10);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *e = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek strcpy(e, "-dot-prefix");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek strcpy(e, "-slash-prefix");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct bus_body_part *part;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct kdbus_item *d;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *destination;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bool well_known;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek uint64_t unique;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek size_t sz, dl;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(b);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m->sealed);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* We put this together only once, if this message is reused
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * we reuse the earlier-built version */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->kdbus)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek destination = m->destination ?: m->destination_ptr;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (destination) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering r = bus_kernel_parse_unique_name(destination, &unique);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt well_known = r == 0;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek } else
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek well_known = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sz = offsetof(struct kdbus_msg, items);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) ==
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd)));
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering /* Add in fixed header, fields header and payload */
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sz += (1 + m->n_body_parts) *
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Add space for bloom filter */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
56fd6bf795926409b087bce406ea851ad89f9fe8Tom Gundersen offsetof(struct kdbus_bloom_filter, data) +
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->bus->bloom_size);
d0d6a4cd70477970812bff0a37e70f66208d7c14Tom Gundersen
d0d6a4cd70477970812bff0a37e70f66208d7c14Tom Gundersen /* Add in well-known destination header */
d0d6a4cd70477970812bff0a37e70f66208d7c14Tom Gundersen if (well_known) {
d0d6a4cd70477970812bff0a37e70f66208d7c14Tom Gundersen dl = strlen(destination);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Add space for unix fds */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->n_fds > 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus = memalign(8, sz);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!m->kdbus) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = -ENOMEM;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen m->free_kdbus = true;
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen memzero(m->kdbus, sz);
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen m->kdbus->flags =
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (well_known) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* verify_destination_id will usually be 0, which makes the kernel driver only look
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * at the provided well-known name. Otherwise, the kernel will make sure the provided
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt * destination id matches the owner of the provided weel-known-name, and fail if they
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt * differ. Currently, this is only needed for bus-proxyd. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->dst_id = m->verify_destination_id;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->cookie = (uint64_t) m->header->serial;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->priority = m->priority;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta m->kdbus->cookie_reply = m->reply_cookie;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta } else {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta struct timespec now;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
dd2b607b7d1ce355e93f9f71cd256ec20b8ae9c4Thomas Hindoe Paaboel Andersen assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta m->timeout * NSEC_PER_USEC;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta }
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta d = m->kdbus->items;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (well_known)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_destination(&d, destination, dl);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek MESSAGE_FOREACH_PART(part, i, m) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (part->is_zero) {
3ba3a79df4ae094d1008c04a9af8d1ff970124c4Zbigniew Jędrzejewski-Szmek /* If this is padding then simply send a
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * vector with a NULL data pointer which the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * kernel will just pass through. This is the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * most efficient way to encode zeroes */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_payload_vec(&d, NULL, part->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek continue;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (part->memfd >= 0 && part->sealed && destination) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Try to send a memfd, if the part is
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * sealed and this is not a broadcast. Since we can only */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_payload_memfd(&d, part->memfd, part->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek continue;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Otherwise, let's send a vector to the actual data.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * For that, we need to map it first. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = bus_body_part_map(part);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_payload_vec(&d, part->data, part->size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
3ba3a79df4ae094d1008c04a9af8d1ff970124c4Zbigniew Jędrzejewski-Szmek if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct kdbus_bloom_filter *bloom;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bloom = append_bloom(&d, m->bus->bloom_size);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = bus_message_setup_bloom(m, bloom);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (m->n_fds > 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek append_fds(&d, m->fds, m->n_fds);
3ba3a79df4ae094d1008c04a9af8d1ff970124c4Zbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m->kdbus->size <= sz);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekfail:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->poisoned = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void unset_memfds(struct sd_bus_message *m) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct bus_body_part *part;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Make sure the memfds are not freed twice */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek MESSAGE_FOREACH_PART(part, i, m)
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt if (part->memfd >= 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->memfd = -1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
2972cba11712c3bfbe9fa07d1f3c3c4330127733Nick Owens sd_bus_message *m = NULL;
2972cba11712c3bfbe9fa07d1f3c3c4330127733Nick Owens struct kdbus_item *d;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering unsigned n_fds = 0;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering _cleanup_free_ int *fds = NULL;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering struct bus_header *h = NULL;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering size_t total, n_bytes = 0, idx = 0;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering const char *destination = NULL, *seclabel = NULL;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering int r;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering assert(bus);
2972cba11712c3bfbe9fa07d1f3c3c4330127733Nick Owens assert(k);
2972cba11712c3bfbe9fa07d1f3c3c4330127733Nick Owens assert(k->payload_type == KDBUS_PAYLOAD_DBUS);
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering
e2bccc9d9974eb1290653ecfa3ccfd03c313842bDavid Herrmann KDBUS_ITEM_FOREACH(d, k, items) {
e2bccc9d9974eb1290653ecfa3ccfd03c313842bDavid Herrmann size_t l;
e2bccc9d9974eb1290653ecfa3ccfd03c313842bDavid Herrmann
505c5f6de1a5c0afb238a46db94fe3571902cc9dBenedikt Morbach l = d->size - offsetof(struct kdbus_item, data);
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek switch (d->type) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_PAYLOAD_OFF:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!h) {
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!bus_header_is_complete(h, d->vec.size))
5c82dd13e1eef502afcef209a3b14a2100966909Benedikt Morbach return -EBADMSG;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
a46e37cb1225a36a33e8728005693e825cdbc01aSusant Sahani n_bytes += d->vec.size;
a46e37cb1225a36a33e8728005693e825cdbc01aSusant Sahani break;
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering case KDBUS_ITEM_PAYLOAD_MEMFD:
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering if (!h)
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering return -EBADMSG;
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering n_bytes += d->memfd.size;
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt break;
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt case KDBUS_ITEM_FDS: {
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering int *f;
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering unsigned j;
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering j = l / sizeof(int);
a46e37cb1225a36a33e8728005693e825cdbc01aSusant Sahani f = realloc(fds, sizeof(int) * (n_fds + j));
a46e37cb1225a36a33e8728005693e825cdbc01aSusant Sahani if (!f)
941d0aa8f4426b306e246b096175a28676259055Susant Sahani return -ENOMEM;
941d0aa8f4426b306e246b096175a28676259055Susant Sahani
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt fds = f;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek memcpy(fds + n_fds, d->fds, sizeof(int) * j);
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek n_fds += j;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek break;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek }
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek case KDBUS_ITEM_SECLABEL:
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek seclabel = d->str;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek break;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek }
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek }
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek if (!h)
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek return -EBADMSG;
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek
941d0aa8f4426b306e246b096175a28676259055Susant Sahani r = bus_header_message_size(h, &total);
44de7fb14f0fb5b8fe0f829f128c2c3e64114c0cSusant Sahani if (r < 0)
44de7fb14f0fb5b8fe0f829f128c2c3e64114c0cSusant Sahani return r;
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt if (n_bytes != total)
44de7fb14f0fb5b8fe0f829f128c2c3e64114c0cSusant Sahani return -EBADMSG;
44de7fb14f0fb5b8fe0f829f128c2c3e64114c0cSusant Sahani
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani /* on kdbus we only speak native endian gvariant, never dbus1
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani * marshalling or reverse endian */
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani if (h->version != 2 ||
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani h->endian != BUS_NATIVE_ENDIAN)
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani return -EPROTOTYPE;
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
a86cba89bebb4f5fd35841a6251c0baa321dc9a5Susant Sahani if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The well-known names list is different from the other
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek credentials. If we asked for it, but nothing is there, this
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek means that the list of well-known names is simply empty, not
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek that we lack any data */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek KDBUS_ITEM_FOREACH(d, k, items) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek size_t l;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek l = d->size - offsetof(struct kdbus_item, data);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek switch (d->type) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_PAYLOAD_OFF: {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek size_t begin_body;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek begin_body = BUS_MESSAGE_BODY_BEGIN(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (idx + d->vec.size > begin_body) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct bus_body_part *part;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Contains body material */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part = message_append_part(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!part) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = -ENOMEM;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* A -1 offset is NUL padding. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->is_zero = d->vec.offset == ~0ULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (idx >= begin_body) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!part->is_zero)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->data = (uint8_t *)k + d->vec.offset;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->size = d->vec.size;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!part->is_zero)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->size = d->vec.size - (begin_body - idx);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->sealed = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek idx += d->vec.size;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_PAYLOAD_MEMFD: {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct bus_body_part *part;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (idx < BUS_MESSAGE_BODY_BEGIN(m)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = -EBADMSG;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part = message_append_part(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!part) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = -ENOMEM;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->memfd = d->memfd.fd;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->size = d->memfd.size;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek part->sealed = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek idx += d->memfd.size;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
3ba3a79df4ae094d1008c04a9af8d1ff970124c4Zbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_PIDS:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The PID starttime/TID might be missing,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * when the data is faked by some data bus
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * proxy and it lacks that information about
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * the real client since SO_PEERCRED is used
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * for that. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (d->pids.pid > 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.pid = (pid_t) d->pids.pid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (d->pids.starttime > 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.pid_starttime = d->pids.starttime / NSEC_PER_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (d->pids.tid > 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.tid = (pid_t) d->pids.tid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_CREDS:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((uid_t) d->creds.uid != (uid_t) -1) {
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt m->creds.uid = (uid_t) d->creds.uid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((uid_t) d->creds.euid != (uid_t) -1) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.euid = (uid_t) d->creds.euid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((uid_t) d->creds.suid != (uid_t) -1) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.suid = (uid_t) d->creds.suid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((uid_t) d->creds.fsuid != (uid_t) -1) {
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt m->creds.fsuid = (uid_t) d->creds.fsuid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen if ((gid_t) d->creds.gid != (gid_t) -1) {
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen m->creds.gid = (gid_t) d->creds.gid;
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen }
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen if ((gid_t) d->creds.egid != (gid_t) -1) {
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske m->creds.egid = (gid_t) d->creds.egid;
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske }
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske if ((gid_t) d->creds.sgid != (gid_t) -1) {
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske m->creds.sgid = (gid_t) d->creds.sgid;
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
0d07e595cc22379ec7388406c2f4f2a74eea9083Jens Kuske }
769b56a308c3f3d3952eda87fd4fb004207f4f49Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((gid_t) d->creds.fsgid != (gid_t) -1) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.fsgid = (gid_t) d->creds.fsgid;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering break;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering case KDBUS_ITEM_TIMESTAMP:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->seqnum = d->timestamp.seqnum;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek case KDBUS_ITEM_PID_COMM:
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->creds.comm = d->str;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau case KDBUS_ITEM_TID_COMM:
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau m->creds.tid_comm = d->str;
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau break;
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau case KDBUS_ITEM_EXE:
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau m->creds.exe = d->str;
301f4073fe1c2757e602aef24cee9ccf5f81a3a3Michael Marineau m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_CMDLINE:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.cmdline = d->str;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.cmdline_size = l;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_CGROUP:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.cgroup = d->str;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek 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;
d59be2cf702dd29d0bb228013cef801f2e9dd22fZbigniew Jędrzejewski-Szmek
d59be2cf702dd29d0bb228013cef801f2e9dd22fZbigniew Jędrzejewski-Szmek r = bus_get_root_path(bus);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.cgroup_root = bus->cgroup_root;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
d59be2cf702dd29d0bb228013cef801f2e9dd22fZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_AUDIT:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
1adc5d0bcd17fc8a8cd22fcd03174bfd75306dcdSusant Sahani m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
1adc5d0bcd17fc8a8cd22fcd03174bfd75306dcdSusant Sahani }
1adc5d0bcd17fc8a8cd22fcd03174bfd75306dcdSusant Sahani
d59be2cf702dd29d0bb228013cef801f2e9dd22fZbigniew Jędrzejewski-Szmek if ((uid_t) d->audit.loginuid != (uid_t) -1) {
d59be2cf702dd29d0bb228013cef801f2e9dd22fZbigniew Jędrzejewski-Szmek m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
1adc5d0bcd17fc8a8cd22fcd03174bfd75306dcdSusant Sahani m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
1adc5d0bcd17fc8a8cd22fcd03174bfd75306dcdSusant Sahani }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_CAPS:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.capability = (uint8_t *) d->caps.caps;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps);
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek 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;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek break;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek case KDBUS_ITEM_DST_NAME:
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek if (!service_name_is_valid(d->str)) {
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek r = -EBADMSG;
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek destination = d->str;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_OWNED_NAME:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!service_name_is_valid(d->name.name)) {
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt r = -EBADMSG;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering r = strv_extend(&m->creds.well_known_names, d->name.name);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (r < 0)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering goto fail;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_CONN_DESCRIPTION:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.description = d->str;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_AUXGROUPS:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek size_t i, n;
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen uid_t *u;
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen u = new(uid_t, n);
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen if (!u) {
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen r = -ENOMEM;
4a6970c5354cd367b1fa62114057d8e084a20403Torstein Husebø goto fail;
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen }
3e43b2cd97bd82efe6a09e8b9b2e6b5f33f578a0Jan Janssen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < n; i++)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek u[i] = (uid_t) d->data64[i];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.supplementary_gids = u;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.n_supplementary_gids = n;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_FDS:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek case KDBUS_ITEM_SECLABEL:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek break;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek default:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_debug("Got unknown field from kernel %llu", d->type);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = bus_message_parse_fields(m);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto fail;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Override information from the user header with data from the kernel */
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (k->src_id == KDBUS_SRC_ID_KERNEL)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->sender = m->creds.unique_name = m->sender_buffer;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (destination)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->destination = destination;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m->destination = NULL;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering else if (k->dst_id == KDBUS_DST_ID_NAME)
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen else {
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen m->destination = m->destination_buffer;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen }
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen /* We take possession of the kmsg struct now */
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen m->kdbus = k;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen m->release_kdbus = true;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen m->free_fds = true;
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt fds = NULL;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen bus->rqueue[bus->rqueue_size++] = m;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen return 1;
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersen
9b3a67c55b7df6642a0389306c513b17c211f280Tom Gundersenfail:
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering unset_memfds(m);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sd_bus_message_unref(m);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return r;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering}
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poetteringint bus_kernel_take_fd(sd_bus *b) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering struct kdbus_cmd_hello *hello;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering struct kdbus_item *item;
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt _cleanup_free_ char *g = NULL;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering const char *name;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering size_t l = 0, m = 0, sz;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering int r;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering assert(b);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (b->is_server)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return -EINVAL;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering b->use_memfd = 1;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (b->description) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering g = bus_label_escape(b->description);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (!g)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return -ENOMEM;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering name = g;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering } else {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering char pr[17] = {};
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering /* If no name is explicitly set, we'll include a hint
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering * indicating the library implementation, a hint which
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering * kind of bus this is and the thread name */
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (isempty(pr)) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering name = b->is_system ? "sd-system" :
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt b->is_user ? "sd-user" : "sd";
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering } else {
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt _cleanup_free_ char *e = NULL;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering e = bus_label_escape(pr);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (!e)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return -ENOMEM;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering g = strappend(b->is_system ? "sd-system-" :
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering b->is_user ? "sd-user-" : "sd-",
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering e);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (!g)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return -ENOMEM;
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering name = g;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering b->description = bus_label_unescape(name);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (!b->description)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering return -ENOMEM;
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering m = strlen(name);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (b->fake_creds_valid)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (b->fake_pids_valid)
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
b938cb902c3b5bca807a94b277672c64d6767886Jan Engelhardt
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering if (b->fake_label) {
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering l = strlen(b->fake_label);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering }
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering hello = alloca0_align(sz, 8);
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering hello->size = sz;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek hello->flags = b->hello_flags;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek hello->attach_flags_send = _KDBUS_ATTACH_ANY;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek hello->attach_flags_recv = b->attach_flags;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek hello->pool_size = KDBUS_POOL_SIZE;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item = hello->items;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->size = offsetof(struct kdbus_item, str) + m + 1;
072f9e4af4cf465aca6e263f4dfd6e07786786d2Zbigniew Jędrzejewski-Szmek item->type = KDBUS_ITEM_CONN_DESCRIPTION;
072f9e4af4cf465aca6e263f4dfd6e07786786d2Zbigniew Jędrzejewski-Szmek memcpy(item->str, name, m + 1);
072f9e4af4cf465aca6e263f4dfd6e07786786d2Zbigniew Jędrzejewski-Szmek item = KDBUS_ITEM_NEXT(item);
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani if (b->fake_creds_valid) {
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->type = KDBUS_ITEM_CREDS;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->creds = b->fake_creds;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek item = KDBUS_ITEM_NEXT(item);
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek }
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek if (b->fake_pids_valid) {
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->type = KDBUS_ITEM_PIDS;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->pids = b->fake_pids;
84c3409631f48869dcb59c0a74eba6d4ac40ad93Zbigniew Jędrzejewski-Szmek
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item = KDBUS_ITEM_NEXT(item);
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek }
84c3409631f48869dcb59c0a74eba6d4ac40ad93Zbigniew Jędrzejewski-Szmek
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani if (b->fake_label) {
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->size = offsetof(struct kdbus_item, str) + l + 1;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani item->type = KDBUS_ITEM_SECLABEL;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani memcpy(item->str, b->fake_label, l+1);
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani }
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek if (r < 0)
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani return -errno;
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani if (!b->kdbus_buffer) {
23da66bb402cc6d9bca2eb34e090ccc24dfbf3f5Zbigniew Jędrzejewski-Szmek b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani if (b->kdbus_buffer == MAP_FAILED) {
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek b->kdbus_buffer = NULL;
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek return -errno;
23da66bb402cc6d9bca2eb34e090ccc24dfbf3f5Zbigniew Jędrzejewski-Szmek }
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani }
165c41a99ab6002ef3ba6bd1f9361abf32c077f2Susant Sahani
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The higher 32bit of the bus_flags fields are considered
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * 'incompatible flags'. Refuse them all for now. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (hello->bus_flags > 0xFFFFFFFFULL)
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek return -ENOTSUP;
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
47c7dfe275b30cb507108f08e471d2d9ef2baa56Zbigniew Jędrzejewski-Szmek return -ENOTSUP;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->bloom_size = (size_t) hello->bloom.size;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return -ENOMEM;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->unique_id = hello->id;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->is_kernel = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->bus_client = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->message_version = 2;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->message_endian = BUS_NATIVE_ENDIAN;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* the kernel told us the UUID of the underlying bus */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return bus_start_running(b);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint bus_kernel_connect(sd_bus *b) {
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt assert(b);
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt assert(b->input_fd < 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(b->output_fd < 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(b->kernel);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (b->is_server)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return -EINVAL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (b->input_fd < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return -errno;
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek b->output_fd = b->input_fd;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen return bus_kernel_take_fd(b);
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen}
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersenstatic void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen struct kdbus_cmd_free cmd = {};
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct kdbus_item *d;
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(bus);
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen assert(k);
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen KDBUS_ITEM_FOREACH(d, k, items) {
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
9c8ca3f7a69f82ca181b3cd2d5e1d3e621938abbZbigniew Jędrzejewski-Szmek if (d->type == KDBUS_ITEM_FDS)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek safe_close(d->memfd.fd);
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering }
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma}
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpomaint bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) {
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma int r;
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma assert(bus);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(m);
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma assert(bus->state == BUS_RUNNING);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering /* If we can't deliver, we want room for the error message */
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma r = bus_rqueue_make_room(bus);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma return r;
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma r = bus_message_setup_kmsg(bus, m);
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering /* If this is a synchronous method call, then let's tell the
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen * kernel, so that it can pass CPU time/scheduling to the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * destination for the time, if it wants to. If we
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen * synchronously wait for the result anyway, we won't need CPU
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen * anyway. */
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen if (hint_sync_call)
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen m->kdbus->flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY|KDBUS_MSG_FLAGS_SYNC_REPLY;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen r = ioctl(bus->output_fd, KDBUS_CMD_MSG_SEND, m->kdbus);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0) {
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen sd_bus_message *reply;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen if (errno == EAGAIN || errno == EINTR)
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen return 0;
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen else if (errno == ENXIO || errno == ESRCH) {
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* ENXIO: unique name not known
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen * ESRCH: well-known name not known */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen return 0;
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen }
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (errno == EADDRNOTAVAIL) {
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* EADDRNOTAVAIL: activation is possible, but turned off in request flags */
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen else {
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen return 0;
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden return -errno;
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden
6c1695be47b2830c79e128e4d05d760eb862184eLennart Poettering r = bus_message_new_synthetic_error(
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden bus,
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden BUS_MESSAGE_COOKIE(m),
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden &error,
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden &reply);
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden if (r < 0)
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden return r;
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden
d94facdcaa8053768a2d190ee8dd6ff5114f8b33Major Hayden r = bus_seal_synthetic_message(bus, reply);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (r < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return r;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bus->rqueue[bus->rqueue_size++] = reply;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (hint_sync_call) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek struct kdbus_msg *k;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + m->kdbus->offset_reply);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert(k);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen
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("Ignoring invalid message: %s", strerror(-r));
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) {
_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;
m->sender = "org.freedesktop.DBus";
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, struct kdbus_msg *k, struct kdbus_item *d) {
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);
}
static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
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);
}
static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) {
_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;
m->sender = "org.freedesktop.DBus";
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) {
struct kdbus_item *d, *found = NULL;
static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = {
[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,
};
assert(bus);
assert(k);
assert(k->payload_type == KDBUS_PAYLOAD_KERNEL);
KDBUS_ITEM_FOREACH(d, k, items) {
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);
}
int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
struct kdbus_cmd_recv 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_MSG_RECV, &recv);
if (r < 0) {
if (errno == EAGAIN)
return 0;
if (errno == EOVERFLOW) {
log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
return 0;
}
return -errno;
}
k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + recv.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("Ignoring invalid message: %s", strerror(-r));
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_PID_STARTTIME|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 *make;
struct kdbus_item *n;
int fd;
assert(name);
assert(s);
fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
offsetof(struct kdbus_item, str) +
DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
8);
make->size = offsetof(struct kdbus_cmd_make, items);
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);
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;
}
static int bus_kernel_translate_access(BusPolicyAccess access) {
assert(access >= 0);
assert(access < _BUS_POLICY_ACCESS_MAX);
switch (access) {
case BUS_POLICY_ACCESS_SEE:
return KDBUS_POLICY_SEE;
case BUS_POLICY_ACCESS_TALK:
return KDBUS_POLICY_TALK;
case BUS_POLICY_ACCESS_OWN:
return KDBUS_POLICY_OWN;
default:
assert_not_reached("Unknown policy access");
}
}
static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
int r;
assert(policy);
assert(item);
switch (policy->type) {
case BUSNAME_POLICY_TYPE_USER: {
const char *user = policy->name;
uid_t uid;
r = get_user_creds(&user, &uid, NULL, NULL, NULL);
if (r < 0)
return r;
item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
item->policy_access.id = uid;
break;
}
case BUSNAME_POLICY_TYPE_GROUP: {
const char *group = policy->name;
gid_t gid;
r = get_group_creds(&group, &gid);
if (r < 0)
return r;
item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
item->policy_access.id = gid;
break;
}
default:
assert_not_reached("Unknown policy type");
}
item->policy_access.access = bus_kernel_translate_access(policy->access);
return 0;
}
int bus_kernel_open_bus_fd(const char *bus, char **path) {
char *p;
int fd;
size_t len;
len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
if (path) {
p = malloc(len);
if (!p)
return -ENOMEM;
*path = p;
} else
p = alloca(len);
sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
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 *make;
struct kdbus_item *n;
size_t size;
int fd;
fd = bus_kernel_open_bus_fd(bus_name, &path);
if (fd < 0)
return fd;
size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
make = alloca0_align(size, 8);
make->size = size;
make->flags = KDBUS_MAKE_ACCESS_WORLD;
n = make->items;
n->type = KDBUS_ITEM_MAKE_NAME;
n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1;
strcpy(n->str, ep_name);
if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
safe_close(fd);
return -errno;
}
if (ep_path) {
char *p;
p = strjoin(dirname(path), "/", ep_name, NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
}
*ep_path = p;
}
return fd;
}
int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
struct kdbus_cmd_update *update;
struct kdbus_item *n;
BusEndpointPolicy *po;
Iterator i;
size_t size;
int r;
size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
HASHMAP_FOREACH(po, ep->policy_hash, i) {
size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
}
update = alloca0_align(size, 8);
update->size = size;
n = update->items;
HASHMAP_FOREACH(po, ep->policy_hash, i) {
n->type = KDBUS_ITEM_NAME;
n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
strcpy(n->str, po->name);
n = KDBUS_ITEM_NEXT(n);
n->type = KDBUS_ITEM_POLICY_ACCESS;
n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
n->policy_access.access = bus_kernel_translate_access(po->access);
n->policy_access.id = uid;
n = KDBUS_ITEM_NEXT(n);
}
r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
if (r < 0)
return -errno;
return 0;
}
int bus_kernel_make_starter(
int fd,
const char *name,
bool activating,
bool accept_fd,
BusNamePolicy *policy,
BusPolicyAccess world_policy) {
struct kdbus_cmd_hello *hello;
struct kdbus_item *n;
size_t policy_cnt = 0;
BusNamePolicy *po;
size_t size;
int r;
assert(fd >= 0);
assert(name);
LIST_FOREACH(policy, po, policy)
policy_cnt++;
if (world_policy >= 0)
policy_cnt++;
size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
hello = alloca0_align(size, 8);
n = hello->items;
strcpy(n->str, name);
n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
n->type = KDBUS_ITEM_NAME;
n = KDBUS_ITEM_NEXT(n);
LIST_FOREACH(policy, po, policy) {
n->type = KDBUS_ITEM_POLICY_ACCESS;
n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
r = bus_kernel_translate_policy(po, n);
if (r < 0)
return r;
n = KDBUS_ITEM_NEXT(n);
}
if (world_policy >= 0) {
n->type = KDBUS_ITEM_POLICY_ACCESS;
n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
n->policy_access.access = bus_kernel_translate_access(world_policy);
}
hello->size = size;
hello->flags =
(activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
(accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
hello->pool_size = KDBUS_POOL_SIZE;
hello->attach_flags_send = _KDBUS_ATTACH_ANY;
hello->attach_flags_recv = _KDBUS_ATTACH_ALL;
if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
return -errno;
/* The higher 32bit of the bus_flags fields are considered
* 'incompatible flags'. Refuse them all for now. */
if (hello->bus_flags > 0xFFFFFFFFULL)
return -ENOTSUP;
if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
return -ENOTSUP;
return fd;
}
int bus_kernel_try_close(sd_bus *bus) {
assert(bus);
assert(bus->is_kernel);
if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
return -errno;
return 0;
}
int bus_kernel_drop_one(int fd) {
struct kdbus_cmd_recv recv = {
.flags = KDBUS_RECV_DROP
};
assert(fd >= 0);
if (ioctl(fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
return -errno;
return 0;
}
int bus_kernel_realize_attach_flags(sd_bus *bus) {
struct kdbus_cmd_update *update;
struct kdbus_item *n;
assert(bus);
assert(bus->is_kernel);
update = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_update, items) +
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_update, items) + n->size;
if (ioctl(bus->input_fd, KDBUS_CMD_CONN_UPDATE, update) < 0)
return -errno;
return 0;
}