sd-bus: fix parsing of KDBUS_CMD_LIST

We *must not* assume that an entry returned by KDBUS_CMD_LIST only
carries a single KDBUS_ITEM_OWNED_NAME. Similarly, we already parse
multiple such items for message-metadata, so make sure we support the
same on KDBUS_CMD_LIST.

By relying on the kernel to return all names separately, we limit the
kernel API significantly. Stop this and let the kernel decide how to
return its data.
This commit is contained in:
David Herrmann
2015-07-30 14:12:09 +02:00
parent 8388607b58
commit 89c240e3a5
2 changed files with 24 additions and 24 deletions

View File

@@ -441,27 +441,29 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
name_list = (struct kdbus_info *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
KDBUS_FOREACH(name, name_list, cmd.list_size) {
const char *entry_name = NULL;
struct kdbus_item *item;
char *n;
KDBUS_ITEM_FOREACH(item, name, items)
if (item->type == KDBUS_ITEM_OWNED_NAME)
entry_name = item->name.name;
KDBUS_ITEM_FOREACH(item, name, items) {
if (item->type == KDBUS_ITEM_OWNED_NAME) {
if (!streq_ptr(item->name.name, arg0))
continue;
if (!streq_ptr(entry_name, arg0))
continue;
if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
err = -ENOMEM;
break;
}
if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
err = -ENOMEM;
break;
r = strv_consume(&owners, n);
if (r < 0) {
err = r;
break;
}
}
}
r = strv_consume(&owners, n);
if (r < 0) {
err = r;
if (err < 0)
break;
}
}
r = bus_kernel_cmd_free(a, cmd.offset);

View File

@@ -256,9 +256,7 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
name_list = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
KDBUS_FOREACH(name, name_list, cmd.list_size) {
struct kdbus_item *item;
const char *entry_name = NULL;
if ((flags & KDBUS_LIST_UNIQUE) && name->id != previous_id) {
char *n;
@@ -275,15 +273,15 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
previous_id = name->id;
}
KDBUS_ITEM_FOREACH(item, name, items)
if (item->type == KDBUS_ITEM_OWNED_NAME)
entry_name = item->name.name;
if (entry_name && service_name_is_valid(entry_name)) {
r = strv_extend(x, entry_name);
if (r < 0) {
r = -ENOMEM;
goto fail;
KDBUS_ITEM_FOREACH(item, name, items) {
if (item->type == KDBUS_ITEM_OWNED_NAME) {
if (service_name_is_valid(item->name.name)) {
r = strv_extend(x, item->name.name);
if (r < 0) {
r = -ENOMEM;
goto fail;
}
}
}
}
}