Thread (98 messages) 98 messages, 13 authors, 2018-06-26

Re: [PATCH 00/10] Control Flow Enforcement - Part (3)

From: Yu-cheng Yu <hidden>
Date: 2018-06-12 17:27:53
Also in: linux-arch, linux-mm, lkml

On Tue, 2018-06-12 at 09:31 -0700, Andy Lutomirski wrote:
On Tue, Jun 12, 2018 at 9:24 AM Yu-cheng Yu [off-list ref] wrote:
quoted
On Tue, 2018-06-12 at 09:00 -0700, Andy Lutomirski wrote:
quoted
On Tue, Jun 12, 2018 at 8:06 AM Yu-cheng Yu [off-list ref] wrote:
quoted
On Tue, 2018-06-12 at 20:56 +1000, Balbir Singh wrote:
quoted
On 08/06/18 00:37, Yu-cheng Yu wrote:
quoted
This series introduces CET - Shadow stack

At the high level, shadow stack is:

    Allocated from a task's address space with vm_flags VM_SHSTK;
    Its PTEs must be read-only and dirty;
    Fixed sized, but the default size can be changed by sys admin.

For a forked child, the shadow stack is duplicated when the next
shadow stack access takes place.

For a pthread child, a new shadow stack is allocated.

The signal handler uses the same shadow stack as the main program.
Even with sigaltstack()?


Balbir Singh.
Yes.
I think we're going to need some provision to add an alternate signal
stack to handle the case where the shadow stack overflows.
The shadow stack stores only return addresses; its consumption will not
exceed a percentage of (program stack size + sigaltstack size) before
those overflow.  When that happens, there is usually very little we can
do.  So we set a default shadow stack size that supports certain nested
calls and allow sys admin to adjust it.
Of course there's something you can do: add a sigaltstack-like stack
switching mechanism.  Have a reserve shadow stack and, when a signal
is delivered (possibly guarded by other conditions like "did the
shadow stack overflow"), switch to a new shadow stack and maybe write
a special token to the new shadow stack that says "signal delivery
jumped here and will restore to the previous shadow stack and
such-and-such address on return".
If (shstk size == (stack size + sigaltstack size)), then shstk will not
overflow before program stack overflows and sigaltstack also overflows.

Let me think about this.
Also, I have a couple of other questions after reading the
documentation some more:

1. Why on Earth does INCSSP only take an 8-bit number of frames to
skip?  It seems to me that code that calls setjmp() and then calls
longjmp() while nested more than 256 function call levels will crash.
GLIBC takes care of more than 256 functions calls.
2. The mnemonic RSTORSSP makes no sense to me.  RSTORSSP is a stack
*switch* operation not a stack *restore* operation, unless I'm
seriously misunderstanding.
The intention is to switch shadow stacks with tokens.  RSTORSSP restores
to a previous shadow stack address from a restore token.
3. Is there anything resembling clear documentation of the format of
the shadow stack?  That is, what types of values might be found on the
shadow stack and what do they all mean?
Only return addresses and restore tokens can be on a user-mode shadow
stack.  The restore token has the incoming shadow stack address plus one
bit indicating 64/32-bit mode.

I will put this into Documentation/x86/intel_cet.txt.
4. Usually Intel doesn't submit upstream Linux patches for ISA
extensions until the ISA is documented for real.  CET does not appear
to be documented for real.  Could Intel kindly release something that
at least claims to be authoritative documentation?

--Andy

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help