From 101fb7d963ed362c4e351d95e55cbd70dc59eac3 Mon Sep 17 00:00:00 2001
From: Christopher Ferris <cferris@google.com>
Date: Fri, 6 Dec 2013 18:54:48 -0800
Subject: [PATCH] Do not clear tids on detached threads.

Make sure that the kernel isn't going to try and clear the tid of
freed memory.

Bug: 11963327
Change-Id: I95d02340bfbe92f56036d2cc58dbf0e3079eb7c3
---
 libc/bionic/pthread_exit.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 22c2c3c1d..c1140de9d 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -36,6 +36,7 @@
 
 extern "C" void _exit_with_stack_teardown(void*, size_t, int);
 extern "C" void __exit(int);
+extern "C" int __set_tid_address(int*);
 
 /* CAVEAT: our implementation of pthread_cleanup_push/pop doesn't support C++ exceptions
  *         and thread cancelation
@@ -94,6 +95,9 @@ void pthread_exit(void* return_value) {
   pthread_mutex_lock(&gThreadListLock);
   if ((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) != 0) {
     // The thread is detached, so we can destroy the pthread_internal_t.
+    // First make sure that the thread does not try to clear the tid since
+    // it points into memory that will be freed.
+    __set_tid_address(NULL);
     _pthread_internal_remove_locked(thread);
   } else {
     // Make sure that the pthread_internal_t doesn't have stale pointers to a stack that