Zbigniew Jędrzejewski-Szmek 62fe94
From ff02f101cb7db516bf1732bb74c42cb3b6259af1 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 62fe94
From: David Herrmann <dh.herrmann@gmail.com>
Zbigniew Jędrzejewski-Szmek 62fe94
Date: Wed, 17 Sep 2014 10:32:49 +0200
Zbigniew Jędrzejewski-Szmek 62fe94
Subject: [PATCH] bus: fix error leak in bus_node_exists()
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
If we call into user callbacks, we must always propagate possible errors.
Zbigniew Jędrzejewski-Szmek 62fe94
Fix bus_node_exists() to do that and adjust the callers (which already
Zbigniew Jędrzejewski-Szmek 62fe94
partially propagated the error).
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
Also speed up that function by first checking for registered enumerators
Zbigniew Jędrzejewski-Szmek 62fe94
and/or object-managers.
Zbigniew Jędrzejewski-Szmek 62fe94
---
Zbigniew Jędrzejewski-Szmek 62fe94
 src/libsystemd/sd-bus/bus-objects.c | 29 ++++++++++++++++++-----------
Zbigniew Jędrzejewski-Szmek 62fe94
 1 file changed, 18 insertions(+), 11 deletions(-)
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
Zbigniew Jędrzejewski-Szmek 62fe94
index ecac73a94d..0ab1119b58 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/libsystemd/sd-bus/bus-objects.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/libsystemd/sd-bus/bus-objects.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -820,7 +820,7 @@ static int property_get_all_callbacks_run(
Zbigniew Jędrzejewski-Szmek 62fe94
         return 1;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-static bool bus_node_exists(
Zbigniew Jędrzejewski-Szmek 62fe94
+static int bus_node_exists(
Zbigniew Jędrzejewski-Szmek 62fe94
                 sd_bus *bus,
Zbigniew Jędrzejewski-Szmek 62fe94
                 struct node *n,
Zbigniew Jędrzejewski-Szmek 62fe94
                 const char *path,
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -828,6 +828,7 @@ static bool bus_node_exists(
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         struct node_vtable *c;
Zbigniew Jędrzejewski-Szmek 62fe94
         struct node_callback *k;
Zbigniew Jędrzejewski-Szmek 62fe94
+        int r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(bus);
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(n);
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -836,11 +837,14 @@ static bool bus_node_exists(
Zbigniew Jędrzejewski-Szmek 62fe94
         /* Tests if there's anything attached directly to this node
Zbigniew Jędrzejewski-Szmek 62fe94
          * for the specified path */
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!require_fallback && (n->enumerators || n->object_managers))
Zbigniew Jędrzejewski-Szmek 62fe94
+                return true;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         LIST_FOREACH(callbacks, k, n->callbacks) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (require_fallback && !k->is_fallback)
Zbigniew Jędrzejewski-Szmek 62fe94
                         continue;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                return true;
Zbigniew Jędrzejewski-Szmek 62fe94
+                return 1;
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         LIST_FOREACH(vtables, c, n->vtables) {
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -849,13 +853,14 @@ static bool bus_node_exists(
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (require_fallback && !c->is_fallback)
Zbigniew Jędrzejewski-Szmek 62fe94
                         continue;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (node_vtable_get_userdata(bus, path, c, NULL, &error) > 0)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return true;
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = node_vtable_get_userdata(bus, path, c, NULL, &error);
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (r != 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (bus->nodes_modified)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return false;
Zbigniew Jędrzejewski-Szmek 62fe94
+                        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        return !require_fallback && (n->enumerators || n->object_managers);
Zbigniew Jędrzejewski-Szmek 62fe94
+        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 static int process_introspect(
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -938,12 +943,12 @@ static int process_introspect(
Zbigniew Jędrzejewski-Szmek 62fe94
                 /* Nothing?, let's see if we exist at all, and if not
Zbigniew Jędrzejewski-Szmek 62fe94
                  * refuse to do anything */
Zbigniew Jędrzejewski-Szmek 62fe94
                 r = bus_node_exists(bus, n, m->path, require_fallback);
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (bus->nodes_modified)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (r == 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (r <= 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        goto finish;
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (bus->nodes_modified) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                        r = 0;
Zbigniew Jędrzejewski-Szmek 62fe94
                         goto finish;
Zbigniew Jędrzejewski-Szmek 62fe94
+                }
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         *found_object = true;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1293,6 +1298,8 @@ static int object_find_and_run(
Zbigniew Jędrzejewski-Szmek 62fe94
                 r = bus_node_exists(bus, n, m->path, require_fallback);
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         return r;
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (bus->nodes_modified)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r > 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         *found_object = true;
Zbigniew Jędrzejewski-Szmek 62fe94
         }