[PATCH v3 3/9] x86/cet: Sync with Linux kernel 6.6 shadow stack interface
Noah Goldstein
goldstein.w.n@gmail.com
Wed Dec 20 20:53:20 GMT 2023
On Tue, Dec 19, 2023 at 8:08 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Sync with Linux kernel 6.6 shadow stack interface. Since only x86-64 is
> supported, i386 shadow stack codes are unchanged and CET shouldn't be
> enabled for i386.
>
> 1. When the shadow stack base in TCB is unset, the default shadow stack
> is in use. Use the current shadow stack pointer as the marker for the
> default shadow stack. It is used to identify if the current shadow stack
> is the same as the target shadow stack when switching ucontexts. If yes,
> INCSSP will be used to unwind shadow stack. Otherwise, shadow stack
> restore token will be used.
> 2. Allocate shadow stack with the map_shadow_stack syscall. Since there
> is no function to explicitly release ucontext, there is no place to
> release shadow stack allocated by map_shadow_stack in ucontext functions.
> Such shadow stacks will be leaked.
> 3. Rename arch_prctl CET commands to ARCH_SHSTK_XXX.
> 4. Rewrite the CET control functions with the current kernel shadow stack
> interface.
>
> Since CET is no longer enabled by kernel, a separate patch will enable
> shadow stack during startup.
> ---
> sysdeps/unix/sysv/linux/x86/Makefile | 1 +
> .../sysv/linux/x86/allocate-shadow-stack.c | 62 +++++++++++++++++++
> .../sysv/linux/x86/allocate-shadow-stack.h | 27 ++++++++
> sysdeps/unix/sysv/linux/x86/bits/mman.h | 5 ++
> sysdeps/unix/sysv/linux/x86/cpu-features.c | 13 ++--
> sysdeps/unix/sysv/linux/x86/dl-cet.h | 16 +++--
> .../unix/sysv/linux/x86/include/asm/prctl.h | 37 +++++------
> .../sysv/linux/x86/tst-cet-setcontext-1.c | 17 +++--
> .../unix/sysv/linux/x86_64/__start_context.S | 38 +++---------
> sysdeps/unix/sysv/linux/x86_64/getcontext.S | 30 ++-------
> sysdeps/unix/sysv/linux/x86_64/makecontext.c | 29 +++++----
> sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 22 ++-----
> sysdeps/x86/cpu-features.c | 15 +++--
> sysdeps/x86/dl-cet.c | 2 +-
> sysdeps/x86_64/nptl/tls.h | 2 +-
> 15 files changed, 184 insertions(+), 132 deletions(-)
> create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c
> create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h
>
> diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
> index 9dfdd689a9..ed0d6500b9 100644
> --- a/sysdeps/unix/sysv/linux/x86/Makefile
> +++ b/sysdeps/unix/sysv/linux/x86/Makefile
> @@ -44,6 +44,7 @@ CFLAGS-tst-cet-vfork-1.c += -mshstk
> endif
>
> ifeq ($(subdir),stdlib)
> +sysdep_routines += allocate-shadow-stack
> tests += tst-cet-setcontext-1
> CFLAGS-tst-cet-setcontext-1.c += -mshstk
> endif
> diff --git a/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c
> new file mode 100644
> index 0000000000..d7938b6ea9
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c
> @@ -0,0 +1,62 @@
> +/* Helper function to allocate shadow stack.
> + Copyright (C) 2023 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <stdint.h>
> +#include <errno.h>
> +#include <sys/mman.h>
> +#include <libc-pointer-arith.h>
> +#include <allocate-shadow-stack.h>
> +
> +/* NB: This can be treated as a syscall by caller. */
> +
> +#ifndef __x86_64__
> +__attribute__ ((regparm (2)))
can you just add inl assembly constraints instead of this?
> +#endif
> +long int
> +__allocate_shadow_stack (size_t stack_size,
> + shadow_stack_size_t *child_stack)
> +{
> +#ifdef __NR_map_shadow_stack
> + size_t shadow_stack_size
> + = stack_size >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT;
> + /* Align shadow stack to 8 bytes. */
> + shadow_stack_size = ALIGN_UP (shadow_stack_size, 8);
> + /* Since sigaltstack shares shadow stack with the current context in
> + the thread, add extra 20 stack frames in shadow stack for signal
> + handlers. */
> +# ifdef __x86_64__
> + shadow_stack_size += 20 * 8;
> +# else
> + shadow_stack_size += 20 * 4;
> +# endif
> + void *shadow_stack = (void *)INLINE_SYSCALL_CALL
> + (map_shadow_stack, NULL, shadow_stack_size, SHADOW_STACK_SET_TOKEN);
> + /* Report the map_shadow_stack error. */
> + if (shadow_stack == MAP_FAILED)
> + return -errno;
> +
> + /* Save the shadow stack base and size on child stack. */
> + child_stack[0] = (uintptr_t) shadow_stack;
> + child_stack[1] = shadow_stack_size;
> +
> + return 0;
> +#else
> + return -ENOSYS;
> +#endif
> +}
> diff --git a/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h
> new file mode 100644
> index 0000000000..834373e0d3
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h
> @@ -0,0 +1,27 @@
> +/* Helper function to allocate shadow stack.
> + Copyright (C) 2023 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <ucontext.h>
> +
> +typedef __typeof (((ucontext_t *) 0)->__ssp[0]) shadow_stack_size_t;
> +
> +extern long int __allocate_shadow_stack (size_t, shadow_stack_size_t *)
> +#ifndef __x86_64__
> + __attribute__ ((regparm (2)))
> +#endif
> + attribute_hidden;
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h
> index 3d356e86a0..221f7c82bd 100644
> --- a/sysdeps/unix/sysv/linux/x86/bits/mman.h
> +++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h
> @@ -27,6 +27,11 @@
> #define MAP_32BIT 0x40 /* Only give out 32-bit addresses. */
> #define MAP_ABOVE4G 0x80 /* Only map above 4GB. */
>
> +#ifdef __USE_MISC
> +/* Set up a restore token in the newly allocatd shadow stack */
allocatd -> allocated
> +# define SHADOW_STACK_SET_TOKEN 0x1
> +#endif
> +
> #include <bits/mman-map-flags-generic.h>
>
> /* Include generic Linux declarations. */
> diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> index 41e7600668..0e6e2bf855 100644
> --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> @@ -23,10 +23,15 @@
> static inline int __attribute__ ((always_inline))
> get_cet_status (void)
> {
> - unsigned long long cet_status[3];
> - if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_STATUS, cet_status) == 0)
> - return cet_status[0];
> - return 0;
> + unsigned long long kernel_feature;
> + unsigned int status = 0;
> + if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS,
> + &kernel_feature) == 0)
> + {
> + if ((kernel_feature & ARCH_SHSTK_SHSTK) != 0)
> + status = GNU_PROPERTY_X86_FEATURE_1_SHSTK;
> + }
> + return status;
> }
>
> # ifndef SHARED
> diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> index c885bf1323..da220ac627 100644
> --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
> +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> @@ -21,12 +21,20 @@
> static inline int __attribute__ ((always_inline))
> dl_cet_disable_cet (unsigned int cet_feature)
> {
> - return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_DISABLE,
> - cet_feature);
> + if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK)
> + return -1;
> + long long int kernel_feature = ARCH_SHSTK_SHSTK;
> + return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISABLE,
> + kernel_feature);
> }
>
> static inline int __attribute__ ((always_inline))
> -dl_cet_lock_cet (void)
> +dl_cet_lock_cet (unsigned int cet_feature)
> {
> - return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_LOCK, 0);
> + if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK)
> + return -1;
> + /* Lock all SHSTK features. */
> + long long int kernel_feature = -1;
> + return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK,
> + kernel_feature);
> }
> diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
> index 45ad0b052f..2f511321ad 100644
> --- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
> +++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
> @@ -4,24 +4,19 @@
>
> #include_next <asm/prctl.h>
>
> -#ifndef ARCH_CET_STATUS
> -/* CET features:
> - IBT: GNU_PROPERTY_X86_FEATURE_1_IBT
> - SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
> - */
> -/* Return CET features in unsigned long long *addr:
> - features: addr[0].
> - shadow stack base address: addr[1].
> - shadow stack size: addr[2].
> - */
> -# define ARCH_CET_STATUS 0x3001
> -/* Disable CET features in unsigned int features. */
> -# define ARCH_CET_DISABLE 0x3002
> -/* Lock all CET features. */
> -# define ARCH_CET_LOCK 0x3003
Are these not already part of the API?
> -/* Allocate a new shadow stack with unsigned long long *addr:
> - IN: requested shadow stack size: *addr.
> - OUT: allocated shadow stack address: *addr.
> - */
> -# define ARCH_CET_ALLOC_SHSTK 0x3004
> -#endif /* ARCH_CET_STATUS */
> +#ifndef ARCH_SHSTK_ENABLE
> +/* Enable SHSTK features in unsigned long int features. */
> +# define ARCH_SHSTK_ENABLE 0x5001
> +/* Disable SHSTK features in unsigned long int features. */
> +# define ARCH_SHSTK_DISABLE 0x5002
> +/* Lock SHSTK features in unsigned long int features. */
> +# define ARCH_SHSTK_LOCK 0x5003
> +/* Unlock SHSTK features in unsigned long int features. */
> +# define ARCH_SHSTK_UNLOCK 0x5004
> +/* Return SHSTK features in unsigned long int features. */
> +# define ARCH_SHSTK_STATUS 0x5005
> +
> +/* ARCH_SHSTK_ features bits */
> +# define ARCH_SHSTK_SHSTK 0x1
> +# define ARCH_SHSTK_WRSS 0x2
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c
> index 837a9fd0eb..2ea66c803b 100644
> --- a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c
> +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c
> @@ -87,15 +87,14 @@ do_test (void)
> ctx[4].uc_link = &ctx[0];
> makecontext (&ctx[4], (void (*) (void)) f1, 0);
>
> - /* NB: When shadow stack is enabled, makecontext calls arch_prctl
> - with ARCH_CET_ALLOC_SHSTK to allocate a new shadow stack which
> - can be unmapped. The base address and size of the new shadow
> - stack are returned in __ssp[1] and __ssp[2]. makecontext is
> - called for CTX1, CTX3 and CTX4. But only CTX1 is used. New
> - shadow stacks are allocated in the order of CTX3, CTX1, CTX4.
> - It is very likely that CTX1's shadow stack is placed between
> - CTX3 and CTX4. We munmap CTX3's and CTX4's shadow stacks to
> - create gaps above and below CTX1's shadow stack. We check
> + /* NB: When shadow stack is enabled, makecontext calls map_shadow_stack
> + to allocate a new shadow stack which can be unmapped. The base
> + address and size of the new shadow stack are returned in __ssp[1]
> + and __ssp[2]. makecontext is called for CTX1, CTX3 and CTX4. But
> + only CTX1 is used. New shadow stacks are allocated in the order
> + of CTX3, CTX1, CTX4. It is very likely that CTX1's shadow stack is
> + placed between CTX3 and CTX4. We munmap CTX3's and CTX4's shadow
> + stacks to create gaps above and below CTX1's shadow stack. We check
> that setcontext CTX1 works correctly in this case. */
> if (_get_ssp () != 0)
> {
> diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> index f6436dd6bb..ae04203c90 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> @@ -24,20 +24,14 @@
> /* Use CALL to push __start_context onto the new stack as well as the new
> shadow stack. RDI points to ucontext:
> Incoming:
> - __ssp[0]: The original caller's shadow stack pointer.
> - __ssp[1]: The size of the new shadow stack.
> - __ssp[2]: The size of the new shadow stack.
> - Outgoing:
> __ssp[0]: The new shadow stack pointer.
> __ssp[1]: The base address of the new shadow stack.
> __ssp[2]: The size of the new shadow stack.
> */
>
> ENTRY(__push___start_context)
below in __start_constext rbx is used. Does it need to be saved/restored?
> - /* Save the pointer to ucontext. */
> - movq %rdi, %r9
> /* Get the original shadow stack pointer. */
> - rdsspq %r8
> + rdsspq %rcx
> /* Save the original stack pointer. */
> movq %rsp, %rdx
> /* Load the top of the new stack into RSI. */
> @@ -45,24 +39,12 @@ ENTRY(__push___start_context)
> /* Add 8 bytes to RSI since CALL will push the 8-byte return
> address onto stack. */
> leaq 8(%rsi), %rsp
> - /* Allocate the new shadow stack. The size of the new shadow
> - stack is passed in __ssp[1]. */
> - lea (oSSP + 8)(%rdi), %RSI_LP
> - movl $ARCH_CET_ALLOC_SHSTK, %edi
> - movl $__NR_arch_prctl, %eax
> - /* The new shadow stack base is returned in __ssp[1]. */
> - syscall
> - testq %rax, %rax
> - jne L(hlt) /* This should never happen. */
> -
> - /* Get the size of the new shadow stack. */
> - movq 8(%rsi), %rdi
> -
> - /* Get the base address of the new shadow stack. */
> - movq (%rsi), %rsi
> -
> + /* The size of the new shadow stack is stored in __ssp[2]. */
> + mov (oSSP + 16)(%rdi), %RSI_LP
> + /* The new shadow stack base is stored in __ssp[1]. */
> + mov (oSSP + 8)(%rdi), %RAX_LP
> /* Use the restore stoken to restore the new shadow stack. */
> - rstorssp -8(%rsi, %rdi)
> + rstorssp -8(%rax, %rsi)
>
> /* Save the restore token on the original shadow stack. */
> saveprevssp
> @@ -73,18 +55,12 @@ ENTRY(__push___start_context)
> jmp __start_context
> 1:
>
> - /* Get the new shadow stack pointer. */
> - rdsspq %rdi
> -
> /* Use the restore stoken to restore the original shadow stack. */
> - rstorssp -8(%r8)
> + rstorssp -8(%rcx)
>
> /* Save the restore token on the new shadow stack. */
> saveprevssp
>
> - /* Store the new shadow stack pointer in __ssp[0]. */
> - movq %rdi, oSSP(%r9)
> -
> /* Restore the original stack. */
> mov %rdx, %rsp
> ret
> diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> index a00e2f6290..71f3802dca 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> @@ -58,35 +58,15 @@ ENTRY(__getcontext)
> testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
> jz L(no_shstk)
>
> - /* Save RDI in RDX which won't be clobbered by syscall. */
> - movq %rdi, %rdx
> -
> xorl %eax, %eax
> cmpq %fs:SSP_BASE_OFFSET, %rax
> jnz L(shadow_stack_bound_recorded)
>
> - /* Get the base address and size of the default shadow stack
> - which must be the current shadow stack since nothing has
> - been recorded yet. */
> - sub $24, %RSP_LP
> - mov %RSP_LP, %RSI_LP
> - movl $ARCH_CET_STATUS, %edi
> - movl $__NR_arch_prctl, %eax
> - syscall
> - testq %rax, %rax
> - jz L(continue_no_err)
> -
> - /* This should never happen. */
> - hlt
> -
> -L(continue_no_err):
> - /* Record the base of the current shadow stack. */
> - movq 8(%rsp), %rax
> + /* When the shadow stack base is unset, the default shadow
> + stack is in use. Use the current shadow stack pointer
> + as the marker for the default shadow stack. */
> + rdsspq %rax
> movq %rax, %fs:SSP_BASE_OFFSET
> - add $24, %RSP_LP
> -
> - /* Restore RDI. */
> - movq %rdx, %rdi
>
> L(shadow_stack_bound_recorded):
> /* Get the current shadow stack pointer. */
> @@ -94,7 +74,7 @@ L(shadow_stack_bound_recorded):
> /* NB: Save the caller's shadow stack so that we can jump back
> to the caller directly. */
> addq $8, %rax
> - movq %rax, oSSP(%rdx)
> + movq %rax, oSSP(%rdi)
>
> /* Save the current shadow stack base in ucontext. */
> movq %fs:SSP_BASE_OFFSET, %rax
> diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> index de9e03eb81..788b730132 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> @@ -24,6 +24,8 @@
> # include <pthread.h>
> # include <libc-pointer-arith.h>
> # include <sys/prctl.h>
> +# include <sys/mman.h>
> +# include <allocate-shadow-stack.h>
> #endif
>
> #include "ucontext_i.h"
> @@ -88,23 +90,24 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
> if ((feature_1 & X86_FEATURE_1_SHSTK) != 0)
> {
> /* Shadow stack is enabled. We need to allocate a new shadow
> - stack. */
> - unsigned long ssp_size = (((uintptr_t) sp
> - - (uintptr_t) ucp->uc_stack.ss_sp)
> - >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT);
> - /* Align shadow stack to 8 bytes. */
> - ssp_size = ALIGN_UP (ssp_size, 8);
> -
> - ucp->__ssp[1] = ssp_size;
> - ucp->__ssp[2] = ssp_size;
> -
> - /* Call __push___start_context to allocate a new shadow stack,
> - push __start_context onto the new stack as well as the new
> - shadow stack. NB: After __push___start_context returns,
> + stack. NB:
> ucp->__ssp[0]: The new shadow stack pointer.
> ucp->__ssp[1]: The base address of the new shadow stack.
> ucp->__ssp[2]: The size of the new shadow stack.
> */
> + long int ret
> + = __allocate_shadow_stack (((uintptr_t) sp
> + - (uintptr_t) ucp->uc_stack.ss_sp),
> + &ucp->__ssp[1]);
> + if (ret != 0)
> + {
> + /* FIXME: What should we do? */
> + abort ();
> + }
> +
> + ucp->__ssp[0] = ucp->__ssp[1] + ucp->__ssp[2] - 8;
> + /* Call __push___start_context to push __start_context onto the new
> + stack as well as the new shadow stack. */
> __push___start_context (ucp);
> }
> else
> diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> index 5925752164..2f2fe9875b 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> @@ -109,25 +109,11 @@ ENTRY(__swapcontext)
> cmpq %fs:SSP_BASE_OFFSET, %rax
> jnz L(shadow_stack_bound_recorded)
>
> - /* Get the base address and size of the default shadow stack
> - which must be the current shadow stack since nothing has
> - been recorded yet. */
> - sub $24, %RSP_LP
> - mov %RSP_LP, %RSI_LP
> - movl $ARCH_CET_STATUS, %edi
> - movl $__NR_arch_prctl, %eax
> - syscall
> - testq %rax, %rax
> - jz L(continue_no_err)
> -
> - /* This should never happen. */
> - hlt
> -
> -L(continue_no_err):
> - /* Record the base of the current shadow stack. */
> - movq 8(%rsp), %rax
> + /* When the shadow stack base is unset, the default shadow
> + stack is in use. Use the current shadow stack pointer
> + as the marker for the default shadow stack. */
> + rdsspq %rax
> movq %rax, %fs:SSP_BASE_OFFSET
> - add $24, %RSP_LP
>
> L(shadow_stack_bound_recorded):
> /* If we unwind the stack, we can't undo stack unwinding. Just
> diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
> index 0bf923d48b..f180f0d9a4 100644
> --- a/sysdeps/x86/cpu-features.c
> +++ b/sysdeps/x86/cpu-features.c
> @@ -1121,8 +1121,9 @@ no_cpuid:
>
> # ifndef SHARED
> /* Check if IBT and SHSTK are enabled by kernel. */
> - if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT)
> - || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
> + if ((cet_status
> + & (GNU_PROPERTY_X86_FEATURE_1_IBT
> + | GNU_PROPERTY_X86_FEATURE_1_SHSTK)))
> {
> /* Disable IBT and/or SHSTK if they are enabled by kernel, but
> disabled by environment variable:
> @@ -1131,9 +1132,11 @@ no_cpuid:
> */
> unsigned int cet_feature = 0;
> if (!CPU_FEATURE_USABLE (IBT))
> - cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
> + cet_feature |= (cet_status
> + & GNU_PROPERTY_X86_FEATURE_1_IBT);
> if (!CPU_FEATURE_USABLE (SHSTK))
> - cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
> + cet_feature |= (cet_status
> + & GNU_PROPERTY_X86_FEATURE_1_SHSTK);
>
> if (cet_feature)
> {
> @@ -1148,7 +1151,9 @@ no_cpuid:
> lock CET if IBT or SHSTK is enabled permissively. */
> if (GL(dl_x86_feature_control).ibt != cet_permissive
> && GL(dl_x86_feature_control).shstk != cet_permissive)
> - dl_cet_lock_cet ();
> + dl_cet_lock_cet (GL(dl_x86_feature_1)
> + & (GNU_PROPERTY_X86_FEATURE_1_IBT
> + | GNU_PROPERTY_X86_FEATURE_1_SHSTK));
> }
> # endif
> }
> diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
> index 67c51ee8c2..8b911fd931 100644
> --- a/sysdeps/x86/dl-cet.c
> +++ b/sysdeps/x86/dl-cet.c
> @@ -201,7 +201,7 @@ dl_cet_check_startup (struct link_map *m, struct dl_cet_info *info)
> feature_1_lock |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
>
> if (feature_1_lock != 0
> - && dl_cet_lock_cet () != 0)
> + && dl_cet_lock_cet (feature_1_lock) != 0)
> _dl_fatal_printf ("%s: can't lock CET\n", info->program);
> }
>
> diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
> index 1403f939f7..4bcc2552a1 100644
> --- a/sysdeps/x86_64/nptl/tls.h
> +++ b/sysdeps/x86_64/nptl/tls.h
> @@ -60,7 +60,7 @@ typedef struct
> void *__private_tm[4];
> /* GCC split stack support. */
> void *__private_ss;
> - /* The lowest address of shadow stack, */
> + /* The marker for the current shadow stack. */
> unsigned long long int ssp_base;
> /* Must be kept even if it is no longer used by glibc since programs,
> like AddressSanitizer, depend on the size of tcbhead_t. */
> --
> 2.43.0
>
More information about the Libc-alpha
mailing list