]> code.delx.au - pulseaudio/commitdiff
bluetooth: Protect from a misbehaving bluetoothd
authorJoão Paulo Rechi Vita <jprvita@gmail.com>
Tue, 24 Sep 2013 22:45:36 +0000 (19:45 -0300)
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Sun, 29 Sep 2013 13:54:37 +0000 (16:54 +0300)
bluetoothd always send the GetManagedObjects() reply messages with the
objects array argument following an in-depth order starting from the
root. That means parents will always be known at the time their children
objects are parsed, if clients parse the objects in the same order they
appear in the array, as we do in PulseAudio.

This commit tries to protect PulseAudio in the case bluetoothd changes
that behavior for some reason. It hasn't been tested, since this
situation never occurs.

src/modules/bluetooth/bluez5-util.c
src/modules/bluetooth/bluez5-util.h

index 541948fb07592f62f1dc4587b4445a277936ed83..17889b61c9b7b88a015446c8adef49d6e5a0cc9b 100644 (file)
@@ -489,11 +489,13 @@ static void parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, bo
                     return;
                 }
 
-                if (d->adapter) {
+                if (d->adapter_path) {
                     pa_log_warn("Device %s: Received a duplicate 'Adapter' property, ignoring", d->path);
                     return;
                 }
 
+                d->adapter_path = pa_xstrdup(value);
+
                 d->adapter = pa_hashmap_get(d->discovery->adapters, value);
                 if (!d->adapter)
                     pa_log_info("Device %s: 'Adapter' property references an unknown adapter %s.", d->path, value);
@@ -561,7 +563,7 @@ static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, b
         dbus_message_iter_next(&element_i);
     }
 
-    if (!d->address || !d->adapter || !d->alias) {
+    if (!d->address || !d->adapter_path || !d->alias) {
         pa_log_error("Non-optional information missing for device %s", d->path);
         d->device_info_valid = -1;
         return -1;
@@ -685,6 +687,7 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const
 static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) {
     DBusMessageIter element_i;
     const char *path;
+    void *state;
     pa_bluetooth_device *d;
 
     pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH);
@@ -745,6 +748,15 @@ static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessa
         dbus_message_iter_next(&element_i);
     }
 
+    PA_HASHMAP_FOREACH(d, y->devices, state)
+        if (!d->adapter && d->adapter_path) {
+            d->adapter = pa_hashmap_get(d->discovery->adapters, d->adapter_path);
+            if (!d->adapter) {
+                pa_log_error("Device %s is child of nonexistent adapter %s", d->path, d->adapter_path);
+                d->device_info_valid = -1;
+            }
+        }
+
     return;
 }
 
index 41673e3d83b57bc0c784f7020c56a07451e4f2d1..bbc5b714c32e71cc4b28dbd325822bec6b028596 100644 (file)
@@ -80,6 +80,7 @@ struct pa_bluetooth_device {
 
     /* Device information */
     char *path;
+    char *adapter_path;
     char *alias;
     char *address;
     uint32_t class_of_device;