summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-bus')
-rw-r--r--src/libsystemd-bus/bus-internal.h5
-rw-r--r--src/libsystemd-bus/bus-kernel.c55
-rw-r--r--src/libsystemd-bus/sd-bus.c1
3 files changed, 47 insertions, 14 deletions
diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h
index 7af8c1e22d..673f30eb91 100644
--- a/src/libsystemd-bus/bus-internal.h
+++ b/src/libsystemd-bus/bus-internal.h
@@ -36,6 +36,7 @@
#include "bus-error.h"
#include "bus-match.h"
#include "bus-kernel.h"
+#include "kdbus.h"
struct reply_callback {
sd_bus_message_handler_t callback;
@@ -161,6 +162,7 @@ struct sd_bus {
bool filter_callbacks_modified:1;
bool nodes_modified:1;
bool trusted:1;
+ bool fake_creds_valid:1;
int use_memfd;
@@ -259,6 +261,9 @@ struct sd_bus {
sd_bus **default_bus_ptr;
pid_t tid;
+
+ struct kdbus_creds fake_creds;
+ char *fake_label;
};
#define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c
index e53bc51727..fb5266d44e 100644
--- a/src/libsystemd-bus/bus-kernel.c
+++ b/src/libsystemd-bus/bus-kernel.c
@@ -317,7 +317,9 @@ fail:
}
int bus_kernel_take_fd(sd_bus *b) {
- struct kdbus_cmd_hello hello;
+ struct kdbus_cmd_hello *hello;
+ struct kdbus_item *item;
+ size_t l, sz;
int r;
assert(b);
@@ -327,13 +329,38 @@ int bus_kernel_take_fd(sd_bus *b) {
b->use_memfd = 1;
- zero(hello);
- hello.size = sizeof(hello);
- hello.conn_flags = b->hello_flags;
- hello.attach_flags = b->attach_flags;
- hello.pool_size = KDBUS_POOL_SIZE;
+ sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
+
+ if (b->fake_creds_valid)
+ sz += ALIGN8(offsetof(struct kdbus_item, creds));
+
+ if (b->fake_label) {
+ l = strlen(b->fake_label);
+ sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
+ }
+
+ hello = alloca0(sz);
+ hello->size = sz;
+ hello->conn_flags = b->hello_flags;
+ hello->attach_flags = b->attach_flags;
+ hello->pool_size = KDBUS_POOL_SIZE;
+
+ item = hello->items;
- r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
+ if (b->fake_creds_valid) {
+ item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
+ item->type = KDBUS_ITEM_CREDS;
+ item->creds = b->fake_creds;
+
+ item = KDBUS_ITEM_NEXT(item);
+ }
+
+ if (b->fake_label) {
+ item->size = offsetof(struct kdbus_item, str) + l + 1;
+ memcpy(item->str, b->fake_label, l+1);
+ }
+
+ r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
if (r < 0)
return -errno;
@@ -347,26 +374,26 @@ int bus_kernel_take_fd(sd_bus *b) {
/* The higher 32bit of both flags fields are considered
* 'incompatible flags'. Refuse them all for now. */
- if (hello.bus_flags > 0xFFFFFFFFULL ||
- hello.conn_flags > 0xFFFFFFFFULL)
+ if (hello->bus_flags > 0xFFFFFFFFULL ||
+ hello->conn_flags > 0xFFFFFFFFULL)
return -ENOTSUP;
- if (hello.bloom_size != BLOOM_SIZE)
+ if (hello->bloom_size != BLOOM_SIZE)
return -ENOTSUP;
- if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
+ if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
return -ENOMEM;
- b->unique_id = hello.id;
+ b->unique_id = hello->id;
b->is_kernel = true;
b->bus_client = true;
- b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
+ b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
b->message_version = 2;
b->message_endian = BUS_NATIVE_ENDIAN;
/* the kernel told us the UUID of the underlying bus */
- memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
+ memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
return bus_start_running(b);
}
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 9dfb6e4442..910a5f8136 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -141,6 +141,7 @@ static void bus_free(sd_bus *b) {
free(b->address);
free(b->kernel);
free(b->machine);
+ free(b->fake_label);
free(b->exec_path);
strv_free(b->exec_argv);