Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-28 Thread Yu-cheng Yu
On Tue, 2020-05-19 at 18:04 -0700, Andy Lutomirski wrote:
> On Mon, May 18, 2020 at 6:35 PM Andy Lutomirski  wrote:
> > [...]
> > > On May 18, 2020, at 5:38 PM, Dave Hansen  wrote:
> > > [...]
> > > The sadistic parts of selftests/x86 come from real bugs.  Either bugs
> > > where the kernel fell over, or where behavior changed that broke apps.
> > > I'd suggest doing some research on where that particular test case came
> > > from.  Find the author of the test, look at the changelogs.
> > > 
> > > If this is something that a real app does, this is a problem.  If it's a
> > > sadistic test that Andy L added because it was an attack vector against
> > > the entry code, it's a different story.
> > 
> > There are quite a few tests that do these horrible things in there. IN my 
> > personal opinion, sigreturn.c is one of the most important tests we have — 
> > it does every horrible thing to the entry code that I thought of and that I 
> > could come up with a way of doing.  We have been saved from regressing many 
> > times by these tests.  CET, and especially the CPL0 version of CET, is its 
> > own set of entry horror, and we need to keep these tests working.
> > 
> > I assume the basic issue is that we call raise(), the context magically 
> > changes to 32-bit, but SSP has a 64-bit value, and horrors happen.  So I 
> > think two things need to happen:
> > 
> > 1. Someone needs to document what happens when IRET tries to put a 64-bit 
> > value into SSP but CS is compat. Because Intel has plenty of history of 
> > doing colossally broken things here. IOW you could easily be hitting a 
> > hardware design problem, not a software issue per se.
> > 
> > 2. The test needs to work. Assuming the hardware doesn’t do something 
> > utterly broken, either the 32-bit code needs to be adjusted to avoid any 
> > CALL
> > or RET, or you need to write a little raise_on_32bit_shstk() func that 
> > switches to an SSP that fits in 32 bits, calls raise(), and switches back.  
> > From memory, I didn’t think there was a CALl or RET, so I’m guessing that 
> > SSP is getting truncated when we round trip through CPL3 compat mode and 
> > the result is that the kernel invoked the signal handler with the wrong 
> > SSP.  Whoops.
> > 
> 
> Following up here, I think this needs attention from the H/W architects.
> 
> From the SDM:
> 
> SYSRET and SYSEXIT:
> 
> IF ShadowStackEnabled(CPL)
> SSP ← IA32_PL3_SSP;
> FI;
> 
> IRET:
> 
> IF ShadowStackEnabled(CPL)
> IF CPL = 3
> THEN tempSSP ← IA32_PL3_SSP; FI;
> IF ((EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0)
> THEN #GP(0); FI;
> SSP ← tempSSP
> 
> The semantics of actually executing in compat mode with SSP >= 2^32
> are unclear.  If nothing else, VM exit will save the full SSP and a
> subsequent VM entry will fail.

Here is what I got after talking to the architect.

If the guest is in 32-bit mode, but its VM guest state SSP field is 64-bit, the
CPU only uses the lower 32 bits.

The SDM currently states a consistency check of the guest SSP field, but that
will be removed in the next version.  Upon VM entry, the CPU only requires the
guest SSP to be pseudo-canonical like the RIP and RSP.

> I don't know what the actual effect of operand-size-32 SYSRET or
> SYSEXIT with too big a PL3_SSP will be, but I think it needs to be
> documented.  Ideally it will not put the CPU in an invalid state.
> Ideally it will also not fault, because SYSRET faults in particular
> are fatal unless the vector uses IST, and please please please don't
> force more ISTs on anyone.

On SYSRET/SYSEXIT to a 32-bit context, the CPU only uses the lower 32 bits of
the user-mode SSP, and will not go into an invalid state and will not fault. 
The SDM will be explicit about this.

Yu-cheng

> 
> So I think we may need to put this entire series on hold until we get
> some answers, because I suspect we're going to have a nice little root
> hole otherwise.



Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-22 Thread Andrew Cooper
On 22/05/2020 17:49, Peter Zijlstra wrote:
> On Sat, May 16, 2020 at 03:09:22PM +0100, Andrew Cooper wrote:
>
>> Sadly, the same is not true for kernel shadow stacks.
>>
>> SSP is 0 after SYSCALL, SYSENTER and CLRSSBSY, and you've got to be
>> careful to re-establish the shadow stack before a CALL, interrupt or
>> exception tries pushing a word onto the shadow stack at 0xfff8.
> Oh man, I can only imagine the joy that brings to #NM and friends :-(

Establishing a supervisor shadow stack for the first time involves a
large leap of faith, even by usual x86 standards.

You need to have prepared MSR_PL0_SSP with correct mappings and
supervisor tokens, such that when you enable CR4.CET and
MSR_S_CET.SHSTK_EN, your SETSSBSY instruction succeeds at its atomic
"check the token and set the busy bit" shadow stack access.  Any failure
here tends to be a triple fault, and I didn't get around to figuring out
why #DF wasn't taken cleanly.

You also need to have prepared MSR_IST_SSP beforehand with the IST
shadow stack pointers matching any IST configuration in the IDT, lest a
NMI ruins your day on the instruction boundary before SETSSBSY.

A less obvious side effect of these "windows with an SSP of 0" is that
you're now forced to use IST for all non-maskable interrupts/exceptions,
even if you choose not to use SYSCALL, and you no longer need IST to
remove the risks of a userspace privilege escalation, and would prefer
not to use IST because of its problematic reentrancy characteristics.

For anyone counting the number of IST-necessary vectors across all
potential configurations in modern hardware, its #DB, NMI, #DF, #MC,
#VE, #HV, #VC and #SX, and an architectural limit of 7.

There are several other amusing aspects, such as iret-to-self needing to
use call-oriented-programming to keep itself shadow-stack-safe, or the
fact that IRET to user mode doesn't fault if it fails to clear the
supervisor busy bit, instead leaving you to double fault at some point
in the future at the next syscall/interrupt/exception because the stack
is still busy.

~Andrew

P.S. For anyone interested,
https://lore.kernel.org/xen-devel/20200501225838.9866-1-andrew.coop...@citrix.com/T/#u
for getting supervisor shadow stacks working on Xen, which is far
simpler to manage than Linux.  I do not envy whomever has the fun of
trying to make this work for Linux.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-22 Thread Peter Zijlstra
On Sat, May 16, 2020 at 03:09:22PM +0100, Andrew Cooper wrote:

> Sadly, the same is not true for kernel shadow stacks.
> 
> SSP is 0 after SYSCALL, SYSENTER and CLRSSBSY, and you've got to be
> careful to re-establish the shadow stack before a CALL, interrupt or
> exception tries pushing a word onto the shadow stack at 0xfff8.

Oh man, I can only imagine the joy that brings to #NM and friends :-(


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-19 Thread Andy Lutomirski
On Mon, May 18, 2020 at 6:35 PM Andy Lutomirski  wrote:
>
>
>
> > On May 18, 2020, at 5:38 PM, Dave Hansen  wrote:
> >
> > On 5/18/20 4:47 PM, Yu-cheng Yu wrote:
> >>> On Fri, 2020-05-15 at 19:53 -0700, Yu-cheng Yu wrote:
> >>> On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
>  On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> > [...]
> > I have run them with CET enabled.  All of them pass, except for the 
> > following:
> > Sigreturn from 64-bit to 32-bit fails, because shadow stack is at a 
> > 64-bit
> > address.  This is understandable.
>  [...]
>  One a separate topic: You ran the selftests and one failed.  This is a
>  *MASSIVE* warning sign.  It should minimally be described in your cover
>  letter, and accompanied by a fix to the test case.  It is absolutely
>  unacceptable to introduce a kernel feature that causes a test to fail.
>  You must either fix your kernel feature or you fix the test.
> 
>  This code can not be accepted until this selftests issue is rectified.
> >> The x86/sigreturn test constructs 32-bit ldt entries, and does sigreturn 
> >> from
> >> 64-bit to 32-bit context.  We do not have a way to construct a static 
> >> 32-bit
> >> shadow stack.
> >
> > Why? What's the limiting factor?  Hardware architecture?  Something in
> > the kernel?
> >
> >> Why do we want that?  I think we can simply run the test with CET
> >> disabled.
> >
> > The sadistic parts of selftests/x86 come from real bugs.  Either bugs
> > where the kernel fell over, or where behavior changed that broke apps.
> > I'd suggest doing some research on where that particular test case came
> > from.  Find the author of the test, look at the changelogs.
> >
> > If this is something that a real app does, this is a problem.  If it's a
> > sadistic test that Andy L added because it was an attack vector against
> > the entry code, it's a different story.
>
> There are quite a few tests that do these horrible things in there. IN my 
> personal opinion, sigreturn.c is one of the most important tests we have — it 
> does every horrible thing to the entry code that I thought of and that I 
> could come up with a way of doing.  We have been saved from regressing many 
> times by these tests.  CET, and especially the CPL0 version of CET, is its 
> own set of entry horror, and we need to keep these tests working.
>
> I assume the basic issue is that we call raise(), the context magically 
> changes to 32-bit, but SSP has a 64-bit value, and horrors happen.  So I 
> think two things need to happen:
>
> 1. Someone needs to document what happens when IRET tries to put a 64-bit 
> value into SSP but CS is compat. Because Intel has plenty of history of doing 
> colossally broken things here. IOW you could easily be hitting a hardware 
> design problem, not a software issue per se.
>
> 2. The test needs to work. Assuming the hardware doesn’t do something utterly 
> broken, either the 32-bit code needs to be adjusted to avoid any CALL
> or RET, or you need to write a little raise_on_32bit_shstk() func that 
> switches to an SSP that fits in 32 bits, calls raise(), and switches back.  
> From memory, I didn’t think there was a CALl or RET, so I’m guessing that SSP 
> is getting truncated when we round trip through CPL3 compat mode and the 
> result is that the kernel invoked the signal handler with the wrong SSP.  
> Whoops.
>

Following up here, I think this needs attention from the H/W architects.

>From the SDM:

SYSRET and SYSEXIT:

IF ShadowStackEnabled(CPL)
SSP ← IA32_PL3_SSP;
FI;

IRET:

IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP ← IA32_PL3_SSP; FI;
IF ((EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0)
THEN #GP(0); FI;
SSP ← tempSSP

The semantics of actually executing in compat mode with SSP >= 2^32
are unclear.  If nothing else, VM exit will save the full SSP and a
subsequent VM entry will fail.

I don't know what the actual effect of operand-size-32 SYSRET or
SYSEXIT with too big a PL3_SSP will be, but I think it needs to be
documented.  Ideally it will not put the CPU in an invalid state.
Ideally it will also not fault, because SYSRET faults in particular
are fatal unless the vector uses IST, and please please please don't
force more ISTs on anyone.

So I think we may need to put this entire series on hold until we get
some answers, because I suspect we're going to have a nice little root
hole otherwise.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Andy Lutomirski



> On May 18, 2020, at 5:38 PM, Dave Hansen  wrote:
> 
> On 5/18/20 4:47 PM, Yu-cheng Yu wrote:
>>> On Fri, 2020-05-15 at 19:53 -0700, Yu-cheng Yu wrote:
>>> On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
 On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> [...]
> I have run them with CET enabled.  All of them pass, except for the 
> following:
> Sigreturn from 64-bit to 32-bit fails, because shadow stack is at a 64-bit
> address.  This is understandable.
 [...]
 One a separate topic: You ran the selftests and one failed.  This is a
 *MASSIVE* warning sign.  It should minimally be described in your cover
 letter, and accompanied by a fix to the test case.  It is absolutely
 unacceptable to introduce a kernel feature that causes a test to fail.
 You must either fix your kernel feature or you fix the test.
 
 This code can not be accepted until this selftests issue is rectified.
>> The x86/sigreturn test constructs 32-bit ldt entries, and does sigreturn from
>> 64-bit to 32-bit context.  We do not have a way to construct a static 32-bit
>> shadow stack.
> 
> Why? What's the limiting factor?  Hardware architecture?  Something in
> the kernel?
> 
>> Why do we want that?  I think we can simply run the test with CET
>> disabled.
> 
> The sadistic parts of selftests/x86 come from real bugs.  Either bugs
> where the kernel fell over, or where behavior changed that broke apps.
> I'd suggest doing some research on where that particular test case came
> from.  Find the author of the test, look at the changelogs.
> 
> If this is something that a real app does, this is a problem.  If it's a
> sadistic test that Andy L added because it was an attack vector against
> the entry code, it's a different story.

There are quite a few tests that do these horrible things in there. IN my 
personal opinion, sigreturn.c is one of the most important tests we have — it 
does every horrible thing to the entry code that I thought of and that I could 
come up with a way of doing.  We have been saved from regressing many times by 
these tests.  CET, and especially the CPL0 version of CET, is its own set of 
entry horror, and we need to keep these tests working.

I assume the basic issue is that we call raise(), the context magically changes 
to 32-bit, but SSP has a 64-bit value, and horrors happen.  So I think two 
things need to happen:

1. Someone needs to document what happens when IRET tries to put a 64-bit value 
into SSP but CS is compat. Because Intel has plenty of history of doing 
colossally broken things here. IOW you could easily be hitting a hardware 
design problem, not a software issue per se.

2. The test needs to work. Assuming the hardware doesn’t do something utterly 
broken, either the 32-bit code needs to be adjusted to avoid any CALL
or RET, or you need to write a little raise_on_32bit_shstk() func that switches 
to an SSP that fits in 32 bits, calls raise(), and switches back.  From memory, 
I didn’t think there was a CALl or RET, so I’m guessing that SSP is getting 
truncated when we round trip through CPL3 compat mode and the result is that 
the kernel invoked the signal handler with the wrong SSP.  Whoops.

> 
> I don't personally know the background, but the changelogs can help you
> find the person that does.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Dave Hansen
On 5/18/20 4:47 PM, Yu-cheng Yu wrote:
> On Fri, 2020-05-15 at 19:53 -0700, Yu-cheng Yu wrote:
>> On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
>>> On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
 [...]
 I have run them with CET enabled.  All of them pass, except for the 
 following:
 Sigreturn from 64-bit to 32-bit fails, because shadow stack is at a 64-bit
 address.  This is understandable.
>>> [...]
>>> One a separate topic: You ran the selftests and one failed.  This is a
>>> *MASSIVE* warning sign.  It should minimally be described in your cover
>>> letter, and accompanied by a fix to the test case.  It is absolutely
>>> unacceptable to introduce a kernel feature that causes a test to fail.
>>> You must either fix your kernel feature or you fix the test.
>>>
>>> This code can not be accepted until this selftests issue is rectified.
> The x86/sigreturn test constructs 32-bit ldt entries, and does sigreturn from
> 64-bit to 32-bit context.  We do not have a way to construct a static 32-bit
> shadow stack.

Why? What's the limiting factor?  Hardware architecture?  Something in
the kernel?

> Why do we want that?  I think we can simply run the test with CET
> disabled.

The sadistic parts of selftests/x86 come from real bugs.  Either bugs
where the kernel fell over, or where behavior changed that broke apps.
I'd suggest doing some research on where that particular test case came
from.  Find the author of the test, look at the changelogs.

If this is something that a real app does, this is a problem.  If it's a
sadistic test that Andy L added because it was an attack vector against
the entry code, it's a different story.

I don't personally know the background, but the changelogs can help you
find the person that does.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Yu-cheng Yu
On Fri, 2020-05-15 at 19:53 -0700, Yu-cheng Yu wrote:
> On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
> > On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> > > [...]
> > > I have run them with CET enabled.  All of them pass, except for the 
> > > following:
> > > Sigreturn from 64-bit to 32-bit fails, because shadow stack is at a 64-bit
> > > address.  This is understandable.
> > [...]
> > One a separate topic: You ran the selftests and one failed.  This is a
> > *MASSIVE* warning sign.  It should minimally be described in your cover
> > letter, and accompanied by a fix to the test case.  It is absolutely
> > unacceptable to introduce a kernel feature that causes a test to fail.
> > You must either fix your kernel feature or you fix the test.
> > 
> > This code can not be accepted until this selftests issue is rectified.

The x86/sigreturn test constructs 32-bit ldt entries, and does sigreturn from
64-bit to 32-bit context.  We do not have a way to construct a static 32-bit
shadow stack.  Why do we want that?  I think we can simply run the test with CET
disabled.

Yu-cheng




Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Dave Hansen
On 5/18/20 7:01 AM, H.J. Lu wrote:
>> Could some of this information be added to the documentation, please?
>> It would also be nice to have some more details about how apps end up
>> using ARCH_X86_CET_STATUS.  Why would they care that CET is on?
> CET software spec is at
> 
> https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/Intel-CET-extension
> 
> My CET presentation at 2018 LPC is at
> 
> https://www.linuxplumbersconf.org/event/2/contributions/147/attachments/72/83/CET-LPC-2018.pdf
> 
> I am working on an updated CET presentation for 2020 LPC.  Let me know
> if you want to see the early draft.

There's a lot of great information in there!

However, please remember that presentations are no substitute for old
fashioned documentation in the kernel tree and changelogs.  The fact
that we need to lean on them to answer basic questions about new
interfaces is not a great sign.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Yu-cheng Yu
On Mon, 2020-05-18 at 06:41 -0700, Dave Hansen wrote:
> On 5/15/20 7:53 PM, Yu-cheng Yu wrote:
> > On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
> > > What's my recourse as an end user?  I want to run my app and turn off
> > > CET for that app.  How can I do that?
> > 
> > GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT
> 
> Like I mentioned to H.J., this is something that we need to at least
> acknowledge the existence of in the changelog and probably even the
> Documentation/.

Sure.  I will do that.

> 
> > > > >  I think you're saying that the CET-enabled binary would do
> > > > > arch_setup_elf_property() when it was first exec()'d.  Later, it could
> > > > > use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
> > > > > then fork() and the child would not be using CET.  Right?
> > > > > 
> > > > > What is ARCH_X86_CET_DISABLE used for, anyway?
> > > > 
> > > > Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
> > > > not locked.
> > > 
> > > Could you please describe a real-world example of why
> > > ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
> > > using it?  Why was it created in the first place?
> > 
> > Currently, ld-linux turns off CET if the binary being loaded does not 
> > support
> > CET.
> 
> Great!  Could this please be immortalized in the documentation for the
> prctl()?

Yes.

> 
> > > > > > > Does this *code* work?  Could you please indicate which JITs have 
> > > > > > > been
> > > > > > > enabled to use the code in this series?  How much of the new ABI 
> > > > > > > is in use?
> > > > > > 
> > > > > > JIT does not necessarily use all of the ABI.  The JIT changes 
> > > > > > mainly fix stack
> > > > > > frames and insert ENDBRs.  I do not work on JIT.  What I found is 
> > > > > > LLVM JIT fixes
> > > > > > are tested and in the master branch.  Sljit fixes are in the 
> > > > > > release.
> > > > > 
> > > > > Huh, so who is using the new prctl() ABIs?
> > > > 
> > > > Any code can use the ABI, but JIT code CET-enabling part mostly do not 
> > > > use these
> > > > new prctl()'s, except, probably to get CET status.
> > > 
> > > Which applications specifically are going to use the new prctl()s which
> > > this series adds?  How are they going to use them?
> > > 
> > > "Any code can use them" is not a specific enough answer.
> > 
> > We have four arch_ptctl() calls.  ARCH_X86_CET_DISABLE and 
> > ARCH_X86_CET_LOCK are
> > used by ld-linux.  ARCH_X86_CET_STATUS are used in many places to determine 
> > if
> > CET is on.  ARCH_X86_CET_ALLOC_SHSTK is used in ucontext related handling, 
> > but
> > it can be use by any application to switch shadow stacks.
> 
> Could some of this information be added to the documentation, please?
> It would also be nice to have some more details about how apps end up
> using ARCH_X86_CET_STATUS.  Why would they care that CET is on?

Yes.

Yu-cheng



Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread H.J. Lu
On Mon, May 18, 2020 at 6:41 AM Dave Hansen  wrote:
>
> On 5/15/20 7:53 PM, Yu-cheng Yu wrote:
> > On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
> >> What's my recourse as an end user?  I want to run my app and turn off
> >> CET for that app.  How can I do that?
> >
> > GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT
>
> Like I mentioned to H.J., this is something that we need to at least
> acknowledge the existence of in the changelog and probably even the
> Documentation/.
>
>   I think you're saying that the CET-enabled binary would do
>  arch_setup_elf_property() when it was first exec()'d.  Later, it could
>  use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
>  then fork() and the child would not be using CET.  Right?
> 
>  What is ARCH_X86_CET_DISABLE used for, anyway?
> >>>
> >>> Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
> >>> not locked.
> >>
> >> Could you please describe a real-world example of why
> >> ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
> >> using it?  Why was it created in the first place?
> >
> > Currently, ld-linux turns off CET if the binary being loaded does not 
> > support
> > CET.
>
> Great!  Could this please be immortalized in the documentation for the
> prctl()?
>
> >> Does this *code* work?  Could you please indicate which JITs have been
> >> enabled to use the code in this series?  How much of the new ABI is in 
> >> use?
> >
> > JIT does not necessarily use all of the ABI.  The JIT changes mainly 
> > fix stack
> > frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM 
> > JIT fixes
> > are tested and in the master branch.  Sljit fixes are in the release.
> 
>  Huh, so who is using the new prctl() ABIs?
> >>>
> >>> Any code can use the ABI, but JIT code CET-enabling part mostly do not 
> >>> use these
> >>> new prctl()'s, except, probably to get CET status.
> >>
> >> Which applications specifically are going to use the new prctl()s which
> >> this series adds?  How are they going to use them?
> >>
> >> "Any code can use them" is not a specific enough answer.
> >
> > We have four arch_ptctl() calls.  ARCH_X86_CET_DISABLE and 
> > ARCH_X86_CET_LOCK are
> > used by ld-linux.  ARCH_X86_CET_STATUS are used in many places to determine 
> > if
> > CET is on.  ARCH_X86_CET_ALLOC_SHSTK is used in ucontext related handling, 
> > but
> > it can be use by any application to switch shadow stacks.
>
> Could some of this information be added to the documentation, please?
> It would also be nice to have some more details about how apps end up
> using ARCH_X86_CET_STATUS.  Why would they care that CET is on?

CET software spec is at

https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/Intel-CET-extension

My CET presentation at 2018 LPC is at

https://www.linuxplumbersconf.org/event/2/contributions/147/attachments/72/83/CET-LPC-2018.pdf

I am working on an updated CET presentation for 2020 LPC.  Let me know
if you want to see the early draft.

-- 
H.J.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-18 Thread Dave Hansen
On 5/15/20 7:53 PM, Yu-cheng Yu wrote:
> On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
>> What's my recourse as an end user?  I want to run my app and turn off
>> CET for that app.  How can I do that?
> 
> GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT

Like I mentioned to H.J., this is something that we need to at least
acknowledge the existence of in the changelog and probably even the
Documentation/.

  I think you're saying that the CET-enabled binary would do
 arch_setup_elf_property() when it was first exec()'d.  Later, it could
 use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
 then fork() and the child would not be using CET.  Right?

 What is ARCH_X86_CET_DISABLE used for, anyway?
>>>
>>> Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
>>> not locked.
>>
>> Could you please describe a real-world example of why
>> ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
>> using it?  Why was it created in the first place?
> 
> Currently, ld-linux turns off CET if the binary being loaded does not support
> CET.

Great!  Could this please be immortalized in the documentation for the
prctl()?

>> Does this *code* work?  Could you please indicate which JITs have been
>> enabled to use the code in this series?  How much of the new ABI is in 
>> use?
>
> JIT does not necessarily use all of the ABI.  The JIT changes mainly fix 
> stack
> frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM 
> JIT fixes
> are tested and in the master branch.  Sljit fixes are in the release.

 Huh, so who is using the new prctl() ABIs?
>>>
>>> Any code can use the ABI, but JIT code CET-enabling part mostly do not use 
>>> these
>>> new prctl()'s, except, probably to get CET status.
>>
>> Which applications specifically are going to use the new prctl()s which
>> this series adds?  How are they going to use them?
>>
>> "Any code can use them" is not a specific enough answer.
> 
> We have four arch_ptctl() calls.  ARCH_X86_CET_DISABLE and ARCH_X86_CET_LOCK 
> are
> used by ld-linux.  ARCH_X86_CET_STATUS are used in many places to determine if
> CET is on.  ARCH_X86_CET_ALLOC_SHSTK is used in ucontext related handling, but
> it can be use by any application to switch shadow stacks.

Could some of this information be added to the documentation, please?
It would also be nice to have some more details about how apps end up
using ARCH_X86_CET_STATUS.  Why would they care that CET is on?


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-17 Thread Dave Hansen
On 5/15/20 7:51 PM, H.J. Lu wrote:
> On Fri, May 15, 2020 at 4:56 PM Dave Hansen  wrote:
>> Let's say we have an app doing silly things like retpolines.  (Lots of
>> app do lots of silly things).  It gets compiled in a distro but never
>> runs on a system with CET.  The app gets run for the first time on a
>> system with CET.  App goes boom.  Not init, just some random app, say
>> /usr/bin/ldapsearch.
> 
> I designed and implemented CET toolchain and run-time in such a way
> for it very difficult to happen.   Basically, CET won't be enabled on such
> an app.

Would you care to share any specifics about how this is implemented?
That would be great information to include in the kernel documentation
because it informs us about the reasons why we don't need a kernel-based
"kill switch".

>> What's my recourse as an end user?  I want to run my app and turn off
>> CET for that app.  How can I do that?
> 
> The CET OS I designed turns CET off for you and you don't have to do
> anything.

OK, cool!  Could you share some of the specifics about how it does that?

>> Is it possible with the patches in this series to run a single-
>> threaded binary which was has GNU_PROPERTY_X86_FEATURE_1_SHSTK
>> unset to run with shadow stack protection?
> 
> Yes, you can.  I added such capabilities for testing purpose.  But
> you application will crash as soon as there is a CET violation.  My
> CET software design is very flexible. 

Yu-cheng speficially referred to the:

GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT

option.  Is that the option you're talking about?

>>> I have a quick test that checks shadow stack and ibt in both main program 
>>> and in
>>> signals.  Currently it is public on Github.  If that is desired, I can 
>>> submit it
>>> to the mailing list.
>>
>> Yes, that is desired.  It must accompany this submission.  It must also
>> exercise all of the new ABIs.
> 
> Our CET smoke test is for quick validation of CET OS, not just
> kernel. It requires the complete CET implementation.   It does
> nothing if your OS isn't CET enabled.
I think requiring the complete CET implementation to be present for this
test to work is a mistake.  We don't require anything other than an
enabled kernel and the selftests that ship with that kernel.

MPX required toolchain, library and compiler changes.  Yet, we had a
totally standalone kernel test that found real bugs.  It sounds like
this smoke test as it stands wouldn't be a great fit.  But, that
shouldn't discourage us from finding something that _is_ a good fit for
the kernel-shipped selftests.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-16 Thread Andrew Cooper
On 16/05/2020 03:37, H.J. Lu wrote:
> On Fri, May 15, 2020 at 5:13 PM Andrew Cooper  
> wrote:
>> Finally seeing as the question was asked but not answered, it is
>> actually quite easy to figure out whether shadow stacks are enabled in
>> the current thread.
>>
>> mov $1, %eax
>> rdsspd  %eax
> This is for 32-bit mode.

It actually works for both, if all you need is a shstk yes/no check.

Usually, you also want SSP in the yes case, so substitute rdsspq %rax as
appropriate.

(On a tangent - binutils mandating the D/Q suffixes is very irritating
with mixed 32/64bit code because you have to #ifdef your instructions
despite the register operands being totally unambiguous.  Also, D is the
wrong suffix for AT syntax, and should be L.  Frankly - the Intel
manuals are wrong and should not have the operand size suffix included
in the opcode name, as they are consistent with all the other
instructions in this regard.)

>   I use
>
> /* Check if shadow stack is in use.  */
> xorl%esi, %esi
> rdsspq  %rsi
> testq   %rsi, %rsi
> /* Normal return if shadow stack isn't in use.  */
> je  L(no_shstk)

This is probably fine for user code, as I don't think it would be
legitimate for shstk to be enabled, with SSP being 0.

Sadly, the same is not true for kernel shadow stacks.

SSP is 0 after SYSCALL, SYSENTER and CLRSSBSY, and you've got to be
careful to re-establish the shadow stack before a CALL, interrupt or
exception tries pushing a word onto the shadow stack at 0xfff8.

It is a very good (lucky?) thing that frame is unmapped for other
reasons, because this corner case does not protect against multiple
threads/cores using the same shadow stack concurrently.

~Andrew


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread H.J. Lu
On Fri, May 15, 2020 at 4:56 PM Dave Hansen  wrote:
>
> On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> > On Fri, 2020-05-15 at 15:43 -0700, Dave Hansen wrote:
> >> Basically, if there ends up being a bug in an app that violates the
> >> shadow stack rules, the app is broken, period.  The only recourse is to
> >> have the kernel disable CET and reboot.
> >>
> >> Is that right?
> >
> > You must be talking about init or any of the system daemons, right?
> > Assuming we let the app itself start CET with an arch_prctl(), why would 
> > that be
> > different from the current approach?
>
> You're getting ahead of me a bit here.
>
> I'm actually not asking directly about the prctls() or advocating for a
> different approach.  The MPX approach of _requiring the app to make a
> prctl() was actually pretty nasty because sometimes threads got created
> before the prctl() could get called.  Apps ended up inadvertently
> half-MPX-enabled.  Not fun.
>
> Let's say we have an app doing silly things like retpolines.  (Lots of
> app do lots of silly things).  It gets compiled in a distro but never
> runs on a system with CET.  The app gets run for the first time on a
> system with CET.  App goes boom.  Not init, just some random app, say
> /usr/bin/ldapsearch.

