On Thu, Aug 13, 2015 at 1:25 PM, Andy Lutomirski <l...@amacapital.net> wrote:
> On Thu, Aug 13, 2015 at 1:18 PM, Andy Lutomirski <l...@kernel.org> wrote:
>> Linux used to have nearly useless SS handling for 64-bit signals.  Signal
>> delivery to a 64-bit process would preserve the SS selector, but the
>> selector wasn't saved in sigcontext.  Sigreturn would then clobber SS.
>> If the signal being delivered was due to a bad SS, signal delivery would
>> fail and the task would be killed.
>>
>> As of Linux 4.1, it's fixed: signal delivery sets up a valid SS in the
>> hardware SS selector, saves the old SS in the sigcontext, and restores it
>> properly in sigreturn.
>>
>> DOSEMU had a curious workaround for the old behavior: it saved the
>> hardware SS selector it was given during signal delivery and fudged
>> RIP and CS so that sigreturn would return to a trampoline that
>> restored the old RIP, CS, and, importantly, SS.
>>
>> The upshot is that the change in sigcontext had no effect on DOSEMU
>> (DOSEMU doesn't care what was in sigcontext, and the fact that the
>> old SS is presented to the trampoline in new kernels is irrelevant
>> because the trampoline uses long mode), but the change in signal
>> delivery caused DOSEMU's workaround to restore __USER_DS instead of
>> the correct pre-signal SS value.
>>
>> Do our best to work around it: explicitly check whether the old SS
>> is usable and leave it alone during signal delivery if it is.
>> Sigreturn is unchanged.
>>
>> Reported-by: Stas Sergeev <s...@list.ru>
>> Fixes: c6f2062935c8 ("x86/signal/64: Fix SS handling for signals delivered 
>> to 64-bit programs")
>> Signed-off-by: Andy Lutomirski <l...@kernel.org>
>> ---
>
>> +               asm ("lar %[old_ss], %[ar]\n\t"
>> +                    "jz 1f\n\t"
>> +                    "xorl %[ar], %[ar]\n\t"    /* If invalid, set ar = 0 */
>> +                    "1:"
>> +                    : [ar] "=r" (ar)
>> +                    : [old_ss] "rm" ((u16)regs->ss));
>> +
>
> Now that I sent this...
>
> I should learn to think very carefully before doubting Linus'
> off-the-cuff intuition about the x86 instruction set.  This can use
> VERW after all, as long as it's careful to set RPL==3.

And the corollary to that is: I should also assume that Linus is out
to get me :)

VERW is no good, because it considers non-present segments to be
writable.  Test cases for the win!

--Andy
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to