Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Tue, 5 Mar 2019 10:57:19 -0500
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: sigaltstack for implementation-internal signals?

It came up recently that some erlang component is doing awful hacks
(see https://twitter.com/RichFelker/status/1099816400036773888) to try
to get implementation-internal signals to run on the alternate stack
setup by sigaltstack instead of the main stack. This desire makes some
sense, as they have tons of really tiny stacks and for their
coroutine-like things that rapidly context-switch in userspace. And
since there's no portable or valid way to do this hack, it raised the
issue for me: should we just always deliver implementation-internal
signals on the alternate stack if it's setup?

Unfortunateley I don't think this is possible/safe, for reasons
related to how the kernel's signal frame setup works. When a signal is
delivered and is to be handled on the alt stack, Linux checks whether
the current stack pointer is already on the alt stack. If so, it
decrements it normally; if not, it sets the stack pointer to the
beginning of the alt stack. The first case is needed in case a signal
interrupts a signal handler already running on the alt stack; if it
weren't handled that way, the second one would clobber the first one's
state, and upon return Bad Things would happen.

Unfortunately, this can go wrong. Suppose the application's signal
handler running on the alt stack changes the stack pointer to
something off the alt stack -- for example, using swapcontext, or some
awful split-stack hack. This is known to be "unsafe" in general, and
was the motivation for the (problematic with respect to POSIX, but
fixed in http://austingroupbugs.net/view.php?id=1187) addition of
SS_AUTODISARM. However, in principle it was "already safe" (without
SS_AUTODISARM) to use swapcontext with sigaltstack if the signal
handler and swapped-to context kept all SA_ONSTACK-flagged signals
blocked for their duration. An application could clearly arrange for
this; for example it's fairly natural if you only use one signal
handler that's SA_ONSTACK.

If we add unblockable, implementation-internal signals that are
flagged SA_ONSTACK, however, this breaks; now even if an application
has taken the "proper precautions", they can be delivered in a state
where the alt stack is nonempty but the stack pointer doesn't point
into it, thereby causing it to get clobbered.

Perhaps there's a chance that this just isn't supported/valid usage,
that "leaving the alt stack" should always be seen as abandoning it,
and that anything that worked before to preserve it was "just by
mistake/luck".

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.