I designed and implemented CET toolchain and run-time in such a way
for it very difficult to happen.   Basically, CET won't be enabled on such
an app.

> What's my recourse as an end user?  I want to run my app and turn off
> CET for that app.  How can I do that?

The CET OS I designed turns CET off for you and you don't have to do
anything.

>  Can a binary compiled without CET run CET-enabled code?
> >>>
> >>> Partially yes, but in reality somewhat difficult.
> >> ...
> >>> - If a not-CET application does fork(), and the child wants to turn on 
> >>> CET, it
> >>> would be difficult to manage the stack frames, unless the child knows 
> >>> what is is
> >>> doing.
> >>
> >> It might be hard to do, but it is possible with the patches you posted?
> >
> > It is possible to add an arch_prctl() to turn on CET.  That is simple from 
> > the
> > kernel's perspective, but difficult for the application.  Once the app 
> > enables
> > shadow stack, it has to take care not to return beyond the function call 
> > layers
> > before that point.  It can no longer do longjmp or ucontext swaps to 
> > anything
> > before that point.  It will also be complicated if the app enables shadow 
> > stack
> > in a signal handler.
>
> Yu-cheng, I'm having a very hard time getting direct answers to my
> questions.  Could you endeavor to give succinct, direct answers?  If you
> want to give a longer, conditioned answer, that's great.  But, I'd
> appreciate if you could please focus first on clearly answering the
> questions that I'm asking.
>
> Let me try again:
>
> Is it possible with the patches in this series to run a single-
> threaded binary which was has GNU_PROPERTY_X86_FEATURE_1_SHSTK
> unset to run with shadow stack protection?

