diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-04-17 17:06:05 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-04-17 17:06:05 -0400 |
commit | 1ebde9c3a228e8daa4bdba98046556b4b6829f5e (patch) | |
tree | 61ed4895a116fae89024e73079618a904fb05958 | |
parent | 9080cc153cc2b09881c3245becbd68534db18d7c (diff) | |
download | musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.tar.gz musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.tar.xz musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.zip |
fix pthread_exit from cancellation handler
cancellation frames were not correctly popped, so this usage would not only loop, but also reuse discarded and invalid parts of the stack.
-rw-r--r-- | src/thread/pthread_create.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 8e3a4a26..c6a23955 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -18,12 +18,13 @@ weak_alias(dummy_1, __pthread_tsd_run_dtors); void __pthread_unwind_next(struct __ptcb *cb) { - pthread_t self; + pthread_t self = pthread_self(); int n; - if (cb->__next) longjmp((void *)cb->__next->__jb, 1); - - self = pthread_self(); + if (cb->__next) { + self->cancelbuf = cb->__next->__next; + longjmp((void *)cb->__next->__jb, 1); + } LOCK(&self->exitlock); @@ -104,7 +105,6 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo new->detached = attr->_a_detach; new->attr = *attr; new->unblock_cancel = self->cancel; - new->result = PTHREAD_CANCELED; memcpy(new->tlsdesc, self->tlsdesc, sizeof new->tlsdesc); new->tlsdesc[1] = (uintptr_t)new; stack = (void *)((uintptr_t)new-1 & ~(uintptr_t)15); |