Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1217318 > unrolled thread

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

Started byAndy Lutomirski <luto@amacapital.net>
First post2015-09-02 07:20 +0200
Last post2015-09-03 01:00 +0200
Articles 13 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 07:20 +0200
    Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-02 11:20 +0200
      Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 16:30 +0200
        Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 17:10 +0200
        Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-02 19:50 +0200
          Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 20:20 +0200
            Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-02 20:30 +0200
              Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 21:10 +0200
                Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-02 23:00 +0200
                  Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-02 23:40 +0200
                    Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-03 00:30 +0200
                      Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Andy Lutomirski <luto@amacapital.net> - 2015-09-03 00:30 +0200
                        Re: [regression] x86/signal/64: Fix SS handling for signals delivered  to 64-bit programs breaks dosemu Stas Sergeev <stsp@list.ru> - 2015-09-03 01:00 +0200

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

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 07:20 +0200
SubjectRe: [regression] x86/signal/64: Fix SS handling for signals delivered to 64-bit programs breaks dosemu
Message-ID<q48CJ-3QR-1@gated-at.bofh.it>
On Wed, Aug 19, 2015 at 9:30 AM, Stas Sergeev <stsp@list.ru> wrote:
> 19.08.2015 18:46, Andy Lutomirski пишет:
>> On Wed, Aug 19, 2015 at 2:35 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>> Incidentally, I tried implementing the sigaction flag approach.  I
>>>> think it's no good.  When we return from a signal, there's no concept
>>>> of sigaction -- it's just sigreturn.  Sigreturn can't look up the
>>>> sigaction flags -- what if the signal handler calls sigaction itself.
>>> How about the SA_hyz flag that does the following:
>>> - Saves SS into sigcontext
>>> - Forces SS to USER_DS on signal delivery
>>> - Sets the uc_flags flag for sigreturn() to take care of the rest.
>>> You'll have both the control on every bit of action, and a simple
>>> detection logic: if SA_hyz didn't set the uc flag - it didn't work.
>>> You can even employ your lar heuristic here for the case when the
>>> aforementioned SA_hyz is not set. But please, please not when it is
>>> set! In fact, I wonder if you had in mind exactly that: using the
>>> lar heuristic only if the SA_hyz is not set. If so - I misunderstood.
>>> Just please don't add it when it is set.
>>
>> Hmm, interesting.  Maybe that would work for everything.  How's this
>> to make it concrete?
>>
>> Add a sigaction flag SA_RESTORE_SS.
>>
>> On signal delivery, always save SS into sigcontext->ss. if
>> SA_RESTORE_SS is set, then unconditionally switch HW SS to __USER_DS
>> and set UC_RESTORE_SS.  If SA_RESTORE_SS is clear, then leave HW SS
>> alone (i.e. preserve the old behavior).
> Either that, or employ the lar heuristic for the "not set" case
> (I think its not needed).
>
>> On signal return, if UC_RESTORE_SS is set, then restore
>> sigcontext->ss.  If not, then set SS to __USER_DS (as old kernels
>> did).
>>
>> This should change nothing at all (except the initial value of
>> sigcontext->ss / __pad0) on old kernels.
> Agreed.
>

Let me throw out one more possibility, just for completeness:

We don't add any SA_xyz flags.  On signal delivery, we use the LAR
heuristic.  We always fill in sigcontext->ss, and we set a new
UC_SIGCONTEXT_SS flag to indicate that we support the new behavior.

On sigreturn, we honor the sigcontext's ss, *unless* CS is 64 bit and
SS is invalid.  In the latter case, we replace the saved ss with
__USER_DS.

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.

This is a big problematic for my sigreturn_64 test, but I can deal
with that.  We could optionally have another UC_RESTORE_EXACT_SS flag
that you can set that means "no, really, restore the saved SS".

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1217439

