]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
nptl: Fix invalid Systemtap probe in pthread_join [BZ #24211]
authorFlorian Weimer <fweimer@redhat.com>
Fri, 15 Feb 2019 20:27:01 +0000 (21:27 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Fri, 15 Feb 2019 20:27:01 +0000 (21:27 +0100)
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
NEWS
nptl/pthread_join_common.c

index d363be46207f3677a9f7131216fc8e16db71595e..a6a0ce19ed96d3c177b7d4d5f410b20844ac9c4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2019-02-15  Florian Weimer  <fweimer@redhat.com>
+
+       [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  <fweimer@redhat.com>
 
        [BZ #24161]
diff --git a/NEWS b/NEWS
index dbcdd485020fccb15ba5f9993c2ebdbc401c286d..340e06d0f4fa8c6ecf42c098da27857c2242e6fe 100644 (file)
--- 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:
 
index ecb78ffba5861bdc91dfbc55e606b06f8182af97..366feb376beb86d63ba6b60561092eb5f66e0a4c 100644 (file)
@@ -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;
 }