Yes, you can.  I added such capabilities for testing purpose.  But you
application
will crash as soon as there is a CET violation.  My CET software design is very
flexible.  It can accommodate different requirements.  We are working
with 2 OSVs
to enable CET in their OSes.  So far we haven't run into any
unexpected issues.

> I think the answer is an unambiguous: "No".  But I'd like to hear it
> from you.
>
> >>  I think you're saying that the CET-enabled binary would do
> >> arch_setup_elf_property() when it was first exec()'d.  Later, it could
> >> use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
> >> then fork() and the child would not be using CET.  Right?
> >>
> >> What is ARCH_X86_CET_DISABLE used for, anyway?
> >
> > Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
> > not locked.
>
> Could you please describe a real-world example of why
> ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
> using it?  Why was it created in the first place?
>
> >>> The JIT examples I mentioned previously run with CET enabled from the
> >>> beginning.  Do you have a reason to do this?  In other words, if the JIT 
> >>> code
> >>> needs CET, the app could have started with CET in the first place.
> >>
> >> Let's say I have a JIT'd sandbox.  I want the sandbox to be
> >> CET-protected, but the JIT engine itself not to be.
> >
> > I do not have any objections to this use case, but it needs some cautions as
> > stated above.  It will be much easier and cleaner if the sandbox is in a
> > separate exec'ed task with CET on.
>
> OK, great suggestion!  Could you do some research and look at the
> various sandboxing techniques?  Is imposing this requirement for a
> separate exec'd task reasonable?  Does it fit nicely with their existing
> models?  How about the Chrome browser and Firefox sandboxs?
>
>  Does this *code* work?  Could you please indicate which JITs have been
>  enabled to use 

Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Yu-cheng Yu
On Fri, 2020-05-15 at 16:56 -0700, Dave Hansen wrote:
> On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> > On Fri, 2020-05-15 at 15:43 -0700, Dave Hansen wrote:
> > > Basically, if there ends up being a bug in an app that violates the
> > > shadow stack rules, the app is broken, period.  The only recourse is to
> > > have the kernel disable CET and reboot.
> > > 
> > > Is that right?
> > 
> > You must be talking about init or any of the system daemons, right?
> > Assuming we let the app itself start CET with an arch_prctl(), why would 
> > that be
> > different from the current approach?
> 
> You're getting ahead of me a bit here.
> 
> I'm actually not asking directly about the prctls() or advocating for a
> different approach.  The MPX approach of _requiring the app to make a
> prctl() was actually pretty nasty because sometimes threads got created
> before the prctl() could get called.  Apps ended up inadvertently
> half-MPX-enabled.  Not fun.
> 
> Let's say we have an app doing silly things like retpolines.  (Lots of
> app do lots of silly things).  It gets compiled in a distro but never
> runs on a system with CET.  The app gets run for the first time on a
> system with CET.  App goes boom.  Not init, just some random app, say
> /usr/bin/ldapsearch.
> 
> What's my recourse as an end user?  I want to run my app and turn off
> CET for that app.  How can I do that?

GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT

> > > > > Can a binary compiled without CET run CET-enabled code?
> > > > 
> > > > Partially yes, but in reality somewhat difficult.
> > > ...
> > > > - If a not-CET application does fork(), and the child wants to turn on 
> > > > CET, it
> > > > would be difficult to manage the stack frames, unless the child knows 
> > > > what is is
> > > > doing.  
> > > 
> > > It might be hard to do, but it is possible with the patches you posted?
> > 
> > It is possible to add an arch_prctl() to turn on CET.  That is simple from 
> > the
> > kernel's perspective, but difficult for the application.  Once the app 
> > enables
> > shadow stack, it has to take care not to return beyond the function call 
> > layers
> > before that point.  It can no longer do longjmp or ucontext swaps to 
> > anything
> > before that point.  It will also be complicated if the app enables shadow 
> > stack
> > in a signal handler.
> 
> Yu-cheng, I'm having a very hard time getting direct answers to my
> questions.  Could you endeavor to give succinct, direct answers?  If you
> want to give a longer, conditioned answer, that's great.  But, I'd
> appreciate if you could please focus first on clearly answering the
> questions that I'm asking.
> 
> Let me try again:
> 
>   Is it possible with the patches in this series to run a single-
>   threaded binary which was has GNU_PROPERTY_X86_FEATURE_1_SHSTK
>   unset to run with shadow stack protection?
> 
> I think the answer is an unambiguous: "No".  But I'd like to hear it
> from you.

No!

> > >  I think you're saying that the CET-enabled binary would do
> > > arch_setup_elf_property() when it was first exec()'d.  Later, it could
> > > use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
> > > then fork() and the child would not be using CET.  Right?
> > > 
> > > What is ARCH_X86_CET_DISABLE used for, anyway?
> > 
> > Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
> > not locked.
> 
> Could you please describe a real-world example of why
> ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
> using it?  Why was it created in the first place?

Currently, ld-linux turns off CET if the binary being loaded does not support
CET.

> > > > The JIT examples I mentioned previously run with CET enabled from the
> > > > beginning.  Do you have a reason to do this?  In other words, if the 
> > > > JIT code
> > > > needs CET, the app could have started with CET in the first place.
> > > 
> > > Let's say I have a JIT'd sandbox.  I want the sandbox to be
> > > CET-protected, but the JIT engine itself not to be.
> > 
> > I do not have any objections to this use case, but it needs some cautions as
> > stated above.  It will be much easier and cleaner if the sandbox is in a
> > separate exec'ed task with CET on.
> 
> OK, great suggestion!  Could you do some research and look at the
> various sandboxing techniques?  Is imposing this requirement for a
> separate exec'd task reasonable?  Does it fit nicely with their existing
> models?  How about the Chrome browser and Firefox sandboxs?

I will check.

> > > > > Does this *code* work?  Could you please indicate which JITs have been
> > > > > enabled to use the code in this series?  How much of the new ABI is 
> > > > > in use?
> > > > 
> > > > JIT does not necessarily use all of the ABI.  The JIT changes mainly 
> > > > fix stack
> > > > frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM 
> > > > JIT fixes
> > > > are tested and in the master branch.  Sljit fixes are in the 

Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread H.J. Lu
On Fri, May 15, 2020 at 5:13 PM Andrew Cooper  wrote:
>
> On 15/05/2020 23:43, Dave Hansen wrote:
> > On 5/15/20 2:33 PM, Yu-cheng Yu wrote:
> >> On Fri, 2020-05-15 at 11:39 -0700, Dave Hansen wrote:
> >>> On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
> >>> Can a binary compiled with CET run without CET?
> >> Yes, but a few details:
> >>
> >> - The shadow stack is transparent to the application.  A CET application 
> >> does
> >> not have anything different from a non-CET application.  However, if a CET
> >> application uses any CET instructions (e.g. INCSSP), it must first check 
> >> if CET
> >> is turned on.
> >> - If an application is compiled for IBT, the compiler inserts ENDBRs at 
> >> branch
> >> targets.  These are nops if IBT is not on.
> > I appreciate the detailed response, but it wasn't quite what I was
> > asking.  Let's ignore IBT for now and just talk about shadow stacks.
> >
> > An app compiled with the new ELF flags and running on a CET-enabled
> > kernel and CPU will start off with shadow stacks allocated and enabled,
> > right?  It can turn its shadow stack off per-thread with the new prctl.
> >  But, otherwise, it's stuck, the only way to turn shadow stacks off at
> > startup would be editing the binary.
> >
> > Basically, if there ends up being a bug in an app that violates the
> > shadow stack rules, the app is broken, period.  The only recourse is to
> > have the kernel disable CET and reboot.
> >
> > Is that right?
>
> If I may interject with the experience of having got supervisor shadow
> stacks working for Xen.
>
> Turning shadow stacks off is quite easy - clear MSR_U_CET.SHSTK_EN and
> the shadow stack will stay in whatever state it was in, and you can
> largely forget about it.  (Of course, in a sandbox scenario, it would be
> prudent to prevent the ability to disable shadow stacks.)
>
> Turning shadow stacks on is much more tricky.  You cannot enable it in
> any function you intend to return from, as the divergence between the
> stack and shadow stack will constitute a control flow violation.
>
>
> When it comes to binaries,  you can reasonably arrange for clone() to
> start a thread on a new stack/shstk, as you can prepare both stacks
> suitably before execution starts.
>
> You cannot reasonably implement a system call for "turn shadow stacks on
> for me", because you'll crash on the ret out of the VDSO from the system
> call.  It would be possible to conceive of an exec()-like system call
> which is "discard my current stack, turn on shstk, and start me on this
> new stack/shstk".
>
> In principle, with a pair of system calls to atomically manage the ststk
> settings and stack switching, it might possible to construct a
> `run_with_shstk_enabled(func, stack, shstk)` API which executes in the
> current threads context and doesn't explode.
>
> Fork() is a problem when shadow stacks are disabled in the parent.  The
> moment shadow stacks are disabled, the regular stack diverges from the
> shadow stack.  A CET-enabled app which turns off shstk and then fork()'s
> must have the child inherit the shstk-off property.  If the child were
> to start with shstk enabled, it would explode almost immediately due to
> the parent's stack divergence which it inherited.
>
>
> Finally seeing as the question was asked but not answered, it is
> actually quite easy to figure out whether shadow stacks are enabled in
> the current thread.
>
> mov $1, %eax
> rdsspd  %eax

This is for 32-bit mode.  I use

/* Check if shadow stack is in use.  */
xorl%esi, %esi
rdsspq  %rsi
testq   %rsi, %rsi
/* Normal return if shadow stack isn't in use.  */
je  L(no_shstk)

> cmp $1, %eax
> je  no_shstk
> ...
> no_shsk:
>
> rdssp is allocated from the hint nop encoding space, and the minimum
> alignment of the shadow stack pointer is 4.  On older parts, or with
> shstk disabled (either at the system level, or for the thread), the $1
> will be preserved in %eax, while if CET is active, it will be clobbered
> with something that has the bottom two bits clear.
>
> It turns out this is a lifesaver for codepaths (e.g. the NMI handler)
> which need to use other CET instructions which aren't from the hint nop
> space, and run before the BSP can set everything up.
>
> ~Andrew



