[pulseaudio-discuss] [PATCH] bluetooth: Fix crash in setup_stream()

Frédéric Danis frederic.danis at collabora.com
Mon Jun 17 09:49:06 UTC 2019


setup_stream() crashes when calling set_nonblock() with an invalid
stream_fd.

This crash is due to a race condition.
The audio call starts normally, and a 1st call to setup_stream() is
completed properly.
But, if the call is "quickly" hung up, the stream_fd is in error (POLLHUP)
before other modules (loopback, …) have completed their initialization.
This error triggers a call to teardown_stream() which set stream_fd to -1.
After that, the other modules continue their initialization before the IO
thread is stopped, triggering a 2nd call to setup_stream().
---
 src/modules/bluetooth/module-bluez5-device.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 56c96054d..d0e3c7a09 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -753,6 +753,8 @@ static void setup_stream(struct userdata *u) {
     struct pollfd *pollfd;
     int one;
 
+    pa_assert(u->stream_fd >= 0);
+
     /* return if stream is already set up */
     if (u->stream_setup_done)
         return;
@@ -829,7 +831,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
         }
 
         case PA_SOURCE_MESSAGE_SETUP_STREAM:
-            setup_stream(u);
+            /* Skip stream setup if stream_fd as been invalidated, this can
+             * occurs in case of POLLHUP before other modules have finished
+             * their initialization */
+            if (u->stream_fd < 0)
+                pa_log_debug("Skip source stream setup while closing");
+            else
+                setup_stream(u);
             return 0;
 
     }
@@ -1007,7 +1015,13 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
         }
 
         case PA_SINK_MESSAGE_SETUP_STREAM:
-            setup_stream(u);
+            /* Skip stream setup if stream_fd as been invalidated, this can
+             * occurs in case of POLLHUP before other modules have finished
+             * their initialization */
+            if (u->stream_fd < 0)
+                pa_log_debug("Skip sink stream setup while closing");
+            else
+                setup_stream(u);
             return 0;
     }
 
-- 
2.18.0



More information about the pulseaudio-discuss mailing list