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

From: Stas Sergeev
Date: Wed Aug 12 2015 - 04:28:38 EST


12.08.2015 03:38, Andy Lutomirski ÐÐÑÐÑ:
On Tue, Aug 11, 2015 at 5:17 PM, Stas Sergeev <stsp@xxxxxxx> wrote:
Hi guys, I wonder how easily the include/uapi/* is being
changed these days.
The patch:
http://lkml.kernel.org/r/405594361340a2ec32f8e2b115c142df0e180d8e.1426193719.git.luto@xxxxxxxxxx
breaks dosemu (and perhaps everyone else who used
to restore the segregs by hands). And the fix involves
both autoconf magic and run-time magic, so it is not even
trivial.
I realize this patch may be good to have in general, but
breaking userspace without a single warning is a bit
discouraging. Seems like the old "we don't break userspace"
rule have gone.
I didn't anticipate any breakage. I could have been wrong.
You changed include/uapi/*, which is obviously an asking
for problems. I applied the following changes to my local
git tree to get dosemu working again:
https://github.com/stsp/dosemu2/commit/48b2a13a49a9fe1a456cd77df6b9a1feec675a01
https://github.com/stsp/dosemu2/commit/7898ac60d5e569964127d6cc48f592caecd20b81

Do you know what the actual breakage is? I'm curious how this ever
worked for DOSEMU, given that, before this patch, it appeared to be
impossible to return to any nonstandard SS from a 64-bit signal
handler.
This is not the point.
What dosemu wants is to simply save the DOS SS somewhere.
After your patch, it saves the Linux SS instead, then crashes.

FWIW, DOSEMU seems to work for me on recent kernels.
Do you have any protected mode DOS program to test?
I'll send you one in a private e-mail just about now.

We might still be able to require a new sigcontext flag to be set and
to forcibly return to __USER_DS if the flag is set regardless of the
ss value in sigcontext when sigreturn is called, if that is indeed the
problem with DOSEMU. But I'm not actually sure that that's the
problem.
Well, the flag would be an ideal solution in an ideal world,
but in our world I don't know the current relevance of dosemu,
and whether or not it worth a new flag to add.

In fact, DOSEMU contains this:

/* set up a frame to get back to DPMI via iret. The kernel does not save
%ss, and the SYSCALL instruction in sigreturn() destroys it.

IRET pops off everything in 64-bit mode even if the privilege
does not change which is nice, but clobbers the high 48 bits
of rsp if the DPMI client uses a 16-bit stack which is not so
nice (see EMUfailure.txt). Setting %rsp to 0x100000000 so that
bits 16-31 are zero works around this problem, as DPMI code
can't see bits 32-63 anyway.
*/

So, if DOSEMU were to realize that both sigreturnissues it's
complaining about are fixed in recent kernels, it could sigreturn
directly back to any state.
Good, but have you added any flag for dosemu to even know
it can do this? Unless I am mistaken, you didn't. So the fix you
suggest, is not easy to detect and make portable with the older
kernels. Any suggestions?

I don't actually see any code in DOSEMU that generates a sigcontext
It doesn't. But it manually pops the kernel-generated
sigcontext, see dpmisel.S:DPMI_direct_transfer.
This part didn't broke though, so no need to look there in fact.

from scratch (as opposed to copying one and modifying it), so I'm not
entirely sure what the problem is.
Now you have the changes I did to get it working, and I'll
also mail you a simple test-case. Let me know if you need
something else.
The more important question is whether we ignore dosemu
or some actions should be taken. Since you changed uapi/*,
my initial guess was that you opt for ignoring it, but maybe
this was not the point.
--
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/