From e2d435dad669009f4e0dc7dd359a1d72719078c2 Mon Sep 17 00:00:00 2001 From: Tom M <tom.mbrt@googlemail.com> Date: Thu, 30 Apr 2020 19:49:58 +0200 Subject: [PATCH] Fix a NULL deref in delete_rvoice_mixer_threads() (#641) The function attempts to lock a mutex that might have not been created yet, due to a previous error. --- src/rvoice/fluid_rvoice_mixer.c | 42 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/rvoice/fluid_rvoice_mixer.c b/src/rvoice/fluid_rvoice_mixer.c index 463b9806..4f691198 100644 --- a/src/rvoice/fluid_rvoice_mixer.c +++ b/src/rvoice/fluid_rvoice_mixer.c @@ -728,9 +728,9 @@ new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, int fx_units, fluid_real FLUID_LOG(FLUID_ERR, "Out of memory"); goto error_recovery; } - + FLUID_MEMSET(mixer->fx, 0, fx_units * sizeof(*mixer->fx)); - + for(i = 0; i < fx_units; i++) { mixer->fx[i].reverb = new_fluid_revmodel(sample_rate); @@ -768,7 +768,7 @@ new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, int fx_units, fluid_real #endif return mixer; - + error_recovery: delete_fluid_rvoice_mixer(mixer); return NULL; @@ -1266,27 +1266,33 @@ fluid_render_loop_multithread(fluid_rvoice_mixer_t *mixer, int current_blockcoun static void delete_rvoice_mixer_threads(fluid_rvoice_mixer_t *mixer) { int i; - fluid_atomic_int_set(&mixer->threads_should_terminate, 1); - // Signal threads to wake up - fluid_cond_mutex_lock(mixer->wakeup_threads_m); - for(i = 0; i < mixer->thread_count; i++) + // if no threads have been created yet (e.g. because a previous error prevented creation of threads + // mutexes and condition variables), skip terminating threads + if(mixer->thread_count != 0) { - fluid_atomic_int_set(&mixer->threads[i].ready, THREAD_BUF_TERMINATE); - } + fluid_atomic_int_set(&mixer->threads_should_terminate, 1); + // Signal threads to wake up + fluid_cond_mutex_lock(mixer->wakeup_threads_m); - fluid_cond_broadcast(mixer->wakeup_threads); - fluid_cond_mutex_unlock(mixer->wakeup_threads_m); - - for(i = 0; i < mixer->thread_count; i++) - { - if(mixer->threads[i].thread) + for(i = 0; i < mixer->thread_count; i++) { - fluid_thread_join(mixer->threads[i].thread); - delete_fluid_thread(mixer->threads[i].thread); + fluid_atomic_int_set(&mixer->threads[i].ready, THREAD_BUF_TERMINATE); } - fluid_mixer_buffers_free(&mixer->threads[i]); + fluid_cond_broadcast(mixer->wakeup_threads); + fluid_cond_mutex_unlock(mixer->wakeup_threads_m); + + for(i = 0; i < mixer->thread_count; i++) + { + if(mixer->threads[i].thread) + { + fluid_thread_join(mixer->threads[i].thread); + delete_fluid_thread(mixer->threads[i].thread); + } + + fluid_mixer_buffers_free(&mixer->threads[i]); + } } FLUID_FREE(mixer->threads);