diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-05-27 12:42:13 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-09 15:16:45 -0300 |
commit | 8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b (patch) | |
tree | 5215532f194c1da7f1156d357a84c30bb29e4f24 /sysdeps/unix/sysv/linux/x86 | |
parent | a6c813d0ad0fd9830f2cd3c3d079af8d2aa50a1f (diff) | |
download | glibc-8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b.tar.gz glibc-8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b.tar.xz glibc-8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b.zip |
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.
Diffstat (limited to 'sysdeps/unix/sysv/linux/x86')
0 files changed, 0 insertions, 0 deletions