bus-kernel.c revision d663f1b1a92a778bcdc68f29b8c08cb49431b4f7
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh This file is part of systemd.
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh Copyright 2013 Lennart Poettering
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh systemd is free software; you can redistribute it and/or modify it
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh under the terms of the GNU Lesser General Public License as published by
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh the Free Software Foundation; either version 2.1 of the License, or
03e22642617f360a6b55cb853bcf59604754ea5dKay Sievers (at your option) any later version.
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh systemd is distributed in the hope that it will be useful, but
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh WITHOUT ANY WARRANTY; without even the implied warranty of
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh Lesser General Public License for more details.
03e22642617f360a6b55cb853bcf59604754ea5dKay Sievers You should have received a copy of the GNU Lesser General Public License
e2417e4143bb892e4599b01de7b031763421bb64Daniel J Walsh along with systemd; If not, see <http://www.gnu.org/licenses/>.
8a188de9e0ea41509beda12084126d7a75ebe86eWaLyong Cho#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
cad45ba11ec3572296361f53f5852ffb97a97fa3Lennart Poetteringint bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
assert(d);
*d = ALIGN8_PTR(*d);
assert(d);
*d = ALIGN8_PTR(*d);
assert(d);
assert(s);
*d = ALIGN8_PTR(*d);
struct kdbus_item *i;
assert(d);
i = ALIGN8_PTR(*d);
return &i->bloom_filter;
assert(d);
*d = ALIGN8_PTR(*d);
void *data;
assert(m);
bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, "message-type", bus_message_type_to_string(m->header->type));
if (m->interface)
if (m->member)
if (m->path) {
bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, "path-slash-prefix", m->path, '/');
r = sd_bus_message_rewind(m, true);
char type;
struct kdbus_item *d;
bool well_known;
assert(b);
assert(m);
if (m->kdbus)
if (m->destination) {
well_known = r == 0;
well_known = false;
if (well_known) {
if (m->n_fds > 0)
if (!m->kdbus) {
r = -ENOMEM;
goto fail;
m->free_kdbus = true;
well_known ? 0 :
if (well_known)
goto fail;
goto fail;
if (m->n_fds > 0)
fail:
m->poisoned = true;
assert(m);
struct kdbus_item *d;
unsigned n_fds = 0;
assert(k);
size_t l;
switch (d->type) {
case KDBUS_ITEM_PAYLOAD_OFF:
return -EBADMSG;
case KDBUS_ITEM_PAYLOAD_MEMFD:
return -EBADMSG;
case KDBUS_ITEM_FDS: {
return -ENOMEM;
fds = f;
n_fds += j;
case KDBUS_ITEM_SECLABEL:
return -EBADMSG;
return -EBADMSG;
return -EPROTOTYPE;
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_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:
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:
return -EBADMSG;
case KDBUS_ITEM_NAME:
return -EBADMSG;
goto fail;
case KDBUS_ITEM_CONN_NAME:
case KDBUS_ITEM_FDS:
case KDBUS_ITEM_SECLABEL:
r = bus_message_parse_fields(m);
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->connection_name) {
return -ENOMEM;
name = g;
return -ENOMEM;
return -ENOMEM;
name = g;
if (!b->connection_name)
return -ENOMEM;
if (b->fake_creds_valid)
if (b->fake_label) {
if (b->fake_creds_valid) {
if (b->fake_label) {
return -errno;
if (!b->kdbus_buffer) {
return -errno;
return -ENOTSUP;
return -ENOTSUP;
return -ENOMEM;
b->is_kernel = true;
b->bus_client = true;
return bus_start_running(b);
assert(b);
if (b->is_server)
return -EINVAL;
if (b->input_fd < 0)
return -errno;
return bus_kernel_take_fd(b);
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(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) {
bus,
"/org/freedesktop/DBus",
m = NULL;
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;
assert(k);
assert(d);
return push_name_owner_changed(
assert(k);
assert(d);
bus,
k->cookie_reply,
m = NULL;
assert(k);
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) {
return -errno;
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
struct memfd_cache *c;
int fd;
return -ENOTSUP;
return -ENOMEM;
return -errno;
*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;
*kdbus_flags = f;
uint64_t m = 0;
if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
m |= KDBUS_ATTACH_CREDS;
m |= KDBUS_ATTACH_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_CONN_NAME;
*kdbus_mask = m;
struct kdbus_item *n;
int fd;
assert(s);
if (fd < 0)
return -errno;
sizeof(struct kdbus_bloom_parameter);
n = KDBUS_ITEM_NEXT(n);
return -errno;
return -ENOTSUP;
return -ENOMEM;
return fd;
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;
case BUSNAME_POLICY_TYPE_USER: {
case BUSNAME_POLICY_TYPE_GROUP: {
int fd;
if (path) {
return -ENOMEM;
*path = p;
if (fd < 0)
return -errno;
return fd;
struct kdbus_item *n;
int fd;
if (fd < 0)
return fd;
return -errno;
return -ENOTSUP;
if (ep_path) {
return -ENOMEM;
*ep_path = p;
return fd;
struct kdbus_item *n;
Iterator i;
n = KDBUS_ITEM_NEXT(n);
n = KDBUS_ITEM_NEXT(n);
return -errno;
int fd,
const char *name,
bool activating,
bool accept_fd,
struct kdbus_item *n;
policy_cnt++;
if (world_policy >= 0)
policy_cnt++;
policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
n = KDBUS_ITEM_NEXT(n);
n = KDBUS_ITEM_NEXT(n);
if (world_policy >= 0) {
return -errno;
return -ENOTSUP;
return -ENOTSUP;
return fd;
struct kdbus_item *n;
int fd;
assert(s);
if (fd < 0)
return -errno;
return -errno;
return -ENOTSUP;
return -ENOMEM;
return fd;
return -errno;
return -errno;