X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-kernel.c;h=878cd9c432f1b022d1098b167756b1915ac42fb2;hp=ed4e189c3ea92a249889c69cd3a0e832ce42a4a1;hb=e86b80b834016d273196c5ec9687fddcddcf9381;hpb=7211f918ba2b86e0041413b47d51d7593e73cf5d diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index ed4e189c3..878cd9c43 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -57,23 +57,27 @@ static void append_payload_vec(struct kdbus_msg_data **d, const void *p, size_t assert(p); assert(sz > 0); + *d = ALIGN8_PTR(*d); + (*d)->size = offsetof(struct kdbus_msg_data, vec) + sizeof(struct kdbus_vec); (*d)->type = KDBUS_MSG_PAYLOAD_VEC; (*d)->vec.address = (uint64_t) p; (*d)->vec.size = sz; - *d = (struct kdbus_msg_data*) ((uint8_t*) *d + ALIGN8((*d)->size)); + *d = (struct kdbus_msg_data*) ((uint8_t*) *d + (*d)->size); } static void append_destination(struct kdbus_msg_data **d, const char *s, size_t length) { assert(d); assert(d); - (*d)->size = offsetof(struct kdbus_msg_data, data) + length + 1; + *d = ALIGN8_PTR(*d); + + (*d)->size = offsetof(struct kdbus_msg_data, str) + length + 1; (*d)->type = KDBUS_MSG_DST_NAME; - memcpy((*d)->data, s, length + 1); + memcpy((*d)->str, s, length + 1); - *d = (struct kdbus_msg_data*) ((uint8_t*) *d + ALIGN8((*d)->size)); + *d = (struct kdbus_msg_data*) ((uint8_t*) *d + (*d)->size); } static int bus_message_setup_kmsg(sd_bus_message *m) { @@ -109,7 +113,7 @@ static int bus_message_setup_kmsg(sd_bus_message *m) { sz += ALIGN8(offsetof(struct kdbus_msg, data) + dl + 1); } - m->kdbus = malloc0(sz); + m->kdbus = aligned_alloc(8, sz); if (!m->kdbus) return -ENOMEM; @@ -158,6 +162,9 @@ int bus_kernel_take_fd(sd_bus *b) { assert(b); + if (b->is_server) + return -EINVAL; + r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello); if (r < 0) return -errno; @@ -166,6 +173,7 @@ int bus_kernel_take_fd(sd_bus *b) { return -ENOMEM; b->is_kernel = true; + b->bus_client = true; r = bus_start_running(b); if (r < 0) @@ -180,6 +188,9 @@ int bus_kernel_connect(sd_bus *b) { assert(b->output_fd < 0); assert(b->kernel); + if (b->is_server) + return -EINVAL; + b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC); if (b->input_fd < 0) return -errno; @@ -204,7 +215,7 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) { if (r < 0) return errno == EAGAIN ? 0 : -errno; - return 0; + return 1; } static void close_kdbus_msg(struct kdbus_msg *k) { @@ -228,6 +239,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess size_t total, n_bytes = 0, idx = 0; struct kdbus_creds *creds = NULL; uint64_t nsec = 0; + const char *destination = NULL; int r; assert(bus); @@ -271,6 +283,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess creds = &d->creds; else if (d->type == KDBUS_MSG_TIMESTAMP) nsec = d->ts_ns; + else if (d->type == KDBUS_MSG_DST_NAME) + destination = d->str; } if (!h) @@ -326,6 +340,23 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess return r; } + if (k->src_id == KDBUS_SRC_ID_KERNEL) + m->sender = "org.freedesktop.DBus"; + else { + snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id); + m->sender = m->sender_buffer; + } + + if (!m->destination) { + if (destination) + m->destination = destination; + else if (k->dst_id != KDBUS_DST_ID_WELL_KNOWN_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; + } + } + /* We take possession of the kmsg struct now */ m->kdbus = k; m->free_kdbus = true; @@ -339,7 +370,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { struct kdbus_msg *k; - size_t sz = 128; + size_t sz = 1024; int r; assert(bus); @@ -348,17 +379,20 @@ int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { for (;;) { void *q; - q = realloc(bus->rbuffer, sz); + q = aligned_alloc(8, sz); if (!q) return -errno; + free(bus->rbuffer); k = bus->rbuffer = q; k->size = sz; /* Let's tell valgrind that there's really no need to * initialize this fully. This should be removed again * when valgrind learned the kdbus ioctls natively. */ +#ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_MAKE_MEM_DEFINED(k, sz); +#endif r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, bus->rbuffer); if (r >= 0) @@ -379,7 +413,7 @@ int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { else close_kdbus_msg(k); - return r; + return r < 0 ? r : 1; } int bus_kernel_create(const char *name, char **s) { @@ -399,7 +433,7 @@ int bus_kernel_create(const char *name, char **s) { fname = alloca(offsetof(struct kdbus_cmd_fname, name) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1); sprintf(fname->name, "%lu-%s", (unsigned long) getuid(), name); fname->size = offsetof(struct kdbus_cmd_fname, name) + strlen(fname->name) + 1; - fname->kernel_flags = KDBUS_CMD_FNAME_ACCESS_WORLD; + fname->kernel_flags = KDBUS_CMD_FNAME_ACCESS_WORLD | KDBUS_CMD_FNAME_POLICY_OPEN; fname->user_flags = 0; p = strjoin("/dev/kdbus/", fname->name, "/bus", NULL);