From 067fc32968b601493f4b247a3ac00caeea3f3d61 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 15 Feb 2019 21:27:01 +0100 Subject: [PATCH 06] nptl: Fix invalid Systemtap probe in pthread_join [BZ #24211] After commit f1ac7455831546e5dca0ed98fe8af2686fae7ce6 ("arm: Use "nr" constraint for Systemtap probes [BZ #24164]"), we load pd->result into a register in the probe below: /* Free the TCB. */ __free_tcb (pd); } else pd->joinid = NULL; LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result); However, at this point, the thread descriptor has been freed. If the thread stack does not fit into the thread stack cache, the memory will have been unmapped, and the program will crash in the probe. (cherry picked from commit bc10e22c90e42613bd5dafb77b80a9ea1759dd1b) --- ChangeLog | 6 ++++++ NEWS | 1 + nptl/pthread_join_common.c | 5 +++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d363be4620..a6a0ce19ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2019-02-15 Florian Weimer + + [BZ #24211] + * nptl/pthread_join_common.c (__pthread_timedjoin_ex): Do not read + pd->result after the thread descriptor has been freed. + 2019-02-08 Florian Weimer [BZ #24161] diff --git a/NEWS b/NEWS index dbcdd48502..340e06d0f4 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ The following bugs are resolved with this release: [24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309) [24164] Systemtap probes need to use "nr" constraint on 32-bit Arm [24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2 + [24211] Use-after-free in Systemtap probe in pthread_join Security related changes: diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c index ecb78ffba5..366feb376b 100644 --- a/nptl/pthread_join_common.c +++ b/nptl/pthread_join_common.c @@ -86,6 +86,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, pthread_cleanup_pop (0); } + void *pd_result = pd->result; if (__glibc_likely (result == 0)) { /* We mark the thread as terminated and as joined. */ @@ -93,7 +94,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, /* Store the return value if the caller is interested. */ if (thread_return != NULL) - *thread_return = pd->result; + *thread_return = pd_result; /* Free the TCB. */ __free_tcb (pd); @@ -101,7 +102,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, else pd->joinid = NULL; - LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result); + LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd_result); return result; }