#include "bus-control.h"
#include "bus-bloom.h"
#include "bus-util.h"
+#include "capability.h"
#include "cgroup-util.h"
_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
}
static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
- struct kdbus_cmd_name *n;
+ struct kdbus_cmd *n;
size_t size, l;
int r;
assert(name);
l = strlen(name) + 1;
- size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
+ size = offsetof(struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(l);
n = alloca0_align(size, 8);
n->size = size;
n->flags = request_name_flags_to_kdbus(flags);
assert_return(service_name_is_valid(name), -EINVAL);
assert_return(name[0] != ':', -EINVAL);
+ /* Don't allow requesting the special driver and local names */
+ if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
+ return -EINVAL;
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
}
static int bus_release_name_kernel(sd_bus *bus, const char *name) {
- struct kdbus_cmd_name *n;
+ struct kdbus_cmd *n;
size_t size, l;
int r;
assert(name);
l = strlen(name) + 1;
- size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
+ size = offsetof(struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(l);
n = alloca0_align(size, 8);
n->size = size;
assert_return(service_name_is_valid(name), -EINVAL);
assert_return(name[0] != ':', -EINVAL);
+ /* Don't allow releasing the special driver and local names */
+ if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
+ return -EINVAL;
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
}
static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
- struct kdbus_cmd_name_list cmd = {};
- struct kdbus_name_list *name_list;
- struct kdbus_name_info *name;
+ struct kdbus_cmd_list cmd = {};
+ struct kdbus_info *name_list, *name;
uint64_t previous_id = 0;
int r;
/* Caller will free half-constructed list on failure... */
+ cmd.size = sizeof(cmd);
cmd.flags = flags;
- r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
+ r = ioctl(bus->input_fd, KDBUS_CMD_LIST, &cmd);
if (r < 0)
return -errno;
- name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
+ name_list = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
- KDBUS_ITEM_FOREACH(name, name_list, names) {
+ KDBUS_FOREACH(name, name_list, cmd.list_size) {
struct kdbus_item *item;
const char *entry_name = NULL;
- if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
+ if ((flags & KDBUS_LIST_UNIQUE) && name->id != previous_id) {
char *n;
- if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
+ if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
r = -ENOMEM;
goto fail;
}
if (r < 0)
goto fail;
- previous_id = name->owner_id;
+ previous_id = name->id;
}
KDBUS_ITEM_FOREACH(item, name, items)
int r;
if (acquired) {
- r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
+ r = kernel_get_list(bus, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES, &x);
if (r < 0)
return r;
}
if (activatable) {
- r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
+ r = kernel_get_list(bus, KDBUS_LIST_ACTIVATORS, &y);
if (r < 0)
return r;
c->mask |= SD_BUS_CREDS_TID;
}
- if (mask & SD_BUS_CREDS_PID_STARTTIME && item->pids.starttime > 0) {
- c->pid_starttime = item->pids.starttime;
- c->mask |= SD_BUS_CREDS_PID_STARTTIME;
- }
-
break;
case KDBUS_ITEM_CREDS:
SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
if (m) {
- c->capability_size = item->size - offsetof(struct kdbus_item, caps.caps);
- c->capability = memdup(item->caps.caps, c->capability_size);
+ if (item->caps.last_cap != cap_last_cap() ||
+ item->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(item->caps.last_cap, 32U) * 4 * 4)
+ return -EBADMSG;
+
+ c->capability = memdup(item->caps.caps, item->size - offsetof(struct kdbus_item, caps.caps));
if (!c->capability)
return -ENOMEM;
uint64_t id;
int r;
+ if (streq(name, "org.freedesktop.DBus"))
+ return -ENOTSUP;
+
r = bus_kernel_parse_unique_name(name, &id);
if (r < 0)
return r;
memcpy(cmd->items[0].str, name, l);
}
- cmd->size = size;
- cmd->flags = attach_flags_to_kdbus(mask);
-
- /* If augmentation is on, and the bus doesn't didn't allow us
- * to get the bits we want, then ask for the PID/TID so that we
+ /* If augmentation is on, and the bus didn't provide us
+ * the bits we want, then ask for the PID/TID so that we
* can read the rest from /proc. */
if ((mask & SD_BUS_CREDS_AUGMENT) &&
(mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
SD_BUS_CREDS_SELINUX_CONTEXT|
SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
- cmd->flags |= KDBUS_ATTACH_PIDS;
+ mask |= SD_BUS_CREDS_PID;
+
+ cmd->size = size;
+ cmd->flags = attach_flags_to_kdbus(mask);
r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
if (r < 0)
if ((mask & SD_BUS_CREDS_PID) ||
((mask & SD_BUS_CREDS_AUGMENT) &&
- (mask & (SD_BUS_CREDS_PID_STARTTIME|
- SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+ (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
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|
reply = sd_bus_message_unref(reply);
}
- if (mask & SD_BUS_CREDS_UID) {
+ if (mask & SD_BUS_CREDS_EUID) {
uint32_t u;
r = sd_bus_call_method(
if (r < 0)
return r;
- c->uid = u;
- c->mask |= SD_BUS_CREDS_UID;
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
reply = sd_bus_message_unref(reply);
}
assert_return(service_name_is_valid(name), -EINVAL);
assert_return(bus->bus_client, -ENODATA);
+ if (streq(name, "org.freedesktop.DBus.Local"))
+ return -EINVAL;
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
if (!c)
return -ENOMEM;
- cmd.flags = attach_flags_to_kdbus(mask);
-
/* If augmentation is on, and the bus doesn't didn't allow us
* to get the bits we want, then ask for the PID/TID so that we
* can read the rest from /proc. */
SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
SD_BUS_CREDS_SELINUX_CONTEXT|
SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
- cmd.flags |= KDBUS_ATTACH_PIDS;
+ mask |= SD_BUS_CREDS_PID;
+
+ cmd.flags = attach_flags_to_kdbus(mask);
r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
if (r < 0)
}
if (bus->ucred.uid != UID_INVALID) {
- c->uid = bus->ucred.uid;
- c->mask |= SD_BUS_CREDS_UID & mask;
+ c->euid = bus->ucred.uid;
+ c->mask |= SD_BUS_CREDS_EUID & mask;
}
if (bus->ucred.gid != GID_INVALID) {
- c->gid = bus->ucred.gid;
- c->mask |= SD_BUS_CREDS_GID & mask;
+ c->egid = bus->ucred.gid;
+ c->mask |= SD_BUS_CREDS_EGID & mask;
}
}
assert(bus);
+ /* Monitor streams don't support matches, make this a NOP */
+ if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+ return 0;
+
bloom = alloca0(bus->bloom_size);
sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
if (c->type - BUS_MATCH_ARG < 3)
name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
- snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
+ xsprintf(buf, "arg%i", c->type - BUS_MATCH_ARG);
bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
using_bloom = true;
break;
case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
- snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
+ xsprintf(buf, "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
using_bloom = true;
break;
case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
- snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
+ xsprintf(buf, "arg%i-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
using_bloom = true;
break;
#define internal_match(bus, m) \
((bus)->hello_flags & KDBUS_HELLO_MONITOR \
- ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
+ ? (isempty(m) ? "eavesdrop='true'" : strjoina((m), ",eavesdrop='true'")) \
: (m))
static int bus_add_match_internal_dbus1(
assert(bus);
+ /* Monitor streams don't support matches, make this a NOP */
+ if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+ return 0;
+
zero(m);
m.size = offsetof(struct kdbus_cmd_match, items);
m.cookie = cookie;