]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: fix parsing of KDBUS_CMD_LIST 787/head
authorDavid Herrmann <dh.herrmann@gmail.com>
Thu, 30 Jul 2015 12:12:09 +0000 (14:12 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Thu, 30 Jul 2015 12:12:09 +0000 (14:12 +0200)
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.

src/bus-proxyd/driver.c
src/libsystemd/sd-bus/bus-control.c

index 1cb5ea50086af9aaecfadfddee12c2474b3a5664..aa94c6f51be0dd59b8cf706072ffd045b22fb91c 100644 (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;
-
-                        if (!streq_ptr(entry_name, arg0))
-                                continue;
-
-                        if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
-                                err  = -ENOMEM;
-                                break;
+                        KDBUS_ITEM_FOREACH(item, name, items) {
+                                if (item->type == KDBUS_ITEM_OWNED_NAME) {
+                                        if (!streq_ptr(item->name.name, arg0))
+                                                continue;
+
+                                        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);
index c53666ddd02f396ba41b4672d25cf770446e6c37..773c264cf05ba13b757e08041ffb793c3cc88d61 100644 (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;
+                                        }
+                                }
                         }
                 }
         }