[PATCH v2] x86-64/cet: Check the restore token in longjmp

H.J. Lu hjl.tools@gmail.com
Tue Jan 9 03:41:09 GMT 2024


On Mon, Jan 8, 2024 at 7:06 PM Edgecombe, Rick P
<rick.p.edgecombe@intel.com> wrote:
>
> +Shadow stack folks
>
> Context:
> https://inbox.sourceware.org/libc-alpha/20240102150329.3152784-1-hjl.tools@gmail.com/
>
> On Tue, 2024-01-02 at 07:03 -0800, H.J. Lu wrote:
> > Changes in v2:
> >
> > 1. Merge __longjmp.S and __longjmp_chk.S by adding
> > CHECK_INVALID_LONGJMP.
> > 2. Remove a branch in the restore token searching loop.
> > 3. Cache the target shadow stack pointer.
> >
> > setcontext and swapcontext put a restore token on the old shadow
> > stack
> > which is used to restore the target shadow stack when switching user
> > contexts.  When longjmp from a user context, the target shadow stack
> > can be different from the current shadow stack and INCSSP can't be
> > used to restore the shadow stack pointer to the target shadow stack.
> >
> > Update longjmp to search for a restore token.  If found, use the
> > token
> > to restore the shadow stack pointer before using INCSSP to pop the
> > shadow stack.  Stop the token search and use INCSSP if the shadow
> > stack
> > entry value is the same as the current shadow stack pointer.
> >
> > It is a user error if there is a shadow stack switch without leaving
> > a
> > restore token on the old shadow stack.
> >
> > The only difference between __longjmp.S and __longjmp_chk.S is that
> > __longjmp_chk.S has a check for invalid longjmp usages.  Merge
> > __longjmp.S and __longjmp_chk.S by adding the CHECK_INVALID_LONGJMP
> > macro.
>
> Hi,
>
> I realize this is upstream already, but just to follow up from our
> earlier conversation... It indeed seems a different algorithm than you
> proposed earlier - you got rid of the zero frame checking. I can't see
> any problems with this one as far as running off the shadow stack goes.
> (except custom stack switching scenario, as discussed)
>
> I think we also discussed in the past that it is ok to consume the
> token that might have been left for ucontext usage, because once a
> program longjmp()'s, it shouldn't assume anything up the stack is still
> there.
>
> Is there anyway in the x86 ABI docs we could codify that programs doing
> their own shadow stack switching should take care to always leave a
> token? Otherwise it seems the requirement would be hidden in the glibc
> commit logs.

This applies to all shadow stack implementations, not just Linux.   I
could add a paragraph to x86-64 psABI.  But I think this belongs to
a white paper for shadow stack.

> And I guess this means alt shadow stacks would really stick out as
> requiring WRSS for longjmp() and we should try to make it work. And if
> WRSS will be uncommon we should try to make clone3 consume a token, to
> sort of match the security level.

As I mentioned in the shadow stack meeting today,  if we overwrote the last
shadow entry with a restore token, rstorssp couldn't fully restore the shadow
stack and longjmp might not work in some cases.  We should avoid WRSS
if possible.

> Sound good everyone?



-- 
H.J.


More information about the Libc-alpha mailing list