about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-08-20 12:24:49 -0400
committerRich Felker <dalias@aerifal.cx>2022-08-20 12:24:49 -0400
commit2e5fff43dd7fc808197744c67cca7908ac19bb4f (patch)
treee62bcaa00019889aa5fa574a71336b364934c7f7 /src
parent379b18218d18a049b5423bbb9bb22e066ffc3f78 (diff)
downloadmusl-2e5fff43dd7fc808197744c67cca7908ac19bb4f.tar.gz
musl-2e5fff43dd7fc808197744c67cca7908ac19bb4f.tar.xz
musl-2e5fff43dd7fc808197744c67cca7908ac19bb4f.zip
use alt signal stack when present for implementation-internal signals
a request for this behavior has been open for a long time. the
motivation is that application code, particularly under some language
runtimes designed around very-low-footprint coroutine type constructs,
may be operating with extremely small stack sizes unsuitable for
receiving signals, using a separate signal stack for any signals it
might handle.

progress on this was blocked at one point trying to determine whether
the implementation is actually entitled to clobber the alt stack, but
the phrasing "available to the implementation" in the POSIX spec for
sigaltstack seems to make it clear that the application cannot rely on
the contents of this memory to be preserved in the absence of signal
delivery (on the abstract machine, excluding implementation-internal
signals) and that we can therefore use it for delivery of signals that
"don't exist" on the abstract machine.

no change is made for SIGTIMER since it is always blocked when used,
and accepted via sigwaitinfo rather than execution of the signal
handler.
Diffstat (limited to 'src')
-rw-r--r--src/linux/membarrier.c2
-rw-r--r--src/thread/pthread_cancel.c2
-rw-r--r--src/thread/synccall.c2
3 files changed, 3 insertions, 3 deletions
diff --git a/src/linux/membarrier.c b/src/linux/membarrier.c
index 343f7360..f64fe7e1 100644
--- a/src/linux/membarrier.c
+++ b/src/linux/membarrier.c
@@ -35,7 +35,7 @@ int __membarrier(int cmd, int flags)
 		__tl_lock();
 		sem_init(&barrier_sem, 0, 0);
 		struct sigaction sa = {
-			.sa_flags = SA_RESTART,
+			.sa_flags = SA_RESTART | SA_ONSTACK,
 			.sa_handler = bcast_barrier
 		};
 		memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
index 2f9d5e97..2d3a98ea 100644
--- a/src/thread/pthread_cancel.c
+++ b/src/thread/pthread_cancel.c
@@ -77,7 +77,7 @@ void __testcancel()
 static void init_cancellation()
 {
 	struct sigaction sa = {
-		.sa_flags = SA_SIGINFO | SA_RESTART,
+		.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK,
 		.sa_sigaction = cancel_handler
 	};
 	memset(&sa.sa_mask, -1, _NSIG/8);
diff --git a/src/thread/synccall.c b/src/thread/synccall.c
index d58c851f..a6b177c0 100644
--- a/src/thread/synccall.c
+++ b/src/thread/synccall.c
@@ -45,7 +45,7 @@ void __synccall(void (*func)(void *), void *ctx)
 {
 	sigset_t oldmask;
 	int cs, i, r;
-	struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
+	struct sigaction sa = { .sa_flags = SA_RESTART | SA_ONSTACK, .sa_handler = handler };
 	pthread_t self = __pthread_self(), td;
 	int count = 0;