X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-kernel.c;h=2c87f22fd7f5e7509d9d27f52055f4e946746e61;hp=98fc27cda51445385b51384d596f6a7bca1e01f3;hb=65dae17a2f890b12a07dd4901b3db02b1031c463;hpb=fd5b0b9141728abf503f900200dd8b43248ec9e2 diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 98fc27cda..2c87f22fd 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -28,6 +28,7 @@ #include #include "util.h" +#include "strv.h" #include "bus-internal.h" #include "bus-message.h" @@ -248,8 +249,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { memset(m->kdbus, 0, sz); m->kdbus->flags = - ((m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) | - ((m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0); + ((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; @@ -800,9 +801,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { destination = d->str; break; - case KDBUS_ITEM_NAMES: - m->creds.well_known_names = d->str; - m->creds.well_known_names_size = l; + case KDBUS_ITEM_NAME: + r = strv_extend(&m->creds.well_known_names, d->name.name); + if (r < 0) + goto fail; m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask; break; @@ -830,7 +832,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { if (!m->destination) { if (destination) m->destination = destination; - else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_NAME && + else if (k->dst_id != KDBUS_DST_ID_NAME && k->dst_id != KDBUS_DST_ID_BROADCAST) { snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id); m->destination = m->destination_buffer; @@ -1074,6 +1076,13 @@ int bus_kernel_create_bus(const char *name, char **s) { return -errno; } + /* The higher 32bit of the flags field are considered + * 'incompatible flags'. Refuse them all for now. */ + if (make->flags > 0xFFFFFFFFULL) { + close_nointr_nofail(fd); + return -ENOTSUP; + } + if (s) { char *p; @@ -1089,6 +1098,56 @@ int bus_kernel_create_bus(const char *name, char **s) { return fd; } +int bus_kernel_create_starter(const char *bus, const char *name) { + struct kdbus_cmd_hello *hello; + struct kdbus_item *n; + char *p; + int fd; + + assert(bus); + assert(name); + + p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus")); + sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus); + + fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) + + offsetof(struct kdbus_item, str) + + strlen(name) + 1)); + + n = hello->items; + strcpy(n->str, name); + n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1; + n->type = KDBUS_ITEM_STARTER_NAME; + + hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size); + hello->conn_flags = KDBUS_HELLO_STARTER; + hello->pool_size = KDBUS_POOL_SIZE; + + if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + /* 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) { + close_nointr_nofail(fd); + return -ENOTSUP; + } + + if (hello->bloom_size != BLOOM_SIZE) { + close_nointr_nofail(fd); + return -ENOTSUP; + } + + return fd; +} + int bus_kernel_create_namespace(const char *name, char **s) { struct kdbus_cmd_ns_make *make; struct kdbus_item *n; @@ -1118,6 +1177,13 @@ int bus_kernel_create_namespace(const char *name, char **s) { return -errno; } + /* The higher 32bit of the flags field are considered + * 'incompatible flags'. Refuse them all for now. */ + if (make->flags > 0xFFFFFFFFULL) { + close_nointr_nofail(fd); + return -ENOTSUP; + } + if (s) { char *p;