diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-09-13 11:06:08 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-09-13 11:06:08 +0200 |
commit | 526c3cf11ee9367344b6b15d669e4c3cb461a2be (patch) | |
tree | 428aa0c50880ee5001732622b0afe94ba7e113d9 /nptl/pthread_create.c | |
parent | 8af8456004edbab71f8903a60a3cae442cf6fe69 (diff) | |
download | glibc-526c3cf11ee9367344b6b15d669e4c3cb461a2be.tar.gz glibc-526c3cf11ee9367344b6b15d669e4c3cb461a2be.tar.xz glibc-526c3cf11ee9367344b6b15d669e4c3cb461a2be.zip |
nptl: Fix race between pthread_kill and thread exit (bug 12889)
A new thread exit lock and flag are introduced. They are used to detect that the thread is about to exit or has exited in __pthread_kill_internal, and the signal is not sent in this case. The test sysdeps/pthread/tst-pthread_cancel-select-loop.c is derived from a downstream test originally written by Marek Polacek. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'nptl/pthread_create.c')
-rw-r--r-- | nptl/pthread_create.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 7607f36e26..a559f86cc2 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -36,6 +36,7 @@ #include <sys/single_threaded.h> #include <version.h> #include <clone_internal.h> +#include <futex-internal.h> #include <shlib-compat.h> @@ -484,6 +485,19 @@ start_thread (void *arg) /* This was the last thread. */ exit (0); + /* This prevents sending a signal from this thread to itself during + its final stages. This must come after the exit call above + because atexit handlers must not run with signals blocked. */ + __libc_signal_block_all (NULL); + + /* Tell __pthread_kill_internal that this thread is about to exit. + If there is a __pthread_kill_internal in progress, this delays + the thread exit until the signal has been queued by the kernel + (so that the TID used to send it remains valid). */ + __libc_lock_lock (pd->exit_lock); + pd->exiting = true; + __libc_lock_unlock (pd->exit_lock); + #ifndef __ASSUME_SET_ROBUST_LIST /* If this thread has any robust mutexes locked, handle them now. */ # if __PTHREAD_MUTEX_HAVE_PREV |