X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-kernel.c;h=f32f271b7dddffd0967f79dde5969bff541d0d20;hb=613ec4b836c6f322762b4a3e358d22a81b8d6f2c;hp=0437c96a9e55ce3be20157179e4e9aee01aae3c8;hpb=29a07cdb4a317f2e1ea160b79bfe6eb1be2e6e01;p=elogind.git diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 0437c96a9..f32f271b7 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -363,6 +363,7 @@ int bus_kernel_take_fd(sd_bus *b) { b->bus_client = true; 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)); @@ -514,12 +515,12 @@ static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_ assert(k); assert(d); - if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_STARTER))) + if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) old_owner[0] = 0; else sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id); - if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_STARTER))) { + if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) { if (isempty(old_owner)) return 0; @@ -833,6 +834,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { if (r < 0) goto fail; + /* Override information from the user header with data from the kernel */ if (k->src_id == KDBUS_SRC_ID_KERNEL) m->sender = "org.freedesktop.DBus"; else { @@ -1020,7 +1022,7 @@ int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) { if (flags & SD_BUS_NAME_REPLACE_EXISTING) f |= KDBUS_NAME_REPLACE_EXISTING; - if (!(flags & SD_BUS_NAME_QUEUE)) + if (flags & SD_BUS_NAME_QUEUE) f |= KDBUS_NAME_QUEUE; *kdbus_flags = f; @@ -1139,10 +1141,10 @@ int bus_kernel_create_starter(const char *bus, const char *name) { n = hello->items; strcpy(n->str, name); n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1; - n->type = KDBUS_ITEM_STARTER_NAME; + n->type = KDBUS_ITEM_NAME; hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size); - hello->conn_flags = KDBUS_HELLO_STARTER; + hello->conn_flags = KDBUS_HELLO_ACTIVATOR; hello->pool_size = KDBUS_POOL_SIZE; if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) { @@ -1217,18 +1219,37 @@ int bus_kernel_create_namespace(const char *name, char **s) { return fd; } -int bus_kernel_monitor(sd_bus *bus) { - struct kdbus_cmd_monitor cmd_monitor; - int r; +int bus_kernel_create_monitor(const char *bus) { + struct kdbus_cmd_hello *hello; + char *p; + int fd; assert(bus); - cmd_monitor.id = 0; - cmd_monitor.flags = KDBUS_MONITOR_ENABLE; + 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); - r = ioctl(bus->input_fd, KDBUS_CMD_MONITOR, &cmd_monitor); - if (r < 0) + fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) return -errno; - return 1; + hello = alloca0(sizeof(struct kdbus_cmd_hello)); + hello->size = sizeof(struct kdbus_cmd_hello); + hello->conn_flags = KDBUS_HELLO_ACTIVATOR; + 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; + } + + return fd; }