Re: [PATCH 04/10] x86/cet: Handle thread shadow stack

From: Florian Weimer
Date: Fri Jun 08 2018 - 10:53:18 EST


On 06/07/2018 10:53 PM, Andy Lutomirski wrote:
On Thu, Jun 7, 2018 at 12:47 PM Florian Weimer <fweimer@xxxxxxxxxx> wrote:

On 06/07/2018 08:21 PM, Andy Lutomirski wrote:
On Thu, Jun 7, 2018 at 7:41 AM Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> wrote:

When fork() specifies CLONE_VM but not CLONE_VFORK, the child
needs a separate program stack and a separate shadow stack.
This patch handles allocation and freeing of the thread shadow
stack.

Aha -- you're trying to make this automatic. I'm not convinced this
is a good idea. The Linux kernel has a long and storied history of
enabling new hardware features in ways that are almost entirely
useless for userspace.

Florian, do you have any thoughts on how the user/kernel interaction
for the shadow stack should work?

I have not looked at this in detail, have not played with the emulator,
and have not been privy to any discussions before these patches have
been posted, however â

I believe that we want as little code in userspace for shadow stack
management as possible. One concern I have is that even with the code
we arguably need for various kinds of stack unwinding, we might have
unwittingly built a generic trampoline that leads to full CET bypass.

I was imagining an API like "allocate a shadow stack for the current
thread, fail if the current thread already has one, and turn on the
shadow stack". glibc would call clone and then call this ABI pretty
much immediately (i.e. before making any calls from which it expects
to return).

Ahh. So you propose not to enable shadow stack enforcement on the new thread even if it is enabled for the current thread? For the cases where CLONE_VM is involved?

It will still need a new assembler wrapper which sets up the shadow stack, and it's probably required to disable signals.

I think it should be reasonable safe and actually implementable. But the benefits are not immediately obvious to me.

We definitely want strong enough user control that tools like CRIU can
continue to work. I haven't looked at the SDM recently enough to
remember for sure, but I'm reasonably confident that user code can
learn the address of its own shadow stack. If nothing else, CRIU
needs to be able to restore from a context where there's a signal on
the stack and the signal frame contains a shadow stack pointer.

CRIU also needs the shadow stack *contents*, which shouldn't be directly available to the process. So it needs very special interfaces anyway.

Does CRIU implement MPX support?

Thanks,
Florian