FromStas Sergeev <stsp@list.ru>
Date2015-09-02 11:20 +0200
Message-ID<q4cmZ-KF-1@gated-at.bofh.it>
In reply to#1217318
02.09.2015 08:12, Andy Lutomirski пишет:
> On Wed, Aug 19, 2015 at 9:30 AM, Stas Sergeev <stsp@list.ru> wrote:
>> 19.08.2015 18:46, Andy Lutomirski пишет:
>>> On Wed, Aug 19, 2015 at 2:35 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>>> Incidentally, I tried implementing the sigaction flag approach.  I
>>>>> think it's no good.  When we return from a signal, there's no concept
>>>>> of sigaction -- it's just sigreturn.  Sigreturn can't look up the
>>>>> sigaction flags -- what if the signal handler calls sigaction itself.
>>>> How about the SA_hyz flag that does the following:
>>>> - Saves SS into sigcontext
>>>> - Forces SS to USER_DS on signal delivery
>>>> - Sets the uc_flags flag for sigreturn() to take care of the rest.
>>>> You'll have both the control on every bit of action, and a simple
>>>> detection logic: if SA_hyz didn't set the uc flag - it didn't work.
>>>> You can even employ your lar heuristic here for the case when the
>>>> aforementioned SA_hyz is not set. But please, please not when it is
>>>> set! In fact, I wonder if you had in mind exactly that: using the
>>>> lar heuristic only if the SA_hyz is not set. If so - I misunderstood.
>>>> Just please don't add it when it is set.
>>> Hmm, interesting.  Maybe that would work for everything.  How's this
>>> to make it concrete?
>>>
>>> Add a sigaction flag SA_RESTORE_SS.
>>>
>>> On signal delivery, always save SS into sigcontext->ss. if
>>> SA_RESTORE_SS is set, then unconditionally switch HW SS to __USER_DS
>>> and set UC_RESTORE_SS.  If SA_RESTORE_SS is clear, then leave HW SS
>>> alone (i.e. preserve the old behavior).
>> Either that, or employ the lar heuristic for the "not set" case
>> (I think its not needed).
>>
>>> On signal return, if UC_RESTORE_SS is set, then restore
>>> sigcontext->ss.  If not, then set SS to __USER_DS (as old kernels
>>> did).
>>>
>>> This should change nothing at all (except the initial value of
>>> sigcontext->ss / __pad0) on old kernels.
>> Agreed.
>>
> Let me throw out one more possibility, just for completeness:
>
> We don't add any SA_xyz flags.  On signal delivery, we use the LAR
> heuristic.  We always fill in sigcontext->ss, and we set a new
> UC_SIGCONTEXT_SS flag to indicate that we support the new behavior.
>
> On sigreturn, we honor the sigcontext's ss, *unless* CS is 64 bit and
> SS is invalid.  In the latter case, we replace the saved ss with
> __USER_DS.
But this is not a new proposal, see here:
https://lkml.org/lkml/2015/8/13/436
The very last sentence says exactly the same.
I thought this is in the past. :)

> 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
- Async signals can silently "validate" SS behind your back
- No way to extend that solution to later fixing the TLS problem
- Many ugly checks in the code, that are not always even obvious
(eg you wanted to try verw instead, and there was a gotcha with
NP bit)

