pthread: Invalidate stale stack pointers on pthread_exit()
A call to pthread_key_delete() after pthread_exit() have unmapped the stack of a thread but before the ongoing pthread_join() have finished executing will result in an access to unmapped memory. Avoid this by invalidating the stack_base and tls pointers during pthread_exit(). This is based on the investigation and proprosed solution by Srinavasa Nagaraju <srinavasa.x.nagaraju@sonyericsson.com> Change-Id: I145fb5d57930e91b00f1609d7b2cd16a55d5b3a9
This commit is contained in:
parent
3919b96ecc
commit
0753dc653e
@ -576,6 +576,17 @@ void pthread_exit(void * retval)
|
|||||||
_pthread_internal_remove(thread);
|
_pthread_internal_remove(thread);
|
||||||
_pthread_internal_free(thread);
|
_pthread_internal_free(thread);
|
||||||
} else {
|
} 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 join_count field is used to store the number of threads waiting for
|
||||||
* the termination of this thread with pthread_join(),
|
* 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()
|
* is gone (as well as its TLS area). when another thread calls pthread_join()
|
||||||
* on it, it will immediately free the thread and return.
|
* on it, it will immediately free the thread and return.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&gThreadListLock);
|
|
||||||
thread->return_value = retval;
|
thread->return_value = retval;
|
||||||
if (thread->join_count > 0) {
|
if (thread->join_count > 0) {
|
||||||
pthread_cond_broadcast(&thread->join_cond);
|
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
|
* similarly, it is possible to have thr->tls == NULL for threads that
|
||||||
* were just recently created through pthread_create() but whose
|
* were just recently created through pthread_create() but whose
|
||||||
* startup trampoline (__thread_entry) hasn't been run yet by the
|
* 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)
|
if (thr->join_count < 0 || !thr->tls)
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user