-- 
H.J.


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Andrew Cooper
On 15/05/2020 23:43, Dave Hansen wrote:
> On 5/15/20 2:33 PM, Yu-cheng Yu wrote:
>> On Fri, 2020-05-15 at 11:39 -0700, Dave Hansen wrote:
>>> On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
>>> Can a binary compiled with CET run without CET?
>> Yes, but a few details:
>>
>> - The shadow stack is transparent to the application.  A CET application does
>> not have anything different from a non-CET application.  However, if a CET
>> application uses any CET instructions (e.g. INCSSP), it must first check if 
>> CET
>> is turned on.
>> - If an application is compiled for IBT, the compiler inserts ENDBRs at 
>> branch
>> targets.  These are nops if IBT is not on.
> I appreciate the detailed response, but it wasn't quite what I was
> asking.  Let's ignore IBT for now and just talk about shadow stacks.
>
> An app compiled with the new ELF flags and running on a CET-enabled
> kernel and CPU will start off with shadow stacks allocated and enabled,
> right?  It can turn its shadow stack off per-thread with the new prctl.
>  But, otherwise, it's stuck, the only way to turn shadow stacks off at
> startup would be editing the binary.
>
> Basically, if there ends up being a bug in an app that violates the
> shadow stack rules, the app is broken, period.  The only recourse is to
> have the kernel disable CET and reboot.
>
> Is that right?

If I may interject with the experience of having got supervisor shadow
stacks working for Xen.

Turning shadow stacks off is quite easy - clear MSR_U_CET.SHSTK_EN and
the shadow stack will stay in whatever state it was in, and you can
largely forget about it.  (Of course, in a sandbox scenario, it would be
prudent to prevent the ability to disable shadow stacks.)

Turning shadow stacks on is much more tricky.  You cannot enable it in
any function you intend to return from, as the divergence between the
stack and shadow stack will constitute a control flow violation.


When it comes to binaries,  you can reasonably arrange for clone() to
start a thread on a new stack/shstk, as you can prepare both stacks
suitably before execution starts.

You cannot reasonably implement a system call for "turn shadow stacks on
for me", because you'll crash on the ret out of the VDSO from the system
call.  It would be possible to conceive of an exec()-like system call
which is "discard my current stack, turn on shstk, and start me on this
new stack/shstk".

In principle, with a pair of system calls to atomically manage the ststk
settings and stack switching, it might possible to construct a
`run_with_shstk_enabled(func, stack, shstk)` API which executes in the
current threads context and doesn't explode.

Fork() is a problem when shadow stacks are disabled in the parent.  The
moment shadow stacks are disabled, the regular stack diverges from the
shadow stack.  A CET-enabled app which turns off shstk and then fork()'s
must have the child inherit the shstk-off property.  If the child were
to start with shstk enabled, it would explode almost immediately due to
the parent's stack divergence which it inherited.


Finally seeing as the question was asked but not answered, it is
actually quite easy to figure out whether shadow stacks are enabled in
the current thread.

    mov $1, %eax
    rdsspd  %eax
    cmp $1, %eax
    je  no_shstk
    ...
no_shsk:

rdssp is allocated from the hint nop encoding space, and the minimum
alignment of the shadow stack pointer is 4.  On older parts, or with
shstk disabled (either at the system level, or for the thread), the $1
will be preserved in %eax, while if CET is active, it will be clobbered
with something that has the bottom two bits clear.

It turns out this is a lifesaver for codepaths (e.g. the NMI handler)
which need to use other CET instructions which aren't from the hint nop
space, and run before the BSP can set everything up.

~Andrew


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Dave Hansen
On 5/15/20 4:29 PM, Yu-cheng Yu wrote:
> On Fri, 2020-05-15 at 15:43 -0700, Dave Hansen wrote:
>> Basically, if there ends up being a bug in an app that violates the
>> shadow stack rules, the app is broken, period.  The only recourse is to
>> have the kernel disable CET and reboot.
>>
>> Is that right?
> 
> You must be talking about init or any of the system daemons, right?
> Assuming we let the app itself start CET with an arch_prctl(), why would that 
> be
> different from the current approach?

You're getting ahead of me a bit here.

I'm actually not asking directly about the prctls() or advocating for a
different approach.  The MPX approach of _requiring the app to make a
prctl() was actually pretty nasty because sometimes threads got created
before the prctl() could get called.  Apps ended up inadvertently
half-MPX-enabled.  Not fun.

Let's say we have an app doing silly things like retpolines.  (Lots of
app do lots of silly things).  It gets compiled in a distro but never
runs on a system with CET.  The app gets run for the first time on a
system with CET.  App goes boom.  Not init, just some random app, say
/usr/bin/ldapsearch.

What's my recourse as an end user?  I want to run my app and turn off
CET for that app.  How can I do that?

 Can a binary compiled without CET run CET-enabled code?
>>>
>>> Partially yes, but in reality somewhat difficult.
>> ...
>>> - If a not-CET application does fork(), and the child wants to turn on CET, 
>>> it
>>> would be difficult to manage the stack frames, unless the child knows what 
>>> is is
>>> doing.  
>>
>> It might be hard to do, but it is possible with the patches you posted?
> 
> It is possible to add an arch_prctl() to turn on CET.  That is simple from the
> kernel's perspective, but difficult for the application.  Once the app enables
> shadow stack, it has to take care not to return beyond the function call 
> layers
> before that point.  It can no longer do longjmp or ucontext swaps to anything
> before that point.  It will also be complicated if the app enables shadow 
> stack
> in a signal handler.

Yu-cheng, I'm having a very hard time getting direct answers to my
questions.  Could you endeavor to give succinct, direct answers?  If you
want to give a longer, conditioned answer, that's great.  But, I'd
appreciate if you could please focus first on clearly answering the
questions that I'm asking.

Let me try again:

Is it possible with the patches in this series to run a single-
threaded binary which was has GNU_PROPERTY_X86_FEATURE_1_SHSTK
unset to run with shadow stack protection?

I think the answer is an unambiguous: "No".  But I'd like to hear it
from you.

>>  I think you're saying that the CET-enabled binary would do
>> arch_setup_elf_property() when it was first exec()'d.  Later, it could
>> use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
>> then fork() and the child would not be using CET.  Right?
>>
>> What is ARCH_X86_CET_DISABLE used for, anyway?
> 
> Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is
> not locked.

Could you please describe a real-world example of why
ARCH_X86_CET_DISABLE exists?  What kinds of apps will use it, or *are*
using it?  Why was it created in the first place?

>>> The JIT examples I mentioned previously run with CET enabled from the
>>> beginning.  Do you have a reason to do this?  In other words, if the JIT 
>>> code
>>> needs CET, the app could have started with CET in the first place.
>>
>> Let's say I have a JIT'd sandbox.  I want the sandbox to be
>> CET-protected, but the JIT engine itself not to be.
> 
> I do not have any objections to this use case, but it needs some cautions as
> stated above.  It will be much easier and cleaner if the sandbox is in a
> separate exec'ed task with CET on.

OK, great suggestion!  Could you do some research and look at the
various sandboxing techniques?  Is imposing this requirement for a
separate exec'd task reasonable?  Does it fit nicely with their existing
models?  How about the Chrome browser and Firefox sandboxs?

 Does this *code* work?  Could you please indicate which JITs have been
 enabled to use the code in this series?  How much of the new ABI is in use?
>>>
>>> JIT does not necessarily use all of the ABI.  The JIT changes mainly fix 
>>> stack
>>> frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM JIT 
>>> fixes
>>> are tested and in the master branch.  Sljit fixes are in the release.
>>
>> Huh, so who is using the new prctl() ABIs?
> 
> Any code can use the ABI, but JIT code CET-enabling part mostly do not use 
> these
> new prctl()'s, except, probably to get CET status.

Which applications specifically are going to use the new prctl()s which
this series adds?  How are they going to use them?

"Any code can use them" is not a specific enough answer.

 Where are the selftests/ for this new ABI?  Were you planning on
 submitting any with this series?
>>>

Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Yu-cheng Yu
On Fri, 2020-05-15 at 15:43 -0700, Dave Hansen wrote:
> On 5/15/20 2:33 PM, Yu-cheng Yu wrote:
> > On Fri, 2020-05-15 at 11:39 -0700, Dave Hansen wrote:
> > > On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
> > > Can a binary compiled with CET run without CET?
> > 
> > Yes, but a few details:
> > 
> > - The shadow stack is transparent to the application.  A CET application 
> > does
> > not have anything different from a non-CET application.  However, if a CET
> > application uses any CET instructions (e.g. INCSSP), it must first check if 
> > CET
> > is turned on.
> > - If an application is compiled for IBT, the compiler inserts ENDBRs at 
> > branch
> > targets.  These are nops if IBT is not on.
> 
> I appreciate the detailed response, but it wasn't quite what I was
> asking.  Let's ignore IBT for now and just talk about shadow stacks.
> 
> An app compiled with the new ELF flags and running on a CET-enabled
> kernel and CPU will start off with shadow stacks allocated and enabled,
> right?  It can turn its shadow stack off per-thread with the new prctl.
>  But, otherwise, it's stuck, the only way to turn shadow stacks off at
> startup would be editing the binary.
> 
> Basically, if there ends up being a bug in an app that violates the
> shadow stack rules, the app is broken, period.  The only recourse is to
> have the kernel disable CET and reboot.
> 
> Is that right?