Is the new SA flag such a big deal here to even bother?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217641

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 16:30 +0200
Message-ID<q4hd0-7Er-25@gated-at.bofh.it>
In reply to#1217439
On Wed, Sep 2, 2015 at 2:17 AM, Stas Sergeev <stsp@list.ru> wrote:
> 02.09.2015 08:12, Andy Lutomirski пишет:
>
>> On Wed, Aug 19, 2015 at 9:30 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>
>>> 19.08.2015 18:46, Andy Lutomirski пишет:
>>>>
>>>> On Wed, Aug 19, 2015 at 2:35 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>>>>
>>>>>> Incidentally, I tried implementing the sigaction flag approach.  I
>>>>>> think it's no good.  When we return from a signal, there's no concept
>>>>>> of sigaction -- it's just sigreturn.  Sigreturn can't look up the
>>>>>> sigaction flags -- what if the signal handler calls sigaction itself.
>>>>>
>>>>> How about the SA_hyz flag that does the following:
>>>>> - Saves SS into sigcontext
>>>>> - Forces SS to USER_DS on signal delivery
>>>>> - Sets the uc_flags flag for sigreturn() to take care of the rest.
>>>>> You'll have both the control on every bit of action, and a simple
>>>>> detection logic: if SA_hyz didn't set the uc flag - it didn't work.
>>>>> You can even employ your lar heuristic here for the case when the
>>>>> aforementioned SA_hyz is not set. But please, please not when it is
>>>>> set! In fact, I wonder if you had in mind exactly that: using the
>>>>> lar heuristic only if the SA_hyz is not set. If so - I misunderstood.
>>>>> Just please don't add it when it is set.
>>>>
>>>> Hmm, interesting.  Maybe that would work for everything.  How's this
>>>> to make it concrete?
>>>>
>>>> Add a sigaction flag SA_RESTORE_SS.
>>>>
>>>> On signal delivery, always save SS into sigcontext->ss. if
>>>> SA_RESTORE_SS is set, then unconditionally switch HW SS to __USER_DS
>>>> and set UC_RESTORE_SS.  If SA_RESTORE_SS is clear, then leave HW SS
>>>> alone (i.e. preserve the old behavior).
>>>
>>> Either that, or employ the lar heuristic for the "not set" case
>>> (I think its not needed).
>>>
>>>> On signal return, if UC_RESTORE_SS is set, then restore
>>>> sigcontext->ss.  If not, then set SS to __USER_DS (as old kernels
>>>> did).
>>>>
>>>> This should change nothing at all (except the initial value of
>>>> sigcontext->ss / __pad0) on old kernels.
>>>
>>> Agreed.
>>>
>> Let me throw out one more possibility, just for completeness:
>>
>> We don't add any SA_xyz flags.  On signal delivery, we use the LAR
>> heuristic.  We always fill in sigcontext->ss, and we set a new
>> UC_SIGCONTEXT_SS flag to indicate that we support the new behavior.
>>
>> On sigreturn, we honor the sigcontext's ss, *unless* CS is 64 bit and
>> SS is invalid.  In the latter case, we replace the saved ss with
>> __USER_DS.
>
> But this is not a new proposal, see here:
> https://lkml.org/lkml/2015/8/13/436
> The very last sentence says exactly the same.
> I thought this is in the past. :)
>

True, but I still want to make sure I understand the alternatives
well, and we never really considered this approach.

>> 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.

> - 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.  At least
with the approach it won't happen in 32-bit or 16-bit code, as we'd
only do the heuristic SS fix on sigreturn when returning to 64-bit
code.

> - No way to extend that solution to later fixing the TLS problem

True.

> - Many ugly checks in the code, that are not always even obvious
> (eg you wanted to try verw instead, and there was a gotcha with
> NP bit)

Also true.  OTOH, there'll be a unit test.

