Messages in this thread | | | Subject | Re: [regression] x86/signal/64: Fix SS handling for signals delivered to 64-bit programs breaks dosemu | From | Stas Sergeev <> | Date | Thu, 3 Sep 2015 00:01:03 +0300 |
| |
02.09.2015 22:06, Andy Lutomirski пишет: > On Wed, Sep 2, 2015 at 11:23 AM, Stas Sergeev <stsp@list.ru> wrote: >> 02.09.2015 21:17, Andy Lutomirski пишет: >>> On Wed, Sep 2, 2015 at 10:46 AM, Stas Sergeev <stsp@list.ru> 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?
| |