From b2d581b42e9e8645b2411532c2164d35a3b60f41 Mon Sep 17 00:00:00 2001 From: Michael Goddard Date: Fri, 27 Apr 2012 11:58:50 +1000 Subject: [PATCH] Fix a possible stale pointer access if we can't connect to PulseAudio. We free the mainloop but didn't check validity before calling lock or unlock. Also we might need to unlock the main loop before freeing it in some other error cases. Change-Id: Iadf1049324cdf37ca9841b82e53e33afdcba8cb2 Reviewed-by: Jun Zhu Reviewed-by: Lev Zelenskiy Reviewed-by: Dmytro Poplavskiy --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 8cc49004..e3890904 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -114,12 +114,14 @@ public: inline void lock() { - pa_threaded_mainloop_lock(m_mainLoop); + if (m_mainLoop) + pa_threaded_mainloop_lock(m_mainLoop); } inline void unlock() { - pa_threaded_mainloop_unlock(m_mainLoop); + if (m_mainLoop) + pa_threaded_mainloop_unlock(m_mainLoop); } inline pa_context *context() const @@ -152,6 +154,7 @@ private: { m_vol = PA_VOLUME_NORM; + m_context = 0; m_mainLoop = pa_threaded_mainloop_new(); if (m_mainLoop == 0) { qWarning("PulseAudioService: unable to create pulseaudio mainloop"); @@ -173,14 +176,19 @@ private: if (m_context == 0) { qWarning("PulseAudioService: Unable to create new pulseaudio context"); + pa_threaded_mainloop_unlock(m_mainLoop); pa_threaded_mainloop_free(m_mainLoop); + m_mainLoop = 0; return; } if (pa_context_connect(m_context, 0, (pa_context_flags_t)0, 0) < 0) { qWarning("PulseAudioService: pa_context_connect() failed"); pa_context_unref(m_context); + pa_threaded_mainloop_unlock(m_mainLoop); pa_threaded_mainloop_free(m_mainLoop); + m_mainLoop = 0; + m_context = 0; return; } unlock(); @@ -191,6 +199,7 @@ private: void release() { if (!m_prepared) return; + pa_context_unref(m_context); pa_threaded_mainloop_stop(m_mainLoop); pa_threaded_mainloop_free(m_mainLoop); m_prepared = false;