>
> 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.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217688

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 17:10 +0200
Message-ID<q4hPI-bE-23@gated-at.bofh.it>
In reply to#1217641
On Wed, Sep 2, 2015 at 7:21 AM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Wed, Sep 2, 2015 at 2:17 AM, Stas Sergeev <stsp@list.ru> wrote:
>> 02.09.2015 08:12, Andy Lutomirski пишет:
>>
>>> On Wed, Aug 19, 2015 at 9:30 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>>
>>>> 19.08.2015 18:46, Andy Lutomirski пишет:
>>>>>
>>>>> On Wed, Aug 19, 2015 at 2:35 AM, Stas Sergeev <stsp@list.ru> wrote:
>>>>>>>
>>>>>>> Incidentally, I tried implementing the sigaction flag approach.  I
>>>>>>> think it's no good.  When we return from a signal, there's no concept
>>>>>>> of sigaction -- it's just sigreturn.  Sigreturn can't look up the
>>>>>>> sigaction flags -- what if the signal handler calls sigaction itself.
>>>>>>
>>>>>> How about the SA_hyz flag that does the following:
>>>>>> - Saves SS into sigcontext
>>>>>> - Forces SS to USER_DS on signal delivery
>>>>>> - Sets the uc_flags flag for sigreturn() to take care of the rest.
>>>>>> You'll have both the control on every bit of action, and a simple
>>>>>> detection logic: if SA_hyz didn't set the uc flag - it didn't work.
>>>>>> You can even employ your lar heuristic here for the case when the
>>>>>> aforementioned SA_hyz is not set. But please, please not when it is
>>>>>> set! In fact, I wonder if you had in mind exactly that: using the
>>>>>> lar heuristic only if the SA_hyz is not set. If so - I misunderstood.
>>>>>> Just please don't add it when it is set.
>>>>>
>>>>> Hmm, interesting.  Maybe that would work for everything.  How's this
>>>>> to make it concrete?
>>>>>
>>>>> Add a sigaction flag SA_RESTORE_SS.
>>>>>
>>>>> On signal delivery, always save SS into sigcontext->ss. if
>>>>> SA_RESTORE_SS is set, then unconditionally switch HW SS to __USER_DS
>>>>> and set UC_RESTORE_SS.  If SA_RESTORE_SS is clear, then leave HW SS
>>>>> alone (i.e. preserve the old behavior).
>>>>
>>>> Either that, or employ the lar heuristic for the "not set" case
>>>> (I think its not needed).
>>>>
>>>>> On signal return, if UC_RESTORE_SS is set, then restore
>>>>> sigcontext->ss.  If not, then set SS to __USER_DS (as old kernels
>>>>> did).
>>>>>
>>>>> This should change nothing at all (except the initial value of
>>>>> sigcontext->ss / __pad0) on old kernels.
>>>>
>>>> Agreed.
>>>>
>>> Let me throw out one more possibility, just for completeness:
>>>
>>> We don't add any SA_xyz flags.  On signal delivery, we use the LAR
>>> heuristic.  We always fill in sigcontext->ss, and we set a new
>>> UC_SIGCONTEXT_SS flag to indicate that we support the new behavior.
>>>
>>> On sigreturn, we honor the sigcontext's ss, *unless* CS is 64 bit and
>>> SS is invalid.  In the latter case, we replace the saved ss with
>>> __USER_DS.
>>
>> But this is not a new proposal, see here:
>> https://lkml.org/lkml/2015/8/13/436
>> The very last sentence says exactly the same.
>> I thought this is in the past. :)
>>
>
> True, but I still want to make sure I understand the alternatives
> well, and we never really considered this approach.
>
>>> 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.
>
>> - 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.  At least
> with the approach it won't happen in 32-bit or 16-bit code, as we'd
> only do the heuristic SS fix on sigreturn when returning to 64-bit
> code.
>
>> - No way to extend that solution to later fixing the TLS problem
>
> True.
>
>> - Many ugly checks in the code, that are not always even obvious
>> (eg you wanted to try verw instead, and there was a gotcha with
>> NP bit)
>
> Also true.  OTOH, there'll be a unit test.
>
>>
>> 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.
>

In fact, I think we can do even better.

On signal delivery:
 - Always set UC_SAVED_SS (for feature detection)
 - Always save SS into sigcontext
 - Use the LAR heuristic to fix SS
 - If the old CS was 64-bit, set UC_STRICT_RESTORE_SS

On sigreturn:
 - Ignore UC_SAVED_SS.
 - Restore SS.
 - If the restored SS is bad, the new CS is 64-bit, and
UC_STRICT_RESTORE_SS is *not* set, then replace SS with __USER_DS.

In other words, we honor the sigcontext SS *unless* the original
signal context was not 64-bit (or UC_STRICT_RESTORE_SS was otherwise
cleared), the new context is 64-bit, and the new SS is bad.

