mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-22 08:56:52 -05:00
bluetooth: Fix crash in setup_stream()
setup_stream() crashes when calling set_nonblock() with an invalid stream_fd. On a new call, the ofono backend gets notified of a new connection. The ofono backend sets the transport state to playing, and that triggers a profile change, which sets up the stream for the first time. Then module-bluetooth-policy sets up the loopbacks. The loopbacks get fully initialized before the crash. After module-bluetooth-policy has done its things, the execution continues in the transport state change hook. The next hook user is module-bluez5-device, whose handle_transport_state_change() function gets called. It will then set up the stream again even though it's already set up. I'm not sure if that's a some kind of a bug. setup_stream() can handle the case where it's unnecessarily called, though, so this second setup is not a big problem. The crash happens, because the connection died due to POLLHUP in the IO thread before the second setup_stream() call.
This commit is contained in:
parent
4be2625ef8
commit
661b13d50d
1 changed files with 24 additions and 2 deletions
|
|
@ -753,6 +753,8 @@ static void setup_stream(struct userdata *u) {
|
||||||
struct pollfd *pollfd;
|
struct pollfd *pollfd;
|
||||||
int one;
|
int one;
|
||||||
|
|
||||||
|
pa_assert(u->stream_fd >= 0);
|
||||||
|
|
||||||
/* return if stream is already set up */
|
/* return if stream is already set up */
|
||||||
if (u->stream_setup_done)
|
if (u->stream_setup_done)
|
||||||
return;
|
return;
|
||||||
|
|
@ -829,7 +831,17 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
|
||||||
}
|
}
|
||||||
|
|
||||||
case PA_SOURCE_MESSAGE_SETUP_STREAM:
|
case PA_SOURCE_MESSAGE_SETUP_STREAM:
|
||||||
setup_stream(u);
|
/* Skip stream setup if stream_fd has been invalidated.
|
||||||
|
This can occur if the stream has already been set up and
|
||||||
|
then immediately received POLLHUP. If the stream has
|
||||||
|
already been set up earlier, then this setup_stream()
|
||||||
|
call is redundant anyway, but currently the code
|
||||||
|
is such that this kind of unnecessary setup_stream()
|
||||||
|
calls can happen. */
|
||||||
|
if (u->stream_fd < 0)
|
||||||
|
pa_log_debug("Skip source stream setup while closing");
|
||||||
|
else
|
||||||
|
setup_stream(u);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1007,7 +1019,17 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
}
|
}
|
||||||
|
|
||||||
case PA_SINK_MESSAGE_SETUP_STREAM:
|
case PA_SINK_MESSAGE_SETUP_STREAM:
|
||||||
setup_stream(u);
|
/* Skip stream setup if stream_fd has been invalidated.
|
||||||
|
This can occur if the stream has already been set up and
|
||||||
|
then immediately received POLLHUP. If the stream has
|
||||||
|
already been set up earlier, then this setup_stream()
|
||||||
|
call is redundant anyway, but currently the code
|
||||||
|
is such that this kind of unnecessary setup_stream()
|
||||||
|
calls can happen. */
|
||||||
|
if (u->stream_fd < 0)
|
||||||
|
pa_log_debug("Skip sink stream setup while closing");
|
||||||
|
else
|
||||||
|
setup_stream(u);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue