Re: [RFC 3/4] x86/signal/64: Re-add support for SS in the 64-bit signal context

Stas Sergeev
2015-10-14T17:41:13Z

14.10.2015 19:40, Andy Lutomirski пишет:
>>> + *
>>> + * Kernels that set UC_SIGCONTEXT_SS will also set UC_STRICT_RESTORE_SS
>>> + * when delivering a signal that came from 64-bit code.
>>> + *
>>> + * Sigreturn modifies its behavior depending on the UC_STRICT_RESTORE_SS
>>> + * flag. If UC_STRICT_RESTORE_SS is set, then the SS value in the
>>> + * signal context is restored verbatim. If UC_STRICT_RESTORE_SS is not
>>> + * set, the CS value in the signal context refers to a 64-bit code
>>> + * segment, and the signal context's SS value is invalid, it will be
>>> + * replaced by an flat 32-bit selector.
Is this correct?
It says "64-bit code segment will use the 32-bit SS".
I guess you mean 64-bit SS instead of a 32-bit?
Also it doesn't seem to be saying what happens if CS is 32-bit
and SS is invalid (the flag is not set).

>>> This is a bit risky, and another option would be to do nothing at
>>> all.
>> Andy, could you please stop pretending there are no other solutions?
>> You do not have to like them. You do not have to implement them.
>> But your continuous re-assertions that they do not exist, make me
>> feel a bit uncomfortable after I spelled them many times.
>>
>>> Stas, what do you think? Could you test this?
>> I think I'll get to testing this only at a week-end.
>> In a mean time, the question about a safety of leaving LDT SS
>> in 64bit mode still makes me wonder. Perhaps, instead of re-iterating
>> this here, you can describe this all in the patch comments? Namely:
>> - How will LDT SS interact with nested signals
>
> The kernel doesn't think about nested signals. If the inner signal is
> delivered while SS is in the LDT, the kernel will try to keep it as is
> and will stick whatever was in SS when the signal happened in the
> inner saved context. On return to the outer signal, it'll restore it
> following the UC_STRICT_RESTORE_SS rules.
Good.

>> - with syscalls
>
> 64-bit syscalls change SS to some default flat value as a side-effect.
> (Actually, IIRC, 64-bit syscalls change it specifically to __USER_DS,
> but, on Xen, 64-bit fast syscall returns may silently flip it to a
> different flat selector.)
Do we need this?
Maybe it should stop doing so?

>> - with siglongjmp()
>
> siglongjmp is a glibc thing. It should work the same way it always
> did. If it internally does a syscall (sigprocmask or whatever), that
> will override SS.
IMHO this side-effect needs to be documented somewhere.
I was scared about using it because I thought SS could be left bad.
Why I think it IS the kernel's problem is because in an ideal world
the sighandler should not run with LDT SS at all, so there will be no
fear about a bad SS after siglongjmp(). And if the sigprocmask() will
sometime stop validating SS, this can lead to surprises.

>>> If SS starts out invalid (this can happen if the signal was caused
>>> by an IRET fault or was delivered on the way out of set_thread_area
>>> or modify_ldt), then IRET to the signal handler can fail, eventually
>>> killing the task.
>> Is this signal-pecific? I.e. the return from IRQs happens via iret too.
>> So if we are running with invalid SS in 64bit mode, can the iret from
>> IRQ also cause the problem?
>>
>
> On new kernels, you can't run with invalid SS under any conditions.
Good.

>> On an off-topic: there was recently a patch from you that
>> disables vm86() by mmap_min_addr. I've found that dosemu, when
>> started as root, could override mmap_min_addr. I guess this will
>> no longer work, right? Not a big regression, just something to
>> know and document.
>
> As root, mmap_min_addr isn't enforced. Calling mmap and then dropping
> privileges would still keep the old mappings around. We could
> potentially rig it so that calling vm86 and then dropping privileges
> allows you to keep using vm86 even after dropping privileges.
Well, there is a special vm86() entry that is served just for
checking its presence, so maybe this could indeed be done. Not
that I find this very important. If you code up such a patch, I'll
see about changing dosemu2 accordingly, but don't rush on this too
much. :)