If I understand correctly, old dosemu will keep working: old dosemu
never sigreturns back to anything other than 64-bit mode because it
can't.  (Unless there's a case where it does flat 32-bit mode using
__USER_DS -- is there?)

CRIU should be fine, since modern CRIU already saves and restore SS
and since older CRIU presumably doesn't set UC_STRICT_RESTORE_SS.

sigcontext_64 will work unmodified because it'll pick up
UC_STRICT_RESTORE_SS automatically as it does its weird sigreturns
directly from raise().

New DOSEMU can detect that the old workarounds aren't needed when it
sees UC_SAVED_SS and, if it wants stricter behavior, it can manually
mask off UC_STRICT_RESTORE_SS.

Old Wine won't be affected because I don't think Wine ever does 32-bit
emulation from a 64-bit binary in the first place.

Faults due to bad SS will never be silently fixed up because the
silent fixup only happens if the signal handler explicitly changes CS,
and only things that are aware of segmentation will do that.  (IOW
some random SIGALRM handler isn't going to touch sigcontext->cs.)

The new behavior is arguably not even insane.  People who reset CS to
some 64-bit value probably don't care what's in SS on return since SS
has no effect in 64-bit mode except possibly causing IRET to fail.
The only thing that seems to care is the DOSEMU IRET trampoline, and
that reprograms SS anyway (unless I'm still missing something).

Thoughts?

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217774

FromStas Sergeev <stsp@list.ru>
Date2015-09-02 19:50 +0200
Message-ID<q4kky-3Dm-3@gated-at.bofh.it>
In reply to#1217641
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.

>> - 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.

>> 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.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217793

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 20:20 +0200
Message-ID<q4kNA-4qF-23@gated-at.bofh.it>
In reply to#1217774
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.

What *does* work is to raise a signal and stash away the entire signal
context.  Then raise another signal and restore the old context.  Of
course, this needs SS support in sigcontext, and may still need to
handle DS and ES manually.

>
>>> - 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. :-/

>
>>> 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'll draft up an implementation and we can go from there.

--Andy

-- 
Andy Lutomirski
AMA Capital Management, LLC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217795

FromStas Sergeev <stsp@list.ru>
Date2015-09-02 20:30 +0200
Message-ID<q4kXf-4BW-1@gated-at.bofh.it>
In reply to#1217793
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?

>>>> - 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?

>>>> 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().
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217809

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 21:10 +0200
Message-ID<q4lzX-5B5-1@gated-at.bofh.it>
In reply to#1217795
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.

>
>>>>> - 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.

>
>>>>> 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
deliver signals with ss preserved when possible unless the program
opts out.  But I don't see why new programs would care what SS is,
since it has no effect during 64-bit code execution unless you read it
directly or long jmp/long ret to non-64-bit mode.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217856

FromStas Sergeev <stsp@list.ru>
Date2015-09-02 23:00 +0200
Message-ID<q4niq-7PZ-27@gated-at.bofh.it>
In reply to#1217809
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?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217867

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-02 23:40 +0200
Message-ID<q4nV8-mO-11@gated-at.bofh.it>
In reply to#1217856
On Wed, Sep 2, 2015 at 2:01 PM, Stas Sergeev <stsp@list.ru> wrote:
> 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)

So you're modifying sigcontext such that it returns to a C function
that calls longjmp?

>
> How dosemu2 is supposed to do this:
> 1. sigreturn() (to DOS)
> 2. siglongjmp() (to 64bit C-coded)

This should work fine on any kernel, right?  The main problem will be
that you presumably need to remember the old context so you can go
back to DOS, I assume.  So SS needs to be there somewhere.

>
>>>>>>> - 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?

Because siglongjmp calls sigprocmask, which uses SYSCALL, which clobbers SS.

>
>>>>>>> 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?

For backwards compat, we either need the default behavior to be
unchanged, or we need the default behavior to be something that works
with existing dosemu.  For existing dosemu, the only interesting cases
(I think) are signal delivery from *valid* 16-bit context, in which
case we need to preserve SS so that the signal handler can read it out
with mov ..., %ss, and sigreturn to 64-bit mode for the IRET
trampoline.  For sigreturn, IIUC old dosemu will replace the saved CS
with a 64-bit code segment selector and won't touch the saved SS
because it doesn't know about the saved SS.  Those dosemu versions
don't care what SS actually contains after sigreturn, because they're
immediately going to change it again using IRET.  So we just need to
make sure we return without faulting.

New dosemu2 would like to sigreturn directly back to 16-bit mode, so
it needs the kernel to honor the saved ss value and restore it,
possibly changed by dosemu.

We obviously can't require old dosemu to set an SA flag to keep
working.  But, if we can get away with it, I think it's somewhat
preferable not to require new DOSEMU to set an SA flag either.

This has one major benefit at least: if new dosemu loads some random
library that installs some async signal handler (SIGALRM for example),
everything will work with regard to CS and SS.  If SIGALRM hits 16-bit
code, CS and SS get saved, the signal handler gets invoked in 64-bit
mode, and sigreturn restores the old state.

Of course, FS and GS still screw this up.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217876

FromStas Sergeev <stsp@list.ru>
Date2015-09-03 00:30 +0200
Message-ID<q4oHw-1ws-9@gated-at.bofh.it>
In reply to#1217867
03.09.2015 00:39, Andy Lutomirski пишет:
> On Wed, Sep 2, 2015 at 2:01 PM, Stas Sergeev <stsp@list.ru> wrote:
>> 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)
> So you're modifying sigcontext such that it returns to a C function
> that calls longjmp?
Yes.

