]> git.ipfire.org Git - thirdparty/glibc.git/commit
nptl: Avoid async cancellation to wrongly update __nptl_nthreads (BZ #19366)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 27 May 2021 15:42:13 +0000 (12:42 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 9 Jun 2021 18:16:45 +0000 (15:16 -0300)
commit8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b
tree5215532f194c1da7f1156d357a84c30bb29e4f24
parenta6c813d0ad0fd9830f2cd3c3d079af8d2aa50a1f
nptl: Avoid async cancellation to wrongly update __nptl_nthreads (BZ #19366)

The testcase provided on BZ#19366 may update __nptl_nthreads in a wrong
order, triggering an early process exit because the thread decrement
the value twice.

The issue is once the thread exits without acting on cancellation,
it decreaments '__nptl_nthreads' and then atomically set
 'cancelhandling' with EXITING_BIT (thus preventing further cancellation
handler to act).  The issue happens if a SIGCANCEL is received between
checking '__ntpl_nthreads' and setting EXITING_BIT.  To avoid it, the
'__nptl_nthreads' decrement is moved after EXITING_BIT.

It does fully follow the POSIX XSH 2.9.5 Thread Cancellation under
the heading Thread Cancellation Cleanup Handlers that states that
when a cancellation request is acted upon, or when a thread calls
pthread_exit(), the thread first disables cancellation by setting its
cancelability state to PTHREAD_CANCEL_DISABLE and its cancelability type
to PTHREAD_CANCEL_DEFERRED.  The issue is '__pthread_enable_asynccancel'
explicit enabled assynchrnous cancellation, so an interrupted syscall
within the cancellation cleanup handlers might see an invalid cancelling
type (a possible fix might be possible with my proposed solution to
BZ#12683).

Trying to come up with a test is quite hard since it requires to
mimic the timing issue described below, however I see that the
bug report reproducer does not early exit anymore.

Checked on x86_64-linux-gnu.
nptl/pthread_create.c