bus-kernel.c revision eccd47c5beb72211ce33c9a33a1bb36366d43e22
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering This file is part of systemd.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering Copyright 2013 Lennart Poettering
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering systemd is free software; you can redistribute it and/or modify it
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering under the terms of the GNU Lesser General Public License as published by
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering (at your option) any later version.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering systemd is distributed in the hope that it will be useful, but
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering Lesser General Public License for more details.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering You should have received a copy of the GNU Lesser General Public License
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering/* When we include libgen.h because we need dirname() we immediately
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * undefine basename() since libgen.h defines it as a macro to the POSIX
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * version which is really broken. We prefer GNU basename(). */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringint bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* Note that p can be NULL, which encodes a region full of
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * zeroes, which is useful to optimize certain padding
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * conditions */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic void append_payload_memfd(struct kdbus_item **d, int memfd, size_t start, size_t sz) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void append_destination(struct kdbus_item **d, const char *s, size_t length) {
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering (*d)->size = offsetof(struct kdbus_item, str) + length + 1;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic struct kdbus_bloom_filter *append_bloom(struct kdbus_item **d, size_t length) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering i->size = offsetof(struct kdbus_item, bloom_filter) +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering offsetof(struct kdbus_bloom_filter, data) +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) i + i->size);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds;
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering memcpy((*d)->fds, fds, sizeof(int) * n_fds);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poetteringstatic void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering *(e++) = '0' + (char) i;
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering bloom_add_pair(data, size, n_hash, buf, t);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_prefixes(data, size, n_hash, buf, t, '.');
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering bloom_add_prefixes(data, size, n_hash, buf, t, '/');
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void add_bloom_arg_has(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering char buf[sizeof("arg")-1 + 2 + sizeof("has")];
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering *(e++) = '0' + (char) i;
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering bloom_add_pair(data, size, n_hash, buf, t);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "interface", m->interface);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "member", m->member);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path", m->path);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering for (i = 0; i < 64; i++) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering const char *t, *contents;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_bus_message_peek_type(m, &type, &contents);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* The bloom filter includes simple strings of any kind */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_bus_message_read_basic(m, type, &t);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* As well as array of simple strings of any kinds */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_bus_message_enter_container(m, type, contents);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering add_bloom_arg_has(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* Stop adding to bloom filter as soon as we
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * run into the first argument we cannot add
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* We put this together only once, if this message is reused
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * we reuse the earlier-built version */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering destination = m->destination ?: m->destination_ptr;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = bus_kernel_parse_unique_name(destination, &unique);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Add in fixed header, fields header and payload */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sizeof(struct kdbus_memfd)));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Add space for bloom filter */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, bloom_filter) +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering offsetof(struct kdbus_bloom_filter, data) +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Add in well-known destination header */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Add space for unix fds */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) |
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0);
90d14d2015dda79c7b465b74dd3aaf2dfc25d43cLuke Shumaker /* verify_destination_id will usually be 0, which makes the kernel driver only look
90d14d2015dda79c7b465b74dd3aaf2dfc25d43cLuke Shumaker * at the provided well-known name. Otherwise, the kernel will make sure the provided
90d14d2015dda79c7b465b74dd3aaf2dfc25d43cLuke Shumaker * destination id matches the owner of the provided weel-known-name, and fail if they
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * differ. Currently, this is only needed for bus-proxyd. */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering m->kdbus->dst_id = m->verify_destination_id;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
90d14d2015dda79c7b465b74dd3aaf2dfc25d43cLuke Shumaker if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering m->kdbus->cookie_reply = m->reply_cookie;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* If this is padding then simply send a
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * vector with a NULL data pointer which the
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * kernel will just pass through. This is the
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * most efficient way to encode zeroes */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering append_payload_vec(&d, NULL, part->size);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (part->memfd >= 0 && part->sealed && destination) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Try to send a memfd, if the part is
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * sealed and this is not a broadcast. Since we can only */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering append_payload_memfd(&d, part->memfd, part->memfd_offset, part->size);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* Otherwise, let's send a vector to the actual data.
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * For that, we need to map it first. */
d60473c7ba32f2325a13f0357b23fd8e25609650Lennart Poettering append_payload_vec(&d, part->data, part->size);
d60473c7ba32f2325a13f0357b23fd8e25609650Lennart Poettering if (m->header->type == SD_BUS_MESSAGE_SIGNAL) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering bloom = append_bloom(&d, m->bus->bloom_size);
goto fail;
if (m->n_fds > 0)
fail:
m->poisoned = true;
assert(m);
static void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) {
assert(m);
if (!ts)
struct kdbus_item *d;
unsigned n_fds = 0;
bool last_was_memfd = false;
assert(k);
size_t l;
switch (d->type) {
case KDBUS_ITEM_PAYLOAD_OFF:
if (!header) {
last_was_memfd = false;
case KDBUS_ITEM_PAYLOAD_MEMFD:
return -EBADMSG;
last_was_memfd = true;
case KDBUS_ITEM_FDS: {
return -ENOMEM;
fds = f;
n_fds += j;
case KDBUS_ITEM_SECLABEL:
return -EBADMSG;
if (!header)
return -EBADMSG;
return -EBADMSG;
return -EPROTOTYPE;
bus,
seclabel, 0, &m);
size_t l;
switch (d->type) {
case KDBUS_ITEM_PAYLOAD_OFF: {
if (!part) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_PAYLOAD_MEMFD: {
r = -EBADMSG;
goto fail;
if (!part) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_PIDS:
case KDBUS_ITEM_CREDS:
case KDBUS_ITEM_TIMESTAMP:
case KDBUS_ITEM_PID_COMM:
case KDBUS_ITEM_TID_COMM:
case KDBUS_ITEM_EXE:
case KDBUS_ITEM_CMDLINE:
case KDBUS_ITEM_CGROUP:
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;
goto fail;
case KDBUS_ITEM_AUDIT:
case KDBUS_ITEM_CAPS:
r = -EBADMSG;
goto fail;
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;
case KDBUS_ITEM_DST_NAME:
r = -EBADMSG;
goto fail;
case KDBUS_ITEM_OWNED_NAME:
r = -EBADMSG;
goto fail;
char **wkn;
size_t n;
if (!wkn) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_AUXGROUPS:
size_t i, n;
gid_t *g;
r = -ENOMEM;
goto fail;
g[i] = d->data64[i];
case KDBUS_ITEM_FDS:
case KDBUS_ITEM_SECLABEL:
case KDBUS_ITEM_BLOOM_FILTER:
r = bus_message_parse_fields(m);
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
if (destination)
snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
m->kdbus = k;
m->release_kdbus = true;
m->free_fds = true;
fail:
unset_memfds(m);
const char *name;
assert(b);
if (b->is_server)
return -EINVAL;
if (b->description) {
return -ENOMEM;
name = g;
return -ENOMEM;
return -ENOMEM;
name = g;
if (!b->description)
return -ENOMEM;
if (b->fake_creds_valid)
if (b->fake_pids_valid)
if (b->fake_label) {
if (b->fake_creds_valid) {
if (b->fake_pids_valid) {
if (b->fake_label) {
return -ESOCKTNOSUPPORT;
return -errno;
if (!b->kdbus_buffer) {
r = -errno;
goto fail;
r = -ESOCKTNOSUPPORT;
goto fail;
r = -EOPNOTSUPP;
goto fail;
r = -ENOMEM;
goto fail;
b->is_kernel = true;
b->bus_client = true;
return bus_start_running(b);
fail:
assert(b);
if (b->is_server)
return -EINVAL;
if (b->input_fd < 0)
return -errno;
return bus_kernel_take_fd(b);
return -errno;
struct kdbus_item *d;
assert(k);
assert(m);
* kernel, so that it can pass CPU time/scheduling to the
if (hint_sync_call) {
sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Destination %s not known", m->destination);
log_debug("Could not deliver message to %s as destination is not known. Ignoring.", m->destination);
sd_bus_error_setf(&error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Activation of %s not requested", m->destination);
log_debug("Could not deliver message to %s as destination is not activated. Ignoring.", m->destination);
return -errno;
bus,
&error,
&reply);
} else if (hint_sync_call) {
struct kdbus_msg *k;
assert(k);
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
static int push_name_owner_changed(
const char *name,
const char *old_owner,
const char *new_owner,
bus,
"/org/freedesktop/DBus",
m = NULL;
static int translate_name_change(
const struct kdbus_msg *k,
const struct kdbus_item *d,
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;
if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
new_owner[0] = 0;
static int translate_id_change(
const struct kdbus_msg *k,
const struct kdbus_item *d,
assert(k);
assert(d);
return push_name_owner_changed(
ts);
static int translate_reply(
const struct kdbus_msg *k,
const struct kdbus_item *d,
assert(k);
assert(d);
bus,
k->cookie_reply,
m = NULL;
static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = {
assert(k);
else if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
if (found)
return -EBADMSG;
found = d;
if (!found) {
struct kdbus_msg *k;
if (hint_priority) {
log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
return -errno;
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
struct memfd_cache *c;
int fd;
return -EOPNOTSUPP;
*mapped = 0;
*allocated = 0;
return fd;
if (size > 0)
struct memfd_cache *c;
assert(b);
for (i = 0; i < b->n_memfd_cache; i++)
uint64_t f = 0;
f |= KDBUS_NAME_QUEUE;
uint64_t m = 0;
m |= KDBUS_ATTACH_CREDS;
m |= KDBUS_ATTACH_PIDS;
m |= KDBUS_ATTACH_PID_COMM;
m |= KDBUS_ATTACH_TID_COMM;
m |= KDBUS_ATTACH_EXE;
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;
m |= KDBUS_ATTACH_SECLABEL;
m |= KDBUS_ATTACH_AUDIT;
m |= KDBUS_ATTACH_NAMES;
m |= KDBUS_ATTACH_AUXGROUPS;
struct kdbus_item *n;
size_t l;
int fd;
assert(s);
if (fd < 0)
return -errno;
sizeof(struct kdbus_bloom_parameter);
n = KDBUS_ITEM_NEXT(n);
n = KDBUS_ITEM_NEXT(n);
return -ESOCKTNOSUPPORT;
return -errno;
return -ENOMEM;
return fd;
int fd;
if (path) {
return -ENOMEM;
if (fd < 0) {
if (path)
free(p);
return -errno;
if (path)
*path = p;
return fd;
struct kdbus_item *n;
const char *name;
int fd;
if (fd < 0)
return fd;
return -errno;
if (ep_path) {
return -ENOMEM;
*ep_path = p;
return fd;
return -errno;
return -errno;
struct kdbus_item *n;
return -errno;
char *n = NULL;
return -errno;
return -EIO;
*name = n;