>> How dosemu2 is supposed to do this:
>> 1. sigreturn() (to DOS)
>> 2. siglongjmp() (to 64bit C-coded)
> This should work fine on any kernel, right?
1 - not.
2 - maybe.
If, as you say, siglongjmp() restores SS, I need to try it out.
(there is also a problem that most siglongjmp() implementations
are incompatible with sigaltstack(), but this is not what you can fix).

>    The main problem will be
> that you presumably need to remember the old context so you can go
> back to DOS, I assume.  So SS needs to be there somewhere.
Its fine if you always save SS to sigcontext.
This is what you proposed already and I think its fine.
dosemu saves entire sigcontext before going out to 64bit.

>>>>>>>> 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?
> For backwards compat, we either need the default behavior to be
> unchanged, or we need the default behavior to be something that works
> with existing dosemu.  For existing dosemu, the only interesting cases
> (I think) are signal delivery from *valid* 16-bit context, in which
> case we need to preserve SS so that the signal handler can read it out
> with mov ..., %ss, and sigreturn to 64-bit mode for the IRET
> trampoline.  For sigreturn, IIUC old dosemu will replace the saved CS
> with a 64-bit code segment selector and won't touch the saved SS
> because it doesn't know about the saved SS.  Those dosemu versions
> don't care what SS actually contains after sigreturn, because they're
> immediately going to change it again using IRET.  So we just need to
> make sure we return without faulting.
>
> New dosemu2 would like to sigreturn directly back to 16-bit mode, so
> it needs the kernel to honor the saved ss value and restore it,
> possibly changed by dosemu.
>
> We obviously can't require old dosemu to set an SA flag to keep
> working.  But, if we can get away with it, I think it's somewhat
> preferable not to require new DOSEMU to set an SA flag either.
>
> This has one major benefit at least: if new dosemu loads some random
> library that installs some async signal handler (SIGALRM for example),
> everything will work with regard to CS and SS.
This case is covered if we do both things together: use
your heuristic when SA_hyz is not set, and don't use it
when its set. In this case dosemu2 will be able to request
the proper SS delivery for its sighandlers, but the 3rd-party
sighandlers will work too.
I think we have never discussed the possibility of doing
both things together, even though I have proposed it many
times.
After discussing this full-blown solution, we can think about
reducing it, either by removing the heuristic or by removing
SA_hyz, but discussing the full one would be nice too.
Your opinion is likely that no one will use this SA_hyz in
presence of the heuristic that "seems to work anyway".
But in the light of extending it for TLS (with a new flag),
I wouldn't be so sure. You can also document it as a
needed flag when user code touches SS, and then it will
be used. dosemu1 code that doesn't use it, will eventually
be forgotten. So IMHO whether it will be used, is fully up
to how will you market it. :)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217877

