glibc/sysdeps/nptl
Adhemerval Zanella 5da15b15ad nptl: Do not use pthread set_tid_address as state synchronization (BZ #19951)
The use-after-free described in BZ#19951 is due to the use of two
different PD fields, 'joinid' and 'cancelhandling', to describe the
thread state and to synchronise the calls of pthread_join,
pthread_detach, pthread_exit, and normal thread exit.

Any state change may require checking both fields atomically to handle
partial state (e.g., pthread_join() with a cancellation handler to
issue a 'joinstate' field rollback).

This patch uses a different PD member with 4 possible states (JOINABLE,
DETACHED, EXITING, and EXITED) instead of the pthread 'tid' field, with
the following logic:

 1. On pthread_create, the initial state is set either to JOINABLE or
    DETACHED depending on the pthread attribute used.

 2. On pthread_detach, a CAS is issued on the state.  If the CAS fails,
    the thread is already detached (DETACHED) or being terminated (EXITING).
    For the former, an EINVAL is returned; for the latter, pthread_detach
    should be responsible for joining the thread (and for deallocating any
    internal resources).

 3. In the exit phase of the wrapper function for the thread start routine
    (reached either if the thread function has returned, pthread_exit has
    been called, or cancellation handled has been acted upon), we issue a
    CAS on state to set it to the EXITING mode.

    If the thread is previously in DETACHED mode, the thread is responsible
    for deallocating any resources; otherwise, the thread must be joined
    (detached threads cannot deallocate themselves immediately).

 4. The clear_tid_field on 'clone' call is changed to set the new 'state'
    field on thread exit (EXITED).  This state is only reached at thread
    termination.

 5. The pthread_join implementation is now simpler: the futex wait is done
    directly on thread state, and there is no need to reset it in case of
    timeout since the state is now set either by pthread_detach() or by the
    kernel on process termination.

The race condition on pthread_detach is avoided with a single atomic
operation on the PD state: once the mode is set to THREAD_STATE_DETACHED, it
is up to the thread itself to deallocate its memory (done during the exit
phase at pthread_create()).

Also, the INVALID_NOT_TERMINATED_TD_P is removed since a negative yid is
not possible, and the macro is not used anywhere.

This change triggers an invalid C11 thread test: it creates a thread that
detaches, and after a timeout, the creating thread checks whether the join
fails.  The issue is that once thrd_join() is called, the thread's lifetime
is not defined.

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
arm-linux-gnueabihf, and powerpc64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-12-19 13:23:05 -03:00
..
bits Remove support for lock elision. 2025-11-18 14:21:13 +01:00
sys Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
Implies
Makeconfig Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
Makefile Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
Subdirs
_Fork.c Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
aio_misc.h aio_suspend64: Fix clock discrepancy [BZ #32795] 2025-03-25 01:05:11 +01:00
c11-thread.h htl: move c11 symbols into libc. 2025-11-22 03:28:48 +01:00
cancellation-pc-check.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
dl-mutex.c Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
dl-thread_gscope_wait.c Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
dl-tls_init_tp.c nptl: Do not use pthread set_tid_address as state synchronization (BZ #19951) 2025-12-19 13:23:05 -03:00
dl-tunables.list Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
fork.h nptl: Add support for setup guard pages with MADV_GUARD_INSTALL 2025-01-30 10:16:37 -03:00
futex-internal.h Remove futex_supports_pshared 2025-09-08 15:01:18 +02:00
gai_misc.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
internaltypes.h Use 64-bit atomic on sem_t with 8-byte alignment [BZ #33632] 2025-12-02 06:50:49 +08:00
jmp-unwind.c Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
libc-lock.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
libc-lockP.h htl: Drop pthread-functions infrastructure 2025-11-13 23:23:13 +01:00
libc_start_call_main.h nptl: Do not use pthread set_tid_address as state synchronization (BZ #19951) 2025-12-19 13:23:05 -03:00
lowlevellock-futex.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
lowlevellock.h Remove support for lock elision. 2025-11-18 14:21:13 +01:00
malloc-machine.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
proc_service.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
pthread-offsets.h nptl: update default pthread-offsets.h 2020-02-10 17:01:21 +01:00
pthread.h nptl: PTHREAD_COND_INITIALIZER compatibility with pre-2.41 versions (bug 32786) 2025-03-13 07:43:33 +01:00
pthreadP.h nptl: Do not use pthread set_tid_address as state synchronization (BZ #19951) 2025-12-19 13:23:05 -03:00
pthread_atfork_compat.h Consolidate pthread_atfork 2021-06-24 10:04:41 -03:00
pthread_early_init.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
pthread_mutex_backoff.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
pthread_mutex_conf.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
rseq-access.h atomic: Reinstate HAVE_64B_ATOMICS configure check 2025-12-17 22:57:00 +00:00
setxid.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
stdio-lock.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
tcb-access.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
tcb-offsets.h
thread_db.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
timer_routines.h Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
tst-mqueue8x.c