You must be talking about init or any of the system daemons, right?
Assuming we let the app itself start CET with an arch_prctl(), why would that be
different from the current approach?

> > > Can a binary compiled without CET run CET-enabled code?
> > 
> > Partially yes, but in reality somewhat difficult.
> ...
> > - If a not-CET application does fork(), and the child wants to turn on CET, 
> > it
> > would be difficult to manage the stack frames, unless the child knows what 
> > is is
> > doing.  
> 
> It might be hard to do, but it is possible with the patches you posted?

It is possible to add an arch_prctl() to turn on CET.  That is simple from the
kernel's perspective, but difficult for the application.  Once the app enables
shadow stack, it has to take care not to return beyond the function call layers
before that point.  It can no longer do longjmp or ucontext swaps to anything
before that point.  It will also be complicated if the app enables shadow stack
in a signal handler.

>  I think you're saying that the CET-enabled binary would do
> arch_setup_elf_property() when it was first exec()'d.  Later, it could
> use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
> then fork() and the child would not be using CET.  Right?
> 
> What is ARCH_X86_CET_DISABLE used for, anyway?

Both the parent and the child can do ARCH_X86_CET_DISABLE, if CET is not locked.

> > The JIT examples I mentioned previously run with CET enabled from the
> > beginning.  Do you have a reason to do this?  In other words, if the JIT 
> > code
> > needs CET, the app could have started with CET in the first place.
> 
> Let's say I have a JIT'd sandbox.  I want the sandbox to be
> CET-protected, but the JIT engine itself not to be.

I do not have any objections to this use case, but it needs some cautions as
stated above.  It will be much easier and cleaner if the sandbox is in a
separate exec'ed task with CET on.

> > - If you are asking about dlopen(), the library will have the same setting 
> > as
> > the main application.  Do you have any reason to have a library running with
> > CET, but the application does not have CET?
> 
> Sure, using old binaries.  That's why IBT has a legacy bitmap and things
> like MPX had ways of jumping into old non-enabled binaries.

If the app has CET, but libs do not, then bitmap can help.
If the app does not have CET, we don't run the libs with CET, right?  This is
the case right now.

> > > Can different threads in a process have different CET enabling state?
> > 
> > Yes, if the parent starts with CET, children can turn it off.
> 
> How would that work, though?  clone() by default will copy the parent
> xsave state, which means it will be CET-enabled, which means it needs a
> shadow stack.  So, if I want a CET-free child thread, I need to clone(),
> then turn CET off, then free the shadow stack?

Yes, the child itself turns off CET.

> > > Does this *code* work?  Could you please indicate which JITs have been
> > > enabled to use the code in this series?  How much of the new ABI is in 
> > > use?
> > 
> > JIT does not necessarily use all of the ABI.  The JIT changes mainly fix 
> > stack
> > frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM JIT 
> > fixes
> > are tested and in the master branch.  Sljit fixes are in the release.
> 
> Huh, so who is using the new prctl() ABIs?

Any code can use the ABI, but JIT code CET-enabling part mostly do not use these
new prctl()'s, except, probably to get CET status.

> > > Where are the selftests/ for this new ABI?  Were you planning on
> > > submitting any 

Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Dave Hansen
On 5/15/20 2:33 PM, Yu-cheng Yu wrote:
> On Fri, 2020-05-15 at 11:39 -0700, Dave Hansen wrote:
>> On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
>> Can a binary compiled with CET run without CET?
> 
> Yes, but a few details:
> 
> - The shadow stack is transparent to the application.  A CET application does
> not have anything different from a non-CET application.  However, if a CET
> application uses any CET instructions (e.g. INCSSP), it must first check if 
> CET
> is turned on.
> - If an application is compiled for IBT, the compiler inserts ENDBRs at branch
> targets.  These are nops if IBT is not on.

I appreciate the detailed response, but it wasn't quite what I was
asking.  Let's ignore IBT for now and just talk about shadow stacks.

An app compiled with the new ELF flags and running on a CET-enabled
kernel and CPU will start off with shadow stacks allocated and enabled,
right?  It can turn its shadow stack off per-thread with the new prctl.
 But, otherwise, it's stuck, the only way to turn shadow stacks off at
startup would be editing the binary.

Basically, if there ends up being a bug in an app that violates the
shadow stack rules, the app is broken, period.  The only recourse is to
have the kernel disable CET and reboot.

Is that right?

>> Can a binary compiled without CET run CET-enabled code?
> 
> Partially yes, but in reality somewhat difficult.
...
> - If a not-CET application does fork(), and the child wants to turn on CET, it
> would be difficult to manage the stack frames, unless the child knows what is 
> is
> doing.  

It might be hard to do, but it is possible with the patches you posted?
 I think you're saying that the CET-enabled binary would do
arch_setup_elf_property() when it was first exec()'d.  Later, it could
use the new prctl(ARCH_X86_CET_DISABLE) to disable its shadow stack,
then fork() and the child would not be using CET.  Right?

What is ARCH_X86_CET_DISABLE used for, anyway?

> The JIT examples I mentioned previously run with CET enabled from the
> beginning.  Do you have a reason to do this?  In other words, if the JIT code
> needs CET, the app could have started with CET in the first place.

Let's say I have a JIT'd sandbox.  I want the sandbox to be
CET-protected, but the JIT engine itself not to be.

> - If you are asking about dlopen(), the library will have the same setting as
> the main application.  Do you have any reason to have a library running with
> CET, but the application does not have CET?

Sure, using old binaries.  That's why IBT has a legacy bitmap and things
like MPX had ways of jumping into old non-enabled binaries.

>> Can different threads in a process have different CET enabling state?
> 
> Yes, if the parent starts with CET, children can turn it off.

How would that work, though?  clone() by default will copy the parent
xsave state, which means it will be CET-enabled, which means it needs a
shadow stack.  So, if I want a CET-free child thread, I need to clone(),
then turn CET off, then free the shadow stack?

>> Does this *code* work?  Could you please indicate which JITs have been
>> enabled to use the code in this series?  How much of the new ABI is in use?
> 
> JIT does not necessarily use all of the ABI.  The JIT changes mainly fix stack
> frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM JIT 
> fixes
> are tested and in the master branch.  Sljit fixes are in the release.

Huh, so who is using the new prctl() ABIs?

>> Where are the selftests/ for this new ABI?  Were you planning on
>> submitting any with this series?
> 
> The ABI is more related to the application side, and therefore most suitable 
> for
> GLIBC unit tests.

I was mostly concerned with the kernel selftests.  The things in
tools/testing/selftests/x86 in the kernel tree.

> The more complicated areas such as pthreads, signals, ucontext,
> fork() are all included there.  I have been constantly running these 
> tests without any problems.  I can provide more details if testing is
> the concern.

For something this complicated, with new kernel ABIs, we need an
in-kernel sefltest.

MPX was not that much different from this feature.  It required a
boatload of compiler and linker changes to function.  Yet, there was a
simple in-kernel test for it that didn't require *any* of that big pile
of toolchain bits.

Is there a reason we don't have one of those for CET?


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Yu-cheng Yu
On Fri, 2020-05-15 at 11:39 -0700, Dave Hansen wrote:
> On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
> > On Wed, 2020-04-29 at 16:02 -0700, Yu-cheng Yu wrote:
> > > On Wed, 2020-04-29 at 15:53 -0700, Dave Hansen wrote:
> > > > On 4/29/20 3:07 PM, Yu-cheng Yu wrote:
> > > > > +Note:
> > > > > +  There is no CET-enabling arch_prctl function.  By design, CET is 
> > > > > enabled
> > > > > +  automatically if the binary and the system can support it.
> > > > 
> > > > I think Andy and I danced around this last time.  Let me try to say it
> > > > more explicitly.
> > > > 
> > > > I want CET kernel enabling to able to be disconnected from the on-disk
> > > > binary.  I want a binary compiled with CET to be able to disable it, and
> > > > I want a binary not compiled with CET to be able to enable it.  I want
> > > > different threads in a process to be able to each have different CET 
> > > > status.
> > > 
> > > The kernel patches we have now can be modified to support this model.  If 
> > > after
> > > discussion this is favorable, I will modify code accordingly.
> > 
> > To turn on/off and to lock CET are application-level decisions.  The kernel 
> > does
> > not prevent any of those.  Should there be a need to provide an 
> > arch_prctl() to
> > turn on CET, it can be added without any conflict to this series.
> 
> I spelled out what I wanted pretty clearly.  On your next post, could
> you please directly address each of the things I asked for?  Please
> directly answer the following questions in your next post with respect
> to the code you post:
> 
> Can a binary compiled with CET run without CET?

