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 - 16:56:33 EST


02.09.2015 22:06, Andy Lutomirski ÐÐÑÐÑ:
On Wed, Sep 2, 2015 at 11:23 AM, Stas Sergeev <stsp@xxxxxxx> wrote:
02.09.2015 21:17, Andy Lutomirski ÐÐÑÐÑ:
On Wed, Sep 2, 2015 at 10:46 AM, Stas Sergeev <stsp@xxxxxxx> wrote:
02.09.2015 17:21, Andy Lutomirski ÐÐÑÐÑ:
This should work for old DOSEMU. It's a bit gross, but it has the
nice benefit that everyone (even things that aren't DOSEMU) gain the
ability to catch signals thrown from bogus SS contexts, which probably
improves debugability. It's also nice to not have the SA flag.
Pros:
- No new SA flag
- May improve debugability in some unknown scenario where people
do not want to just use the new flag to get their things improved

Cons:
- Does not allow to cleanly use siglongjmp(), as then there is a risk
to jump to 64bit code with bad SS
What's the issue here? I don't understand.

On musl, (sig)longjmp just restores rsp, rbx, rbp, and r12-r15, so it
won't be affected. AFAIK all implementations of siglongjmp are likely
to call sigprocmask or similar, and that will clobber SS. I'm not
aware of an implementation of siglongjmp that uses sigreturn.
I am not saying siglongjmp() will be affected.
Quite the opposite: it won't, which is bad. :)
If you have always correct SS, you can use siglongjmp(). If you have
broken SS at times, siglongjmp() will be an asking for troubles, as
it exactly does not restore SS.
dosemu could do a good use of siglongjmp() to get back to 64bit code
from its sighandler.
This seems like it would be relying unpleasantly heavily on libc internals.
Could you please clarify?
If kernel always passes the right SS to the sighandler, then what's
the problem?
What's the exact siglongjmp usage you have in mind? Signal context
isn't normally involved AFAIK.
dosemu needs 2 return pathes:
1. to DOS code
2. to 64bit code (dosemu is not all in a sighandler, right?)

How it is currently achieved:
dosemu1:
1. sigreturn() + iret (to DOS)
2. modify sigcontext -> sigreturn() (to 64bit asm helper)

dosemu2:
1. sigreturn() + iret (to DOS)
2. modify sigcontext -> sigreturn() -> longjmp() (to 64bit C-coded)

How dosemu2 is supposed to do this:
1. sigreturn() (to DOS)
2. siglongjmp() (to 64bit C-coded)

- Async signals can silently "validate" SS behind your back
True, and that's unfortunate. But async signals without SA_SAVE_SS
set with the other approach have exactly the same problem.
Yes, and as such, they should be blocked.
You could improve on that and on siglongjmp().
And on TLS in the future.
*I* can't do anything to siglongjmp because that's almost entirely
outside the kernel. :-/
Except for passing the SS=__USER_DS to the sighandler, for which we
discussed the new SA_hyz?
I'm still not understanding what you're looking for. If you
siglongjmp out of a signal handler, the hardware SS value is
irrelevant, at least on 64-bit binaries, because siglongjmp is just
going to replace it.
Hmm? IIRC you've just said this:
---
On musl, (sig)longjmp just restores rsp, rbx, rbp, and r12-r15, so it won't be affected.
---
So why would siglongjmp() replace it?

Is the new SA flag such a big deal here to even bother?
Not really, but given that the new behavior seems clearly better
behaved than the old, it would be nice to be able to have the good
behavior, or at least most of it, be the default.
Surely, but how about then having the heuristics you suggest,
only if the new SA_hyz is not set? And when it is set, have a
properly defined and predictable behaviour. Then it seems like
we'll get all the possible wishes covered.
That could work. The result is quite similar to explicitly setting
UC_STRICT_RESTORE_SS.
I am much more bothered with delivering the right SS than with
restoring it on sigreturn().
For 64-bit delivery, ignoring backwards compatibility, delivering
signals with ss = __USER_DS would be the right solution, I think: it's
trivial and it works. Because of backwards compatibility, we need to
... add the SA_hyz flag.
I don't understand why do you constantly ignore that part as
if it was never spelled. Lets discuss the proposal as a whole, rather
than with the random bits thrown away. The flag is exactly for
backward compatibility, so why do you present it as a problem
without the context of the new flag?
--
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/