FromAndy Lutomirski <luto@amacapital.net>
Date2015-09-03 00:30 +0200
Message-ID<q4oHw-1ws-11@gated-at.bofh.it>
In reply to#1217876
On Wed, Sep 2, 2015 at 3:25 PM, Stas Sergeev <stsp@list.ru> wrote:
> 03.09.2015 00:39, Andy Lutomirski пишет:
>
>> On Wed, Sep 2, 2015 at 2:01 PM, Stas Sergeev <stsp@list.ru> wrote:
>>>
>>> 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)
>>
>> So you're modifying sigcontext such that it returns to a C function
>> that calls longjmp?
>
> Yes.
>
>>> How dosemu2 is supposed to do this:
>>> 1. sigreturn() (to DOS)
>>> 2. siglongjmp() (to 64bit C-coded)
>>
>> This should work fine on any kernel, right?
>
> 1 - not.
> 2 - maybe.
> If, as you say, siglongjmp() restores SS, I need to try it out.
> (there is also a problem that most siglongjmp() implementations
> are incompatible with sigaltstack(), but this is not what you can fix).
>

1 - definitely needs kernel changes.  I was referring to #2.

2 - siglongjmp probably varies in its behavior across different libc
implementations.  My point is that siglongjmp isn't a kernel-provided
thing.

>> For backwards compat, we either need the default behavior to be
>> unchanged, or we need the default behavior to be something that works
>> with existing dosemu.  For existing dosemu, the only interesting cases
>> (I think) are signal delivery from *valid* 16-bit context, in which
>> case we need to preserve SS so that the signal handler can read it out
>> with mov ..., %ss, and sigreturn to 64-bit mode for the IRET
>> trampoline.  For sigreturn, IIUC old dosemu will replace the saved CS
>> with a 64-bit code segment selector and won't touch the saved SS
>> because it doesn't know about the saved SS.  Those dosemu versions
>> don't care what SS actually contains after sigreturn, because they're
>> immediately going to change it again using IRET.  So we just need to
>> make sure we return without faulting.
>>
>> New dosemu2 would like to sigreturn directly back to 16-bit mode, so
>> it needs the kernel to honor the saved ss value and restore it,
>> possibly changed by dosemu.
>>
>> We obviously can't require old dosemu to set an SA flag to keep
>> working.  But, if we can get away with it, I think it's somewhat
>> preferable not to require new DOSEMU to set an SA flag either.
>>
>> This has one major benefit at least: if new dosemu loads some random
>> library that installs some async signal handler (SIGALRM for example),
>> everything will work with regard to CS and SS.
>
> This case is covered if we do both things together: use
> your heuristic when SA_hyz is not set, and don't use it
> when its set. In this case dosemu2 will be able to request
> the proper SS delivery for its sighandlers, but the 3rd-party
> sighandlers will work too.
> I think we have never discussed the possibility of doing
> both things together, even though I have proposed it many
> times.
> After discussing this full-blown solution, we can think about
> reducing it, either by removing the heuristic or by removing
> SA_hyz, but discussing the full one would be nice too.
> Your opinion is likely that no one will use this SA_hyz in
> presence of the heuristic that "seems to work anyway".
> But in the light of extending it for TLS (with a new flag),
> I wouldn't be so sure. You can also document it as a
> needed flag when user code touches SS, and then it will
> be used. dosemu1 code that doesn't use it, will eventually
> be forgotten. So IMHO whether it will be used, is fully up
> to how will you market it. :)

