[PATCH 11/17] x86/cet: Sync with Linux kernel 6.6 shadow stack interface
szabolcs.nagy@arm.com
szabolcs.nagy@arm.com
Tue Dec 19 17:15:50 GMT 2023
The 12/18/2023 11:06, H.J. Lu wrote:
> On Mon, Dec 18, 2023 at 2:54 AM szabolcs.nagy@arm.com
> <szabolcs.nagy@arm.com> wrote:
> > it does if it scans.
> >
> > for (;; targetssp--) {
> > if (targetssp == ssp) do_samestack();
> > if (*targetssp == restoretoken) do_differentstack();
> > }
> >
> > the only problem i see is if the target shadow stack is
> > different from the current one and does not end in a restore
> > token. but i think that is a user error.
>
> Yes, it works. But it is hard to tell its performance overhead.
>
> > if we plan to introduce altshadowstack then this does not
> > work in case of shadow stack overflow because the overflowed
> > shadow stack cannot be jumped to even though in practice we
> > want that to work.
> >
>
> I'd like to support shadow stack in glibc 2.39. Since my patch
> doesn't enable shadow stack by default, it doesn't have any
> functionality impact on users. It allows us to evaluate shadow
> stack support in all packages. We may need to use WRUSS
> to enable shadow stack for some packages. But users and
> developers can't see how shadow stack works if shadow stack
> can't be turned on.
ok.
> From 3dba6d876db6a47b66a680bb4aa85b1db63aa3f8 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Wed, 13 Dec 2023 17:50:47 -0800
> Subject: [PATCH] x86-64/cet: Check the restore token in longjmp
>
> setcontext and swapcontext put a restore token on the old shadow stack
> so that they switch to a different 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.
looks good except missing saveprevssp below
> ---
> sysdeps/x86_64/__longjmp.S | 28 +++++++++++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S
> index 9ac075e0a8..b106affdcd 100644
> --- a/sysdeps/x86_64/__longjmp.S
> +++ b/sysdeps/x86_64/__longjmp.S
> @@ -63,9 +63,35 @@ ENTRY(__longjmp)
> /* Check and adjust the Shadow-Stack-Pointer. */
> /* Get the current ssp. */
> rdsspq %rax
> + /* Save the current ssp. */
> + movq %rax, %r10
> /* And compare it with the saved ssp value. */
> - subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax
> + movq SHADOW_STACK_POINTER_OFFSET(%rdi), %rcx
> + subq %rcx, %rax
> je L(skip_ssp)
> +
> +L(find_restore_token_loop):
> + /* Look for a restore token. */
> + movq -8(%rcx), %rbx
> + andq $-8, %rbx
> + cmpq %rcx, %rbx
> + /* Find the restore token. */
> + je L(restore_shadow_stack)
> +
> + /* Try the next slot. */
> + subq $8, %rcx
> + /* Stop if the current ssp is found. */
> + cmpq %rcx, %r10
> + je L(no_shadow_stack_token)
> + jmp L(find_restore_token_loop)
> +
> +L(restore_shadow_stack):
> + /* Restore the target shadow stack. */
> + rstorssp -8(%rcx)
> + rdsspq %rax
> + subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax
> +
i'd use saveprevssp in this case so the old shadow stack
remains resumable with a later longjmp.
> +L(no_shadow_stack_token):
> /* Count the number of frames to adjust and adjust it
> with incssp instruction. The instruction can adjust
> the ssp by [0..255] value only thus use a loop if
> --
> 2.43.0
>
More information about the Libc-alpha
mailing list