On Sun, Jan 31, 2016 at 9:33 AM, Stas Sergeev <stsp@xxxxxxx> wrote:I think you are quoting the discription of the "oss" struct,
31.01.2016 20:00, Andy Lutomirski ÐÐÑÐÑ:POSIX says nothing about temporary anything. It says:
On Sun, Jan 31, 2016 at 8:28 AM, Stas Sergeev <stsp@xxxxxxx> wrote:To me, the main advantage is to stay POSIX-compatible, rather
linux implements the sigaltstack() in a way that makes it impossible toThis seems considerably more complicated than my previous proposal to
use with swapcontext(). Per the man page, sigaltstack is allowed to
return
EPERM if the process is altering its sigaltstack while running on
sigaltstack.
This is likely needed to consistently return oss->ss_flags, that
indicates
whether the process is being on sigaltstack or not.
Unfortunately, linux takes that permission to return EPERM too literally:
it returns EPERM even if you don't want to change to another sigaltstack,
but only want to temporarily disable sigaltstack with SS_DISABLE.
You can't use swapcontext() without disabling sigaltstack first, or the
stack will be re-used and overwritten by a subsequent signal.
With this patch, disabling sigaltstack inside a signal handler became
possible, and the swapcontext() can then be used safely. After switching
back to the sighandler, the app can re-enable the sigatlstack.
The oss->ss_flags will correctly indicate the current use of sigaltstack,
even if it is temporarily disabled. Any attempt to modify the sigaltstack
(rather than to disable or re-enable it) within the sighandler, will
still
be punished with EPERM as suggested by POSIX.
add an SS_FORCE flag to say "I know what I'm doing. Ignore POSIX and
let me change the sigaltstack configuration even if it's in use".
What's the advantage?
than adding the linux-specific flag. Please note that this flag does
not add any value other than to say "I want to ignore POSIX here"
in your interpretation of POSIX, and in my interpretation it doesn't
say even this, because in my interpretation the temporary disabling
is not prohibited.
SS_ONSTACK The process is currently executing on the alternate signal
stack. Attempts to modify the alternate signal stack while
the process is executing on it fail. This flag shall not be
modified by processes.
It's a bit ambiguous because "Attempts to modify the alternate signal
stack while the process is executing on it fail." is under SS_ONSTACK,
so it's not quite clear whether SS_DISABLE is *also* supposed to fail
if on the stack.
Likely not.So if it doesn't even fit my interpretation, how wouldWhat do other operating systems do here? You might be stuck with
I write a man description for it? I'll have to first clarify the vague
wording to clearly sound your way, and then add the flag to override
this. This whole procedure looks very illogical to me. So to find out
if it is just me, I'd like to hear from anyone else supporting the idea
of adding this flag. If people think its existence is justified, then fine.
But to me this flag is non-portable, while the both sigaltstack() and
swapcontext() are portable. So what will I gain with adding a
non-portable flag to my apps? A bunch of ifdefs?
IMHO as long as both swapcontext() and sigaltstack() are POSIX-compatible,
they should be compatible with each other in a POSIX-compatible
way. If POSIX needs the linux-specific flags to make them compatible
with each other, then POSIX is inconsistent. So lets just don't interpret
it the way that makes it so.
Linux-specific code here no matter what. If you're causing Linux to
match FreeBSD, that's a different store.
With inline asm or register variable, not good for portability.So in short:An app can figure out if it's on the altstack the same way the kernel
Your concern is the patch complexity. Doing things your way will
however move the problem to the user: he will have to deal with the
linux-specific flags and add ifdefs for just a mere use of a
posix-compatible
interfaces.
There can also be the subtle technical differences.
With your approach the nested signal can AFAIU overflow the
the disabled sigaltstack because you don't maintain the oss->ss_flags
in a consistent way. There is an overflow protection code:
---
/*
* If we are on the alternate signal stack and would overflow it, don't.
* Return an always-bogus address instead so we will die with SIGSEGV.
*/
if (onsigstack && !likely(on_sig_stack(sp)))
return (void __user *)-1L;
---
In your approach it will be bypassed.
And its not possible for an app to find out if it is running on a
sigaltstack now or not, after it is disabled.
does.
In fact, the app needs to be quite careful with this temporaryMy test-case code simply does this in sighandler:
disable thing. If you temporarily disable sigaltstack, then
swapcontext, then you need to keep track of exactly when you're
supposed to re-enable it, which involves knowing what's going on with
the stacks.
Also, consider a use case like yours but with *two* contexts that useOf course the good practice is to set the sigaltstack
their own altstack. If you go to context A, enable sigaltstack, get a
signal, temporarily disable, then swapcontext to B, which tries to
re-enable its own sigaltstack, then everything gets confusing with
your patch, because, with your patch, the kernel is only tracking one
temporarily disabled sigaltstack.
So that's another argument in favor of my thought that there shouldOk so if you block this approach, I wonder how many people
just be a way to override the permission checks to turn sigaltstack
all the way off or to reprogram it even if you're running on the
altstack.