summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c53
-rw-r--r--src/libsystemd/sd-bus/bus-message.c1
-rw-r--r--src/libsystemd/sd-bus/kdbus.h21
3 files changed, 62 insertions, 13 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 2978b0a284..112292735b 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -815,7 +815,9 @@ fail:
}
int bus_kernel_take_fd(sd_bus *b) {
+ struct kdbus_bloom_parameter *bloom = NULL;
struct kdbus_cmd_hello *hello;
+ struct kdbus_item_list *items;
struct kdbus_item *item;
_cleanup_free_ char *g = NULL;
const char *name;
@@ -928,23 +930,40 @@ int bus_kernel_take_fd(sd_bus *b) {
b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
if (b->kdbus_buffer == MAP_FAILED) {
b->kdbus_buffer = NULL;
- return -errno;
+ r = -errno;
+ goto fail;
}
}
/* 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 (hello->bus_flags > 0xFFFFFFFFULL) {
+ r = -ENOTSUP;
+ goto fail;
+ }
- if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
- return -ENOTSUP;
+ /* extract bloom parameters from items */
+ items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset);
+ KDBUS_ITEM_FOREACH(item, items, items) {
+ switch (item->type) {
+ case KDBUS_ITEM_BLOOM_PARAMETER:
+ bloom = &item->bloom_parameter;
+ break;
+ }
+ }
- b->bloom_size = (size_t) hello->bloom.size;
- b->bloom_n_hash = (unsigned) hello->bloom.n_hash;
+ if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) {
+ r = -ENOTSUP;
+ goto fail;
+ }
- if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
- return -ENOMEM;
+ b->bloom_size = (size_t) bloom->size;
+ b->bloom_n_hash = (unsigned) bloom->n_hash;
+
+ if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
b->unique_id = hello->id;
@@ -957,7 +976,14 @@ int bus_kernel_take_fd(sd_bus *b) {
/* the kernel told us the UUID of the underlying bus */
memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
+ /* free returned items */
+ (void) bus_kernel_cmd_free(b, hello->offset);
+
return bus_start_running(b);
+
+fail:
+ (void) bus_kernel_cmd_free(b, hello->offset);
+ return r;
}
int bus_kernel_connect(sd_bus *b) {
@@ -980,6 +1006,7 @@ int bus_kernel_connect(sd_bus *b) {
int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) {
struct kdbus_cmd_free cmd = {
+ .size = sizeof(cmd),
.flags = 0,
.offset = offset,
};
@@ -1724,6 +1751,7 @@ int bus_kernel_make_starter(
BusNamePolicy *policy,
BusPolicyAccess world_policy) {
+ struct kdbus_cmd_free cmd_free = { .size = sizeof(cmd_free) };
struct kdbus_cmd_hello *hello;
struct kdbus_item *n;
size_t policy_cnt = 0;
@@ -1781,14 +1809,15 @@ int bus_kernel_make_starter(
if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
return -errno;
+ /* not interested in any output values */
+ cmd_free.offset = hello->offset;
+ (void) ioctl(fd, KDBUS_CMD_FREE, &cmd_free);
+
/* 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;
}
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 3134029337..0f9334bb84 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -132,6 +132,7 @@ static void message_free(sd_bus_message *m) {
if (m->release_kdbus) {
struct kdbus_cmd_free cmd_free = { };
+ cmd_free.size = sizeof(cmd_free);
cmd_free.flags = 0;
cmd_free.offset = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
(void) ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &cmd_free);
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index bd51e37593..201f21dd13 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -384,6 +384,16 @@ struct kdbus_item {
};
/**
+ * struct kdbus_item_list - A list of items
+ * @size: The total size of the structure
+ * @items: Array of items
+ */
+struct kdbus_item_list {
+ __u64 size;
+ struct kdbus_item items[0];
+};
+
+/**
* enum kdbus_msg_flags - type of message
* @KDBUS_MSG_EXPECT_REPLY: Expect a reply message, used for
* method calls. The userspace-supplied
@@ -576,19 +586,23 @@ struct kdbus_cmd_cancel {
/**
* struct kdbus_cmd_free - struct to free a slice of memory in the pool
+ * @size: Overall size of this structure
* @offset: The offset of the memory slice, as returned by other
* ioctls
* @flags: Flags for the free command, userspace → kernel
* @return_flags: Command return flags, kernel → userspace
* @kernel_flags: Supported flags of the free command, userspace → kernel
+ * @items: Additional items to modify the behavior
*
* This struct is used with the KDBUS_CMD_FREE ioctl.
*/
struct kdbus_cmd_free {
+ __u64 size;
__u64 offset;
__u64 flags;
__u64 kernel_flags;
__u64 return_flags;
+ struct kdbus_item items[0];
} __attribute__((aligned(8)));
/**
@@ -701,6 +715,10 @@ enum kdbus_attach_flags {
* @id: The ID of this connection (kernel → userspace)
* @pool_size: Size of the connection's buffer where the received
* messages are placed
+ * @offset: Pool offset where additional items of type
+ * kdbus_item_list are stored. They contain information
+ * about the bus and the newly created connection.
+ * @items_size: Copy of item_list.size stored in @offset.
* @bloom: The bloom properties of the bus, specified
* by the bus creator (kernel → userspace)
* @id128: Unique 128-bit ID of the bus (kernel → userspace)
@@ -718,7 +736,8 @@ struct kdbus_cmd_hello {
__u64 bus_flags;
__u64 id;
__u64 pool_size;
- struct kdbus_bloom_parameter bloom;
+ __u64 offset;
+ __u64 items_size;
__u8 id128[16];
struct kdbus_item items[0];
} __attribute__((aligned(8)));