diff options
author | Mathis Beer <Mathis.Beer@funkwerk-itk.com> | 2020-03-12 06:37:05 +0100 |
---|---|---|
committer | Mathis Beer <Mathis.Beer@funkwerk-itk.com> | 2020-03-12 06:49:29 +0100 |
commit | a12ca58dfa4db8de1045117c8994b423a9802da4 (patch) | |
tree | 1e665380b2a17c8da4f4dd4aac364c82e3dd370e | |
parent | b4dea2ef9b529e2a7fb8619d68f0830ff957d3de (diff) | |
download | libfaketime-a12ca58dfa4db8de1045117c8994b423a9802da4.tar.gz |
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.
-rw-r--r-- | src/libfaketime.c | 8 |
1 files 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 |