From: Adhemerval Zanella Date: Mon, 23 Aug 2021 17:09:23 +0000 (-0300) Subject: nptl: Use exit_lock when accessing TID on pthread_getcpuclockid X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71a2526d287a6146850ced2fbe3bbe31cb1e1512;p=thirdparty%2Fglibc.git nptl: Use exit_lock when accessing TID on pthread_getcpuclockid Also return EINVAL if the thread is already terminated at the time of the call. Checked on x86_64-linux-gnu. --- diff --git a/nptl/pthread_getcpuclockid.c b/nptl/pthread_getcpuclockid.c index 0cd9f77bea..f1141a6f92 100644 --- a/nptl/pthread_getcpuclockid.c +++ b/nptl/pthread_getcpuclockid.c @@ -16,11 +16,9 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, see . */ -#include -#include -#include -#include +#include #include +#include #include int @@ -28,17 +26,21 @@ __pthread_getcpuclockid (pthread_t threadid, clockid_t *clockid) { struct pthread *pd = (struct pthread *) threadid; - /* Make sure the descriptor is valid. */ - if (INVALID_TD_P (pd)) - /* Not a valid thread handle. */ - return ESRCH; + /* Block all signals, as required by pd->exit_lock. */ + internal_sigset_t old_mask; + internal_signal_block_all (&old_mask); + __libc_lock_lock (pd->exit_lock); - /* The clockid_t value is a simple computation from the TID. */ + int res = 0; + if (pd->tid ) + *clockid = make_thread_cpuclock (pd->tid, CPUCLOCK_SCHED); + else + res = EINVAL; - const clockid_t tidclock = make_thread_cpuclock (pd->tid, CPUCLOCK_SCHED); + __libc_lock_unlock (pd->exit_lock); + internal_signal_restore_set (&old_mask); - *clockid = tidclock; - return 0; + return res; } versioned_symbol (libc, __pthread_getcpuclockid, pthread_getcpuclockid, GLIBC_2_34); diff --git a/sysdeps/pthread/tst-pthread-exited.c b/sysdeps/pthread/tst-pthread-exited.c index 8997752528..c544ebc6be 100644 --- a/sysdeps/pthread/tst-pthread-exited.c +++ b/sysdeps/pthread/tst-pthread-exited.c @@ -23,6 +23,7 @@ #include #include #include +#include static void * noop_thread (void *closure) @@ -43,6 +44,12 @@ do_test (void) TEST_COMPARE (r, EINVAL); } + { + clockid_t clkid; + int r = pthread_getcpuclockid (thr, &clkid); + TEST_COMPARE (r, EINVAL); + } + xpthread_join (thr); return 0;