Re: [regression] x86/signal/64: Fix SS handling for signals delivered to 64-bit programs breaks dosemu

From: Stas Sergeev
Date: Wed Sep 02 2015 - 18:57:02 EST


03.09.2015 01:25, Andy Lutomirski ÐÐÑÐÑ:
On Wed, Sep 2, 2015 at 3:25 PM, Stas Sergeev <stsp@xxxxxxx> wrote:

How dosemu2 is supposed to do this:
1. sigreturn() (to DOS)
2. siglongjmp() (to 64bit C-coded)
This should work fine on any kernel, right?
1 - not.
2 - maybe.
If, as you say, siglongjmp() restores SS, I need to try it out.
(there is also a problem that most siglongjmp() implementations
are incompatible with sigaltstack(), but this is not what you can fix).

1 - definitely needs kernel changes. I was referring to #2.

2 - siglongjmp probably varies in its behavior across different libc
implementations. My point is that siglongjmp isn't a kernel-provided
thing.
So if siglongjmp() restores SS by the side-effect of doing a sigprocmask()
syscall, this admittedly weakens my point.
The unreliability then stays only with the async signals interrupting
the main one.

For backwards compat, we either need the default behavior to be
unchanged, or we need the default behavior to be something that works
with existing dosemu. For existing dosemu, the only interesting cases
(I think) are signal delivery from *valid* 16-bit context, in which
case we need to preserve SS so that the signal handler can read it out
with mov ..., %ss, and sigreturn to 64-bit mode for the IRET
trampoline. For sigreturn, IIUC old dosemu will replace the saved CS
with a 64-bit code segment selector and won't touch the saved SS
because it doesn't know about the saved SS. Those dosemu versions
don't care what SS actually contains after sigreturn, because they're
immediately going to change it again using IRET. So we just need to
make sure we return without faulting.

New dosemu2 would like to sigreturn directly back to 16-bit mode, so
it needs the kernel to honor the saved ss value and restore it,
possibly changed by dosemu.

We obviously can't require old dosemu to set an SA flag to keep
working. But, if we can get away with it, I think it's somewhat
preferable not to require new DOSEMU to set an SA flag either.

This has one major benefit at least: if new dosemu loads some random
library that installs some async signal handler (SIGALRM for example),
everything will work with regard to CS and SS.
This case is covered if we do both things together: use
your heuristic when SA_hyz is not set, and don't use it
when its set. In this case dosemu2 will be able to request
the proper SS delivery for its sighandlers, but the 3rd-party
sighandlers will work too.
I think we have never discussed the possibility of doing
both things together, even though I have proposed it many
times.
After discussing this full-blown solution, we can think about
reducing it, either by removing the heuristic or by removing
SA_hyz, but discussing the full one would be nice too.
Your opinion is likely that no one will use this SA_hyz in
presence of the heuristic that "seems to work anyway".
But in the light of extending it for TLS (with a new flag),
I wouldn't be so sure. You can also document it as a
needed flag when user code touches SS, and then it will
be used. dosemu1 code that doesn't use it, will eventually
be forgotten. So IMHO whether it will be used, is fully up
to how will you market it. :)
I'll think about it. I'll think about FS and GS, too,
OK, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/