From a12ca58dfa4db8de1045117c8994b423a9802da4 Mon Sep 17 00:00:00 2001 From: Mathis Beer Date: Thu, 12 Mar 2020 06:37:05 +0100 Subject: [PATCH] fix threading issue: don't assign to the global lock state struct until we're safely inside the mutex. Otherwise, we might be overwriting the global lock state from two different threads at once. --- src/libfaketime.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libfaketime.c b/src/libfaketime.c index 17ebaa2..c259240 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -2636,8 +2636,9 @@ struct LockedState { static void pthread_cleanup_mutex_lock(void *data) { struct LockedState *state = data; + sigset_t original_mask = state->original_mask; // inside the lock! pthread_mutex_unlock(&state->mutex); - pthread_sigmask(SIG_SETMASK, &state->original_mask, NULL); + pthread_sigmask(SIG_SETMASK, &original_mask, NULL); } #endif @@ -2673,10 +2674,11 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp) static struct LockedState state = { 0 }; // block all signals while locked. prevents deadlocks if signal interrupts in in mid-operation. - sigset_t all_signals; + sigset_t all_signals, original_mask; sigfillset(&all_signals); - pthread_sigmask(SIG_SETMASK, &all_signals, &state.original_mask); + pthread_sigmask(SIG_SETMASK, &all_signals, &original_mask); pthread_mutex_lock(&state.mutex); + state.original_mask = original_mask; // inside the lock! pthread_cleanup_push(pthread_cleanup_mutex_lock, &state); #endif