diff options
author | Volker Lendecke <vl@samba.org> | 2017-11-10 21:22:26 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2017-11-11 03:20:09 +0100 |
commit | 20cfcb7dbc5dd099384b76a76e3d35cf627100b6 (patch) | |
tree | 00d93e595d0cc63f72b2ee6c420dd72db30b8b31 /lib | |
parent | 71720e2e9c414f8ae823a5c6cfa624a4d8683926 (diff) | |
download | samba-20cfcb7dbc5dd099384b76a76e3d35cf627100b6.tar.gz |
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 <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Nov 11 03:20:09 CET 2017 on sn-devel-144
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tevent/tevent_threads.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c index 4d1a8805181..2e83f1b66c2 100644 --- a/lib/tevent/tevent_threads.c +++ b/lib/tevent/tevent_threads.c @@ -451,7 +451,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) { @@ -495,6 +495,8 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, abort(); } + wakeup_fd = tctx->wakeup_fd; + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); if (ret != 0) { abort(); @@ -510,7 +512,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... |