reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit b9fa9885509451ebda813b07fde46f410b1bf15a
parent 0eb0446119d0c5bf570ca4534c227e0a318e8f30
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sun,  5 Feb 2017 23:58:55 -0500

download: fix use after free of m_mutex (same as 1ae44ee634057a11dfa1a33cc9597b45b41b8667)

Diffstat:
Msrc/download.cpp | 31+++++++++++++++----------------
Msrc/download.hpp | 6++++--
2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/src/download.cpp b/src/download.cpp @@ -328,11 +328,6 @@ void DownloadQueue::abort() m_onAbort(); } -DownloadNotifier::DownloadNotifier() : m_active(0) -{ - assert(!s_instance); -} - DownloadNotifier *DownloadNotifier::get() { if(!s_instance) @@ -362,20 +357,24 @@ void DownloadNotifier::notify(const Notification &notif) void DownloadNotifier::tick() { DownloadNotifier *instance = DownloadNotifier::get(); + instance->processQueue(); - WDL_MutexLock lock(&instance->m_mutex); - - while(!instance->m_queue.empty()) { - const Notification notif = instance->m_queue.front(); - instance->m_queue.pop(); - - notif.first->setState(notif.second); - // `this` can be destroyed here - } - + // doing this in stop() would cause a use after free of m_mutex in processQueue if(!instance->m_active) { plugin_register("-timer", (void *)tick); - s_instance = nullptr; + delete s_instance; + s_instance = nullptr; + } +} + +void DownloadNotifier::processQueue() +{ + WDL_MutexLock lock(&m_mutex); + + while(!m_queue.empty()) { + const Notification &notif = m_queue.front(); + notif.first->setState(notif.second); + m_queue.pop(); } } diff --git a/src/download.hpp b/src/download.hpp @@ -156,8 +156,6 @@ class DownloadNotifier { public: static DownloadNotifier *get(); - DownloadNotifier(); - void start(); void stop(); @@ -167,6 +165,10 @@ private: static DownloadNotifier *s_instance; static void tick(); + DownloadNotifier() : m_active(0) {} + ~DownloadNotifier() = default; + void processQueue(); + WDL_Mutex m_mutex; size_t m_active; std::queue<Notification> m_queue;