static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
struct bus_body_part *part;
struct kdbus_item *d;
+ const char *destination;
bool well_known;
uint64_t unique;
size_t sz, dl;
if (m->kdbus)
return 0;
- if (m->destination) {
- r = bus_kernel_parse_unique_name(m->destination, &unique);
+ destination = m->destination ?: m->destination_ptr;
+
+ if (destination) {
+ r = bus_kernel_parse_unique_name(destination, &unique);
if (r < 0)
return r;
/* Add in well-known destination header */
if (well_known) {
- dl = strlen(m->destination);
+ dl = strlen(destination);
sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
}
m->kdbus->flags =
((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
- m->kdbus->dst_id =
- well_known ? 0 :
- m->destination ? unique : KDBUS_DST_ID_BROADCAST;
+
+ if (well_known) {
+ /* verify_destination_id will usually be 0, which makes the kernel driver only look
+ * at the provided well-known name. Otherwise, the kernel will make sure the provided
+ * destination id matches the owner of the provided weel-known-name, and fail if they
+ * differ. Currently, this is only needed for bus-proxyd. */
+ m->kdbus->dst_id = m->verify_destination_id;
+ } else {
+ m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
+ }
+
m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
m->kdbus->cookie = (uint64_t) m->header->serial;
m->kdbus->priority = m->priority;
d = m->kdbus->items;
if (well_known)
- append_destination(&d, m->destination, dl);
+ append_destination(&d, destination, dl);
append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
continue;
}
- if (part->memfd >= 0 && part->sealed && m->destination) {
+ if (part->memfd >= 0 && part->sealed && destination) {
/* Try to send a memfd, if the part is
* sealed and this is not a broadcast. Since we can only */
hello = alloca0_align(sz, 8);
hello->size = sz;
hello->flags = b->hello_flags;
- hello->attach_flags_send = _KDBUS_ATTACH_ALL;
+ hello->attach_flags_send = _KDBUS_ATTACH_ANY;
hello->attach_flags_recv = b->attach_flags;
hello->pool_size = KDBUS_POOL_SIZE;
assert(name);
assert(s);
- fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
if (s) {
char *p;
- p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
+ p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
int fd;
size_t len;
- len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
+ len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
if (path) {
p = malloc(len);
*path = p;
} else
p = alloca(len);
- sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
+ sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
(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_ALL;
+ hello->attach_flags_send = _KDBUS_ATTACH_ANY;
hello->attach_flags_recv = _KDBUS_ATTACH_ALL;
if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
return fd;
}
-int bus_kernel_create_domain(const char *name, char **s) {
- struct kdbus_cmd_make *make;
- struct kdbus_item *n;
- int fd;
-
- assert(name);
- assert(s);
-
- fd = open("/dev/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, str) +
- strlen(name) + 1),
- 8);
-
- n = make->items;
- strcpy(n->str, name);
- n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
- n->type = KDBUS_ITEM_MAKE_NAME;
-
- make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
- make->flags = KDBUS_MAKE_ACCESS_WORLD;
-
- if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
- safe_close(fd);
- return -errno;
- }
-
- /* The higher 32bit of the flags field are considered
- * 'incompatible flags'. Refuse them all for now. */
- if (make->flags > 0xFFFFFFFFULL) {
- safe_close(fd);
- return -ENOTSUP;
- }
-
- if (s) {
- char *p;
-
- p = strappend("/dev/kdbus/domain/", name);
- if (!p) {
- safe_close(fd);
- return -ENOMEM;
- }
-
- *s = p;
- }
-
- return fd;
-}
-
int bus_kernel_try_close(sd_bus *bus) {
assert(bus);
assert(bus->is_kernel);