mirror of
https://github.com/systemd/systemd.git
synced 2026-07-27 03:39:09 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user