summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2012-05-09 09:46:02 -0700
committerandroid code review <noreply-gerritcodereview@google.com>2012-05-09 09:46:02 -0700
commitfd95503347acba5c52d669a186ad2b161338a8a7 (patch)
tree19e15b19489d3b3031b11256aee077f29cb9cccc
parent3919b96eccb6d78f71f6d19b3ebfacec93cbca1f (diff)
parent0753dc653eb3b84d3490212437e7490975d4c020 (diff)
downloadbionic-fd95503347acba5c52d669a186ad2b161338a8a7.zip
bionic-fd95503347acba5c52d669a186ad2b161338a8a7.tar.gz
bionic-fd95503347acba5c52d669a186ad2b161338a8a7.tar.bz2
Merge "pthread: Invalidate stale stack pointers on pthread_exit()"
-rw-r--r--libc/bionic/pthread.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index f611a21..c075d51 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -576,6 +576,17 @@ void pthread_exit(void * retval)
_pthread_internal_remove(thread);
_pthread_internal_free(thread);
} else {
+ pthread_mutex_lock(&gThreadListLock);
+
+ /* make sure that the thread struct doesn't have stale pointers to a stack that
+ * will be unmapped after the exit call below.
+ */
+ if (!user_stack) {
+ thread->attr.stack_base = NULL;
+ thread->attr.stack_size = 0;
+ thread->tls = NULL;
+ }
+
/* the join_count field is used to store the number of threads waiting for
* the termination of this thread with pthread_join(),
*
@@ -588,7 +599,6 @@ void pthread_exit(void * retval)
* is gone (as well as its TLS area). when another thread calls pthread_join()
* on it, it will immediately free the thread and return.
*/
- pthread_mutex_lock(&gThreadListLock);
thread->return_value = retval;
if (thread->join_count > 0) {
pthread_cond_broadcast(&thread->join_cond);
@@ -1712,7 +1722,9 @@ int pthread_key_delete(pthread_key_t key)
* similarly, it is possible to have thr->tls == NULL for threads that
* were just recently created through pthread_create() but whose
* startup trampoline (__thread_entry) hasn't been run yet by the
- * scheduler. so check for this too.
+ * scheduler. thr->tls will also be NULL after it's stack has been
+ * unmapped but before the ongoing pthread_join() is finished.
+ * so check for this too.
*/
if (thr->join_count < 0 || !thr->tls)
continue;