diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-09-20 14:56:08 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-09-20 14:56:08 +0200 |
commit | 95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93 (patch) | |
tree | 0a20e738355959c33d3e61fc66bd07bf57845e0b /nptl | |
parent | a93d9e03a31ec14405cb3a09aa95413b67067380 (diff) | |
download | glibc-95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93.zip glibc-95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93.tar.gz glibc-95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93.tar.bz2 |
nptl: pthread_kill needs to return ESRCH for old programs (bug 19193)
The fix for bug 19193 breaks some old applications which appear
to use pthread_kill to probe if a thread is still running, something
that is not supported by POSIX.
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/pthread_kill.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c index fb7862e..a44dc8f 100644 --- a/nptl/pthread_kill.c +++ b/nptl/pthread_kill.c @@ -21,8 +21,11 @@ #include <pthreadP.h> #include <shlib-compat.h> -int -__pthread_kill_internal (pthread_t threadid, int signo) +/* Sends SIGNO to THREADID. If the thread is about to exit or has + already exited on the kernel side, return NO_TID. Otherwise return + 0 or an error code. */ +static int +__pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) { struct pthread *pd = (struct pthread *) threadid; if (pd == THREAD_SELF) @@ -52,11 +55,8 @@ __pthread_kill_internal (pthread_t threadid, int signo) signal is either not observable (the target thread has already blocked signals at this point), or it will fail, or it might be delivered to a new, unrelated thread that has reused the TID. - So do not actually send the signal. Do not report an error - because the threadid argument is still valid (the thread ID - lifetime has not ended), and ESRCH (for example) would be - misleading. */ - ret = 0; + So do not actually send the signal. */ + ret = no_tid; else { /* Using tgkill is a safety measure. pd->exit_lock ensures that @@ -72,6 +72,15 @@ __pthread_kill_internal (pthread_t threadid, int signo) } int +__pthread_kill_internal (pthread_t threadid, int signo) +{ + /* Do not report an error in the no-tid case because the threadid + argument is still valid (the thread ID lifetime has not ended), + and ESRCH (for example) would be misleading. */ + return __pthread_kill_implementation (threadid, signo, 0); +} + +int __pthread_kill (pthread_t threadid, int signo) { /* Disallow sending the signal we use for cancellation, timers, @@ -81,6 +90,7 @@ __pthread_kill (pthread_t threadid, int signo) return __pthread_kill_internal (threadid, signo); } + /* Some architectures (for instance arm) might pull raise through libgcc, so avoid the symbol version if it ends up being used on ld.so. */ #if !IS_IN(rtld) @@ -88,6 +98,17 @@ libc_hidden_def (__pthread_kill) versioned_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_34); # if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) -compat_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_0); +/* Variant which returns ESRCH in the no-TID case, for backwards + compatibility. */ +int +attribute_compat_text_section +__pthread_kill_esrch (pthread_t threadid, int signo) +{ + if (__is_internal_signal (signo)) + return EINVAL; + + return __pthread_kill_implementation (threadid, signo, ESRCH); +} +compat_symbol (libc, __pthread_kill_esrch, pthread_kill, GLIBC_2_0); # endif #endif |