From 1828011317b0a8142c3b66fff22661a962760574 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 24 May 2017 16:22:34 +0200 Subject: [PATCH] tevent: Fix a race condition in tevent context rundown We protect setting tctx->event_ctx=NULL with tctx->event_ctx_mutex. But in _tevent_threaded_schedule_immediate we have the classic TOCTOU race: After we checked "ev==NULL", looking at tevent_common_context_destructor the event context can go after _tevent_threaded_schedule_immediate checked. We need to serialize things a bit by keeping tctx->event_ctx_mutex locked while we reference "ev", in particular in the DLIST_ADD_END(ev->scheduled_immediates,im); I think the locking hierarchy is still maintained, tevent_atfork_prepare() first locks all the tctx locks, and then the scheduled_mutex. Also, I don't think this will impact parallelism too badly: event_ctx_mutex is only used to protect setting tctx->ev. Found by staring at code while fixing the FreeBSD memleak due to not destroying scheduled_mutex. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Jun 9 00:45:26 CEST 2017 on sn-devel-144 --- lib/tevent/tevent_threads.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c index 8197323af020..8ecda027c331 100644 --- a/lib/tevent/tevent_threads.c +++ b/lib/tevent/tevent_threads.c @@ -443,15 +443,14 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, ev = tctx->event_ctx; - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - if (ev == NULL) { /* * Our event context is already gone. */ + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } return; } @@ -479,6 +478,11 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, abort(); } + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + /* * We might want to wake up the main thread under the lock. We * had a slightly similar situation in pthreadpool, changed -- 2.34.1