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

From: Ingo Molnar
Date: Sat Aug 22 2015 - 08:38:36 EST



* Andy Lutomirski <luto@xxxxxxxxxxxxxx> wrote:

> > The crash happens when DOS program terminates.
> > At that point dosemu subverts the execution flow by
> > replacing segregs and cs/ip ss/sp in sigcontext with its own.
> > But __pad0 still has DOS SS, which crash because (presumably)
> > the DOS LDT have been just removed.
>
> That's unfortunate.
>
> I don't really know what to do about this. My stupid heuristic for
> signal delivery seems unlikely to cause problems, but I'm not coming
> up with a great heuristic for detecting when a program that *modifies*
> sigcontext hasn't set all the fields. Even adding a flag won't really
> help here, since DOSEMU won't know to manipulate the flag.
>
> Ingo, here's the situation, assuming I remember the versions right:
>
> v4.0 and before: If we try to deliver a signal while SS is bad, we
> fail and the process dies. If SS is good but nonstandard, we end up
> in the signal handler with whatever SS value was loaded when the
> signal was sent. We do *not* put SS anywhere in the sigcontext, so
> the only way for a program to figure out what SS was is to look at the
> HW state before making any syscalls. We also don't even try to
> restore SS, so SS is unconditionally set to __USER_DS, necessitating
> nasty workarounds (and breaking all kinds of test cases).
>
> v4.1 and current -linus: We always set SS to __USER_DS when delivering
> a signal. We save the old SS in the sigcontext and restore it, just
> like 32-bit signals.
>
> My patch: We leave SS alone when delivering a signal, unless it's
> invalid, in which case we replace it with __USER_DS. We still save
> the old SS in the sigcontext and restore it on return.
>
> Apparently the remaining regression is that DOSEMU doesn't realize
> that SS is saved so, when it tries to return to full 64-bit mode after
> a signal that hit in 16-bit mode, it fails because it's invalidated
> the old SS descriptor in the mean time.
>
>
> So... what do we do about it? We could revert the whole mess.

Yes, absolutely - we should restore the ABI behavior to where v4.0 and before
stood.

> [...] We could tell everyone to fix their DOSEMU, which violates policy and is
> especially annoying given how much effort we've put into keeping 16-bit mode
> fully functional lately. [...]

So calling DOSEMU broken annoys me: there's nothing to 'fix' in DOSEMU really.

DOSEMU tried hard to work around a kernel bug. 100% of the blame and the
responsibility to keep things working is on the kernel side. No ifs and whens.

> [...] We could add yet more heuristics and teach sigreturn to ignore the saved
> SS value in sigcontext if the saved CS is 64-bit and the saved SS is unusable.

We could maybe try this - assuming it doesn't break DOSEMU.

Or we could extend the ABI and allow DOSEMU to cleanly use it.

I'm not sure it's worth the complexity, given that the DOSEMU workaround already
exists and will likely exist forever, so that it can support older kernels, right?

Thanks,

Ingo
--
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/