Yes, but a few details:

- The shadow stack is transparent to the application.  A CET application does
not have anything different from a non-CET application.  However, if a CET
application uses any CET instructions (e.g. INCSSP), it must first check if CET
is turned on.
- If an application is compiled for IBT, the compiler inserts ENDBRs at branch
targets.  These are nops if IBT is not on.

> Can a binary compiled without CET run CET-enabled code?

Partially yes, but in reality somewhat difficult.

- If a non-CET application does exec() of a CET binary, then CET is enabled.
- If a not-CET application does fork(), and the child wants to turn on CET, it
would be difficult to manage the stack frames, unless the child knows what is is
doing.  The JIT examples I mentioned previously run with CET enabled from the
beginning.  Do you have a reason to do this?  In other words, if the JIT code
needs CET, the app could have started with CET in the first place.
- If you are asking about dlopen(), the library will have the same setting as
the main application.  Do you have any reason to have a library running with
CET, but the application does not have CET?

> Can different threads in a process have different CET enabling state?

Yes, if the parent starts with CET, children can turn it off.  But for the same
reason described above, it is difficult to turn on CET from the middle.

> > > > Which JITs was this tested with?  I think as a bare minimum we need to
> > > > know that this design can accommodate _a_ modern JIT.  It would be
> > > > horrible if the browser javascript engines couldn't use this design, for
> > > > instance.
> > > 
> > > JIT work is still in progress.  When that is available I will test it.
> > 
> > I found CET has been enabled in LLVM JIT, Mesa JIT as well as sljit which is
> > used by jit.  So the current model works with JIT.
> 
> Great!  I'm glad the model works.  That's not what I asked, though.
> 
> Does this *code* work?  Could you please indicate which JITs have been
> enabled to use the code in this series?  How much of the new ABI is in use?

JIT does not necessarily use all of the ABI.  The JIT changes mainly fix stack
frames and insert ENDBRs.  I do not work on JIT.  What I found is LLVM JIT fixes
are tested and in the master branch.  Sljit fixes are in the release.

> Where are the selftests/ for this new ABI?  Were you planning on
> submitting any with this series?

The ABI is more related to the application side, and therefore most suitable for
GLIBC unit tests.  The more complicated areas such as pthreads, signals,
ucontext, fork() are all included there.  I have been constantly running these
tests without any problems.  I can provide more details if testing is the
concern.

Yu-cheng



Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-15 Thread Dave Hansen
On 5/12/20 4:20 PM, Yu-cheng Yu wrote:
> On Wed, 2020-04-29 at 16:02 -0700, Yu-cheng Yu wrote:
>> On Wed, 2020-04-29 at 15:53 -0700, Dave Hansen wrote:
>>> On 4/29/20 3:07 PM, Yu-cheng Yu wrote:
 +Note:
 +  There is no CET-enabling arch_prctl function.  By design, CET is enabled
 +  automatically if the binary and the system can support it.
>>>
>>> I think Andy and I danced around this last time.  Let me try to say it
>>> more explicitly.
>>>
>>> I want CET kernel enabling to able to be disconnected from the on-disk
>>> binary.  I want a binary compiled with CET to be able to disable it, and
>>> I want a binary not compiled with CET to be able to enable it.  I want
>>> different threads in a process to be able to each have different CET status.
>>
>> The kernel patches we have now can be modified to support this model.  If 
>> after
>> discussion this is favorable, I will modify code accordingly.
> 
> To turn on/off and to lock CET are application-level decisions.  The kernel 
> does
> not prevent any of those.  Should there be a need to provide an arch_prctl() 
> to
> turn on CET, it can be added without any conflict to this series.

I spelled out what I wanted pretty clearly.  On your next post, could
you please directly address each of the things I asked for?  Please
directly answer the following questions in your next post with respect
to the code you post:

Can a binary compiled with CET run without CET?
Can a binary compiled without CET run CET-enabled code?
Can different threads in a process have different CET enabling state?

>>> Which JITs was this tested with?  I think as a bare minimum we need to
>>> know that this design can accommodate _a_ modern JIT.  It would be
>>> horrible if the browser javascript engines couldn't use this design, for
>>> instance.
>>
>> JIT work is still in progress.  When that is available I will test it.
> 
> I found CET has been enabled in LLVM JIT, Mesa JIT as well as sljit which is
> used by jit.  So the current model works with JIT.

Great!  I'm glad the model works.  That's not what I asked, though.

Does this *code* work?  Could you please indicate which JITs have been
enabled to use the code in this series?  How much of the new ABI is in use?

Where are the selftests/ for this new ABI?  Were you planning on
submitting any with this series?


Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-05-12 Thread Yu-cheng Yu
On Wed, 2020-04-29 at 16:02 -0700, Yu-cheng Yu wrote:
> On Wed, 2020-04-29 at 15:53 -0700, Dave Hansen wrote:
> > On 4/29/20 3:07 PM, Yu-cheng Yu wrote:
> > > +Note:
> > > +  There is no CET-enabling arch_prctl function.  By design, CET is 
> > > enabled
> > > +  automatically if the binary and the system can support it.
> > 
> > I think Andy and I danced around this last time.  Let me try to say it
> > more explicitly.
> > 
> > I want CET kernel enabling to able to be disconnected from the on-disk
> > binary.  I want a binary compiled with CET to be able to disable it, and
> > I want a binary not compiled with CET to be able to enable it.  I want
> > different threads in a process to be able to each have different CET status.
> 
> The kernel patches we have now can be modified to support this model.  If 
> after
> discussion this is favorable, I will modify code accordingly.

To turn on/off and to lock CET are application-level decisions.  The kernel does
not prevent any of those.  Should there be a need to provide an arch_prctl() to
turn on CET, it can be added without any conflict to this series.

> > Which JITs was this tested with?  I think as a bare minimum we need to
> > know that this design can accommodate _a_ modern JIT.  It would be
> > horrible if the browser javascript engines couldn't use this design, for
> > instance.
> 
> JIT work is still in progress.  When that is available I will test it.

I found CET has been enabled in LLVM JIT, Mesa JIT as well as sljit which is
used by jit.  So the current model works with JIT.

Yu-cheng



Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-04-29 Thread Yu-cheng Yu
On Wed, 2020-04-29 at 15:53 -0700, Dave Hansen wrote:
> On 4/29/20 3:07 PM, Yu-cheng Yu wrote:
> > +Note:
> > +  There is no CET-enabling arch_prctl function.  By design, CET is enabled
> > +  automatically if the binary and the system can support it.
> 
> I think Andy and I danced around this last time.  Let me try to say it
> more explicitly.
> 
> I want CET kernel enabling to able to be disconnected from the on-disk
> binary.  I want a binary compiled with CET to be able to disable it, and
> I want a binary not compiled with CET to be able to enable it.  I want
> different threads in a process to be able to each have different CET status.

The kernel patches we have now can be modified to support this model.  If after
discussion this is favorable, I will modify code accordingly.

> Which JITs was this tested with?  I think as a bare minimum we need to
> know that this design can accommodate _a_ modern JIT.  It would be
> horrible if the browser javascript engines couldn't use this design, for
> instance.

JIT work is still in progress.  When that is available I will test it.

Yu-cheng



Re: [PATCH v10 01/26] Documentation/x86: Add CET description

2020-04-29 Thread Dave Hansen
On 4/29/20 3:07 PM, Yu-cheng Yu wrote:
> +Note:
> +  There is no CET-enabling arch_prctl function.  By design, CET is enabled
> +  automatically if the binary and the system can support it.

I think Andy and I danced around this last time.  Let me try to say it
more explicitly.

I want CET kernel enabling to able to be disconnected from the on-disk
binary.  I want a binary compiled with CET to be able to disable it, and
I want a binary not compiled with CET to be able to enable it.  I want
different threads in a process to be able to each have different CET status.

Which JITs was this tested with?  I think as a bare minimum we need to
know that this design can accommodate _a_ modern JIT.  It would be
horrible if the browser javascript engines couldn't use this design, for
instance.