From: Volker Lendecke Date: Fri, 10 Nov 2017 20:22:26 +0000 (+0100) Subject: tevent: Fix a race condition X-Git-Tag: samba-4.6.10~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a43b1b17902c8fbc319e13f31f6c9177f38371c;p=thirdparty%2Fsamba.git tevent: Fix a race condition We can't rely on tctx to exist after we unlocked the mutex. It took a while, but this does lead to data corruption. If *tctx is replaced with something where tctx->wakeup_fd points to a real, existing file descriptor, we're screwed. And by screwed, this means file corruption on disk. Again. I am not tall enough for this business. http://bholley.net/blog/2015/must-be-this-tall-to-write-multi-threaded-code.html BUG: https://bugzilla.samba.org/show_bug.cgi?id=13130 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Sat Nov 11 03:20:09 CET 2017 on sn-devel-144 (cherry picked from commit 20cfcb7dbc5dd099384b76a76e3d35cf627100b6) Autobuild-User(v4-6-test): Karolin Seeger Autobuild-Date(v4-6-test): Mon Nov 13 14:23:54 CET 2017 on sn-devel-144 --- diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c index 8197323af02..197ad1dfe41 100644 --- a/lib/tevent/tevent_threads.c +++ b/lib/tevent/tevent_threads.c @@ -434,7 +434,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, { #ifdef HAVE_PTHREAD struct tevent_context *ev; - int ret; + int ret, wakeup_fd; ret = pthread_mutex_lock(&tctx->event_ctx_mutex); if (ret != 0) { @@ -442,6 +442,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, } ev = tctx->event_ctx; + wakeup_fd = tctx->wakeup_fd; ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { @@ -489,7 +490,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, * than a noncontended one. So I'd opt for the lower footprint * initially. Maybe we have to change that later. */ - tevent_common_wakeup_fd(tctx->wakeup_fd); + tevent_common_wakeup_fd(wakeup_fd); #else /* * tevent_threaded_context_create() returned NULL with ENOSYS...