I'll think about it.  I'll think about FS and GS, too, although that's
still a longer-term thing.

--Andy

-- 
Andy Lutomirski
AMA Capital Management, LLC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1217903

FromStas Sergeev <stsp@list.ru>
Date2015-09-03 01:00 +0200
Message-ID<q4pay-24f-11@gated-at.bofh.it>
In reply to#1217877
03.09.2015 01:25, Andy Lutomirski пишет:
> On Wed, Sep 2, 2015 at 3:25 PM, Stas Sergeev <stsp@list.ru> wrote:
>
>>>> How dosemu2 is supposed to do this:
>>>> 1. sigreturn() (to DOS)
>>>> 2. siglongjmp() (to 64bit C-coded)
>>> This should work fine on any kernel, right?
>> 1 - not.
>> 2 - maybe.
>> If, as you say, siglongjmp() restores SS, I need to try it out.
>> (there is also a problem that most siglongjmp() implementations
>> are incompatible with sigaltstack(), but this is not what you can fix).
>>
> 1 - definitely needs kernel changes.  I was referring to #2.
>
> 2 - siglongjmp probably varies in its behavior across different libc
> implementations.  My point is that siglongjmp isn't a kernel-provided
> thing.
So if siglongjmp() restores SS by the side-effect of doing a sigprocmask()
syscall, this admittedly weakens my point.
The unreliability then stays only with the async signals interrupting
the main one.

>>> For backwards compat, we either need the default behavior to be
>>> unchanged, or we need the default behavior to be something that works
>>> with existing dosemu.  For existing dosemu, the only interesting cases
>>> (I think) are signal delivery from *valid* 16-bit context, in which
>>> case we need to preserve SS so that the signal handler can read it out
>>> with mov ..., %ss, and sigreturn to 64-bit mode for the IRET
>>> trampoline.  For sigreturn, IIUC old dosemu will replace the saved CS
>>> with a 64-bit code segment selector and won't touch the saved SS
>>> because it doesn't know about the saved SS.  Those dosemu versions
>>> don't care what SS actually contains after sigreturn, because they're
>>> immediately going to change it again using IRET.  So we just need to
>>> make sure we return without faulting.
>>>
>>> New dosemu2 would like to sigreturn directly back to 16-bit mode, so
>>> it needs the kernel to honor the saved ss value and restore it,
>>> possibly changed by dosemu.
>>>
>>> We obviously can't require old dosemu to set an SA flag to keep
>>> working.  But, if we can get away with it, I think it's somewhat
>>> preferable not to require new DOSEMU to set an SA flag either.
>>>
>>> This has one major benefit at least: if new dosemu loads some random
>>> library that installs some async signal handler (SIGALRM for example),
>>> everything will work with regard to CS and SS.
>> This case is covered if we do both things together: use
>> your heuristic when SA_hyz is not set, and don't use it
>> when its set. In this case dosemu2 will be able to request
>> the proper SS delivery for its sighandlers, but the 3rd-party
>> sighandlers will work too.
>> I think we have never discussed the possibility of doing
>> both things together, even though I have proposed it many
>> times.
>> After discussing this full-blown solution, we can think about
>> reducing it, either by removing the heuristic or by removing
>> SA_hyz, but discussing the full one would be nice too.
>> Your opinion is likely that no one will use this SA_hyz in
>> presence of the heuristic that "seems to work anyway".
>> But in the light of extending it for TLS (with a new flag),
>> I wouldn't be so sure. You can also document it as a
>> needed flag when user code touches SS, and then it will
>> be used. dosemu1 code that doesn't use it, will eventually
>> be forgotten. So IMHO whether it will be used, is fully up
>> to how will you market it. :)
> I'll think about it.  I'll think about FS and GS, too,
OK, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web