diff options
author | Rich Felker <dalias@aerifal.cx> | 2022-11-05 18:53:11 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2022-11-05 18:59:53 -0400 |
commit | ad5dcd398b9509cf43672e3a7f02c4b18035998c (patch) | |
tree | 2f7681f04bac40fa57ad2c03d65bb3cebf5de247 | |
parent | 8f9259450aa43a6fd539e428e61e2961b725fbae (diff) | |
download | musl-ad5dcd398b9509cf43672e3a7f02c4b18035998c.tar.gz musl-ad5dcd398b9509cf43672e3a7f02c4b18035998c.tar.xz musl-ad5dcd398b9509cf43672e3a7f02c4b18035998c.zip |
fix async thread cancellation stack alignment
if async cancellation is enabled and acted upon, the stack pointer is not necessarily pointing to a __syscall_cp_asm stack frame. the contents of the stack being wrong don't really matter, but if the stack pointer is not suitably aligned, the procedure call ABI is violated when calling back into C code via __cancel, and pthread_exit, cancellation cleanup handlers, TSD destructors, etc. may malfunction or crash. for the async cancel case, just call __cancel directly like we did prior to commit 102f6a01e249ce4495f1119ae6d963a2a4a53ce5. restore the signal mask prior to doing this since the cancellation handler runs with all signals blocked.
-rw-r--r-- | src/thread/pthread_cancel.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c index 2d3a98ea..139a6fc8 100644 --- a/src/thread/pthread_cancel.c +++ b/src/thread/pthread_cancel.c @@ -56,7 +56,12 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) _sigaddset(&uc->uc_sigmask, SIGCANCEL); - if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) { + if (self->cancelasync) { + pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0); + __cancel(); + } + + if (pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) { uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel; #ifdef CANCEL_GOT uc->uc_mcontext.MC_GOT = CANCEL_GOT; |