X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=d9252b256024f6d4ec765f83af1af0bb2429c8e2;hb=315a73d97f277bfbb32170d0a5e2d259198a6838;hp=2978b0a2844c8dca699b96b2b88c3d877f3f5ac4;hpb=94e15fdc4d9d96fa6607bfb4eaaea164a3aec417;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 2978b0a28..d9252b256 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -744,7 +744,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { /* If we requested the list of well-known names to be appended * and the sender had none no item for it will be - * attached. However, this does *not* mean that we the kernel + * attached. However, this does *not* mean that the kernel * didn't want to provide this information to us. Hence, let's * explicitly mark this information as available if it was * requested. */ @@ -815,7 +815,13 @@ fail: } int bus_kernel_take_fd(sd_bus *b) { + struct kdbus_cmd_free cmd_free = { + .size = sizeof(cmd_free), + .flags = 0, + }; + 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 +934,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; + } + + 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) - return -ENOMEM; + if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) { + r = -ENOMEM; + goto fail; + } b->unique_id = hello->id; @@ -957,7 +980,15 @@ 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: + cmd_free.offset = hello->offset; + (void) ioctl(b->input_fd, KDBUS_CMD_FREE, &cmd_free); + return r; } int bus_kernel_connect(sd_bus *b) { @@ -980,6 +1011,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, }; @@ -1235,6 +1267,9 @@ static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) { assert(k->payload_type == KDBUS_PAYLOAD_KERNEL); KDBUS_ITEM_FOREACH(d, k, items) { + if (d->type == KDBUS_ITEM_TIMESTAMP) + continue; + if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) { if (found) return -EBADMSG; @@ -1478,6 +1513,7 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { make = alloca0_align(offsetof(struct kdbus_cmd_make, items) + ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) + ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) + + ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) + ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1), 8); @@ -1504,6 +1540,13 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { n->data64[0] = _KDBUS_ATTACH_ANY; make->size += ALIGN8(n->size); + /* Provide all metadata via bus-owner queries */ + n = KDBUS_ITEM_NEXT(n); + n->type = KDBUS_ITEM_ATTACH_FLAGS_SEND; + n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t); + n->data64[0] = _KDBUS_ATTACH_ANY; + make->size += ALIGN8(n->size); + /* Set the a good name */ n = KDBUS_ITEM_NEXT(n); sprintf(n->str, UID_FMT "-%s", getuid(), name); @@ -1533,69 +1576,6 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { return fd; } -static int bus_kernel_translate_access(BusPolicyAccess access) { - assert(access >= 0); - assert(access < _BUS_POLICY_ACCESS_MAX); - - switch (access) { - - case BUS_POLICY_ACCESS_SEE: - return KDBUS_POLICY_SEE; - - case BUS_POLICY_ACCESS_TALK: - return KDBUS_POLICY_TALK; - - case BUS_POLICY_ACCESS_OWN: - return KDBUS_POLICY_OWN; - - default: - assert_not_reached("Unknown policy access"); - } -} - -static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) { - int r; - - assert(policy); - assert(item); - - switch (policy->type) { - - case BUSNAME_POLICY_TYPE_USER: { - const char *user = policy->name; - uid_t uid; - - r = get_user_creds(&user, &uid, NULL, NULL, NULL); - if (r < 0) - return r; - - item->policy_access.type = KDBUS_POLICY_ACCESS_USER; - item->policy_access.id = uid; - break; - } - - case BUSNAME_POLICY_TYPE_GROUP: { - const char *group = policy->name; - gid_t gid; - - r = get_group_creds(&group, &gid); - if (r < 0) - return r; - - item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP; - item->policy_access.id = gid; - break; - } - - default: - assert_not_reached("Unknown policy type"); - } - - item->policy_access.access = bus_kernel_translate_access(policy->access); - - return 0; -} - int bus_kernel_open_bus_fd(const char *bus, char **path) { char *p; int fd; @@ -1672,126 +1652,6 @@ int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char * return fd; } -int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) { - - struct kdbus_cmd_update *update; - struct kdbus_item *n; - BusEndpointPolicy *po; - Iterator i; - size_t size; - int r; - - size = ALIGN8(offsetof(struct kdbus_cmd_update, items)); - - HASHMAP_FOREACH(po, ep->policy_hash, i) { - size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1); - size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access)); - } - - update = alloca0_align(size, 8); - update->size = size; - - n = update->items; - - HASHMAP_FOREACH(po, ep->policy_hash, i) { - n->type = KDBUS_ITEM_NAME; - n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1; - strcpy(n->str, po->name); - n = KDBUS_ITEM_NEXT(n); - - n->type = KDBUS_ITEM_POLICY_ACCESS; - n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access); - - n->policy_access.type = KDBUS_POLICY_ACCESS_USER; - n->policy_access.access = bus_kernel_translate_access(po->access); - n->policy_access.id = uid; - - n = KDBUS_ITEM_NEXT(n); - } - - r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update); - if (r < 0) - return -errno; - - return 0; -} - -int bus_kernel_make_starter( - int fd, - const char *name, - bool activating, - bool accept_fd, - BusNamePolicy *policy, - BusPolicyAccess world_policy) { - - struct kdbus_cmd_hello *hello; - struct kdbus_item *n; - size_t policy_cnt = 0; - BusNamePolicy *po; - size_t size; - int r; - - assert(fd >= 0); - assert(name); - - LIST_FOREACH(policy, po, policy) - policy_cnt++; - - if (world_policy >= 0) - policy_cnt++; - - size = offsetof(struct kdbus_cmd_hello, items) + - ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) + - policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access)); - - hello = alloca0_align(size, 8); - - n = hello->items; - strcpy(n->str, name); - n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1; - n->type = KDBUS_ITEM_NAME; - n = KDBUS_ITEM_NEXT(n); - - LIST_FOREACH(policy, po, policy) { - n->type = KDBUS_ITEM_POLICY_ACCESS; - n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access); - - r = bus_kernel_translate_policy(po, n); - if (r < 0) - return r; - - n = KDBUS_ITEM_NEXT(n); - } - - if (world_policy >= 0) { - n->type = KDBUS_ITEM_POLICY_ACCESS; - n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access); - n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD; - n->policy_access.access = bus_kernel_translate_access(world_policy); - } - - hello->size = size; - hello->flags = - (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) | - (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0); - hello->pool_size = KDBUS_POOL_SIZE; - hello->attach_flags_send = _KDBUS_ATTACH_ANY; - hello->attach_flags_recv = _KDBUS_ATTACH_ANY; - - if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) - return -errno; - - /* 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; -} - int bus_kernel_try_close(sd_bus *bus) { assert(bus); assert(bus->is_kernel);