#1 Backport CET changes from glibc 2.32
Opened 3 years ago by hjl. Modified 3 years ago
source-git/ hjl/glibc hjl/cet/c8s  into  c8s

file modified
+15 -11
@@ -116,20 +116,24 @@ 

       executables (PIE) by default.

  

  '--enable-cet'

+ '--enable-cet=permissive'

       Enable Intel Control-flow Enforcement Technology (CET) support.

-      When the GNU C Library is built with '--enable-cet', the resulting

-      library is protected with indirect branch tracking (IBT) and shadow

-      stack (SHSTK).  When CET is enabled, the GNU C Library is

-      compatible with all existing executables and shared libraries.

-      This feature is currently supported on i386, x86_64 and x32 with

-      GCC 8 and binutils 2.29 or later.  Note that when CET is enabled,

-      the GNU C Library requires CPUs capable of multi-byte NOPs, like

-      x86-64 processors as well as Intel Pentium Pro or newer.

+      When the GNU C Library is built with '--enable-cet' or

+      '--enable-cet=permissive', the resulting library is protected with

+      indirect branch tracking (IBT) and shadow stack (SHSTK).  When CET

+      is enabled, the GNU C Library is compatible with all existing

+      executables and shared libraries.  This feature is currently

+      supported on i386, x86_64 and x32 with GCC 8 and binutils 2.29 or

+      later.  Note that when CET is enabled, the GNU C Library requires

+      CPUs capable of multi-byte NOPs, like x86-64 processors as well as

+      Intel Pentium Pro or newer.  With '--enable-cet', it is an error to

+      dlopen a non CET enabled shared library in CET enabled application.

+      With '--enable-cet=permissive', CET is disabled when dlopening a

+      non CET enabled shared library in CET enabled application.

  

       NOTE: '--enable-cet' has been tested for i686, x86_64 and x32 on

-      non-CET processors.  '--enable-cet' has been tested for x86_64 and

-      x32 on CET SDVs, but Intel CET support hasn't been validated for

-      i686.

+      non-CET processors.  '--enable-cet' has been tested for i686,

+      x86_64 and x32 on CET processors.

  

  '--disable-profile'

       Don't build libraries with profiling information.  You may want to

file modified
+3
@@ -259,4 +259,7 @@ 

     in i386 6 argument syscall issue).  */

  #define CAN_USE_REGISTER_ASM_EBP 0

  

+ /* The default value of x86 CET control.  */

+ #define DEFAULT_DL_X86_CET_CONTROL cet_elf_property

+ 

  #endif

file modified
+2
@@ -230,6 +230,8 @@ 

     (except those which cannot be added for some reason).  */

  struct rtld_global _rtld_global =

    {

+     /* Get architecture specific initializer.  */

+ #include <dl-procruntime.c>

      /* Generally the default presumption without further information is an

       * executable stack but this is not true for all platforms.  */

      ._dl_stack_flags = DEFAULT_STACK_PERMS,

file modified
+8 -4
@@ -147,20 +147,24 @@ 

  as dynamic position independent executables (PIE) by default.

  

  @item --enable-cet

+ @itemx --enable-cet=permissive

  Enable Intel Control-flow Enforcement Technology (CET) support.  When

- @theglibc{} is built with @option{--enable-cet}, the resulting library

+ @theglibc{} is built with @option{--enable-cet} or

+ @option{--enable-cet=permissive}, the resulting library

  is protected with indirect branch tracking (IBT) and shadow stack

  (SHSTK)@.  When CET is enabled, @theglibc{} is compatible with all

  existing executables and shared libraries.  This feature is currently

  supported on i386, x86_64 and x32 with GCC 8 and binutils 2.29 or later.

  Note that when CET is enabled, @theglibc{} requires CPUs capable of

  multi-byte NOPs, like x86-64 processors as well as Intel Pentium Pro or

- newer.

+ newer.  With @option{--enable-cet}, it is an error to dlopen a non CET

+ enabled shared library in CET enabled application.  With

+ @option{--enable-cet=permissive}, CET is disabled when dlopening a

+ non CET enabled shared library in CET enabled application.

  

  NOTE: @option{--enable-cet} has been tested for i686, x86_64 and x32

  on non-CET processors.  @option{--enable-cet} has been tested for

- x86_64 and x32 on CET SDVs, but Intel CET support hasn't been validated

- for i686.

+ i686, x86_64 and x32 on CET processors.

  

  @item --disable-profile

  Don't build libraries with profiling information.  You may want to use

file modified
+1 -1
@@ -71,7 +71,7 @@ 

    extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;

    /* Check if SHSTK is enabled by kernel.  */

    bool shstk_enabled

-     = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;

+     = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;

  

    if (l->l_info[DT_JMPREL] && lazy)

      {

@@ -30,6 +30,7 @@ 

  	.type C_SYMBOL_NAME(_mcount), @function

  	.align ALIGNARG(4)

  C_LABEL(_mcount)

+ 	_CET_ENDBR

  	/* Save the caller-clobbered registers.  */

  	pushl %eax

  	pushl %ecx
@@ -58,6 +59,7 @@ 

  	.type C_SYMBOL_NAME(__fentry__), @function

  	.align ALIGNARG(4)

  C_LABEL(__fentry__)

+ 	_CET_ENDBR

  	/* Save the caller-clobbered registers.  */

  	pushl %eax

  	pushl %ecx

@@ -15,12 +15,10 @@ 

     License along with the GNU C Library; if not, see

     <http://www.gnu.org/licenses/>.  */

  

+ #include <sysdep.h>

  #include <lowlevellock.h>

  

- 	.globl	pthread_spin_lock

- 	.type	pthread_spin_lock,@function

- 	.align	16

- pthread_spin_lock:

+ ENTRY (pthread_spin_lock)

  	mov	4(%esp), %eax

  1:	LOCK

  	decl	0(%eax)
@@ -34,4 +32,4 @@ 

  	cmpl	$0, 0(%eax)

  	jg	1b

  	jmp	2b

- 	.size	pthread_spin_lock,.-pthread_spin_lock

+ END (pthread_spin_lock)

@@ -16,15 +16,14 @@ 

     License along with the GNU C Library; if not, see

     <http://www.gnu.org/licenses/>.  */

  

- 	.globl	pthread_spin_unlock

- 	.type	pthread_spin_unlock,@function

- 	.align	16

- pthread_spin_unlock:

+ #include <sysdep.h>

+ 

+ ENTRY (pthread_spin_unlock)

  	movl	4(%esp), %eax

  	movl	$1, (%eax)

  	xorl	%eax, %eax

  	ret

- 	.size	pthread_spin_unlock,.-pthread_spin_unlock

+ END (pthread_spin_unlock)

  

  	/* The implementation of pthread_spin_init is identical.  */

  	.globl	pthread_spin_init

@@ -16,6 +16,7 @@ 

     License along with the GNU C Library; if not, see

     <http://www.gnu.org/licenses/>.  */

  

+ #include <sysdep.h>

  #include <pthread-errnos.h>

  

  
@@ -25,10 +26,7 @@ 

  # define LOCK lock

  #endif

  

- 	.globl	pthread_spin_trylock

- 	.type	pthread_spin_trylock,@function

- 	.align	16

- pthread_spin_trylock:

+ ENTRY (pthread_spin_trylock)

  	movl	4(%esp), %edx

  	movl	$1, %eax

  	xorl	%ecx, %ecx
@@ -43,4 +41,4 @@ 

  0:

  #endif

  	ret

- 	.size	pthread_spin_trylock,.-pthread_spin_trylock

+ END (pthread_spin_trylock)

file modified
+1
@@ -91,6 +91,7 @@ 

  	movl	8(%esi),%eax

  	sbbl	8(%edx),%eax

  	movl	%eax,8(%edi)

+ 	_CET_ENDBR

  	movl	12(%esi),%eax

  	sbbl	12(%edx),%eax

  	movl	%eax,12(%edi)

@@ -1,44 +0,0 @@ 

- /* Copyright (C) 2002-2018 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

-    <http://www.gnu.org/licenses/>.  */

- 

- #include <sysdep.h>

- 

- 	.text

- 	.type	_exit,@function

- 	.global	_exit

- _exit:

- 	movl	4(%esp), %ebx

- 

- 	/* Try the new syscall first.  */

- #ifdef __NR_exit_group

- 	movl	$__NR_exit_group, %eax

- 	ENTER_KERNEL

- #endif

- 

- 	/* Not available.  Now the old one.  */

- 	movl	$__NR_exit, %eax

- 	/* Don't bother using ENTER_KERNEL here.  If the exit_group

- 	   syscall is not available AT_SYSINFO isn't either.  */

- 	int	$0x80

- 

- 	/* This must not fail.  Be sure we don't return.  */

- 	hlt

- 	.size	_exit,.-_exit

- 

- libc_hidden_def (_exit)

- rtld_hidden_def (_exit)

- weak_alias (_exit, _Exit)

@@ -18,6 +18,7 @@ 

     <http://www.gnu.org/licenses/>.  */

  

  #include <sysdep.h>

+ #include <asm/prctl.h>

  

  #include "ucontext_i.h"

  
@@ -26,13 +27,7 @@ 

  	/* Load address of the context data structure.  */

  	movl	4(%esp), %eax

  

- 	/* Return value of getcontext.  EAX is the only register whose

- 	   value is not preserved.  */

- 	movl	$0, oEAX(%eax)

- 

- 	/* Save the 32-bit register values and the return address.  */

- 	movl	%ecx, oECX(%eax)

- 	movl	%edx, oEDX(%eax)

+ 	/* Save the preserved register values and the return address.  */

  	movl	%edi, oEDI(%eax)

  	movl	%esi, oESI(%eax)

  	movl	%ebp, oEBP(%eax)
@@ -48,6 +43,61 @@ 

  	movw	%fs, %dx

  	movl	%edx, oFS(%eax)

  

+ #if SHSTK_ENABLED

+ 	/* Check if shadow stack is enabled.  */

+ 	testl	$X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET

+ 	jz	L(no_shstk)

+ 

+ 	/* Save EAX in EDX.  */

+ 	movl	%eax, %edx

+ 

+ 	xorl	%eax, %eax

+ 	cmpl	%gs:SSP_BASE_OFFSET, %eax

+ 	jnz	L(shadow_stack_bound_recorded)

+ 

+ 	/* Save EBX in the first scratch register slot.  */

+ 	movl	%ebx, oSCRATCH1(%edx)

+ 

+ 	/* 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, %esp

+ 	mov	%esp, %ecx

+ 	movl	$ARCH_CET_STATUS, %ebx

+ 	movl	$__NR_arch_prctl, %eax

+ 	ENTER_KERNEL

+ 	testl	%eax, %eax

+ 	jz	L(continue_no_err)

+ 

+ 	/* This should never happen.  */

+ 	hlt

+ 

+ L(continue_no_err):

+ 	/* Restore EBX from the first scratch register slot.  */

+ 	movl	oSCRATCH1(%edx), %ebx

+ 

+ 	/* Record the base of the current shadow stack.  */

+ 	movl	8(%esp), %eax

+ 	movl	%eax, %gs:SSP_BASE_OFFSET

+ 	add	$24, %esp

+ 

+ L(shadow_stack_bound_recorded):

+ 	/* Load address of the context data structure.  */

+ 	movl	4(%esp), %eax

+ 

+ 	/* Get the current shadow stack pointer.  */

+ 	rdsspd	%edx

+ 	/* NB: Save the caller's shadow stack so that we can jump back

+ 	   to the caller directly.  */

+ 	addl	$4, %edx

+ 	movl	%edx, oSSP(%eax)

+ 

+ 	/* Save the current shadow stack base in ucontext.  */

+ 	movl	%gs:SSP_BASE_OFFSET, %edx

+ 	movl	%edx, (oSSP + 4)(%eax)

+ 

+ L(no_shstk):

+ #endif

  	/* We have separate floating-point register content memory on the

  	   stack.  We use the __fpregs_mem block in the context.  Set the

  	   links up correctly.  */

@@ -18,6 +18,7 @@ 

     <http://www.gnu.org/licenses/>.  */

  

  #include <sysdep.h>

+ #include <asm/prctl.h>

  

  #include "ucontext_i.h"

  
@@ -68,6 +69,127 @@ 

  	jnz	1b

  2:

  

+ #if SHSTK_ENABLED

+ 	/* Check if Shadow Stack is enabled.  */

+ 	testl	$X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET

+ 	jz	L(skip_ssp)

+ 

+ 	/* Reload the pointer to ucontext.  */

+ 	movl	4(%esp), %eax

+ 

+ 	/* Shadow stack is enabled.  We need to allocate a new shadow

+ 	   stack.  */

+ 	subl	oSS_SP(%eax), %edx

+ 	shrl	$STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT, %edx

+ 

+ 	/* Align shadow stack size to 8 bytes.  */

+ 	addl	$7, %edx

+ 	andl	$-8, %edx

+ 

+ 	/* Store shadow stack size in __ssp[2].  */

+ 	movl	%edx, (oSSP + 8)(%eax)

+ 

+ 	/* Save ESI in the second scratch register slot.  */

+ 	movl	%esi, oSCRATCH2(%eax)

+ 	/* Save EDI in the third scratch register slot.  */

+ 	movl	%edi, oSCRATCH3(%eax)

+ 

+ 	/* Save the pointer to ucontext.  */

+ 	movl	%eax, %edi

+ 

+ 	/* Get the original shadow stack pointer.  */

+ 	rdsspd	%esi

+ 

+ 	/* Align the saved original shadow stack pointer to the next

+ 	   8 byte aligned boundary.  */

+ 	andl	$-8, %esi

+ 

+ 	/* Load the top of the new stack into EDX.  */

+ 	movl	oESP(%eax), %edx

+ 

+ 	/* We need to terminate the FDE here because the unwinder looks

+ 	   at ra-1 for unwind information.  */

+ 	cfi_endproc

+ 

+ 	/* Swap the original stack pointer with the top of the new

+ 	   stack.  */

+ 	xchgl	%esp, %edx

+ 

+ 	/* Add 4 bytes since CALL will push the 4-byte return address

+ 	   onto stack.  */

+ 	addl	$4, %esp

+ 

+ 	/* Allocate the new shadow stack.  Save EBX in the first scratch

+ 	   register slot.  */

+ 	movl	%ebx, oSCRATCH1(%eax)

+ 

+ 	/* CET syscall takes 64-bit sizes.  */

+ 	subl	$16, %esp

+ 	movl	(oSSP + 8)(%eax), %ecx

+ 	movl	%ecx, (%esp)

+ 	movl	$0, 4(%esp)

+ 	movl	%ecx, 8(%esp)

+ 	movl	$0, 12(%esp)

+ 	movl	%esp, %ecx

+ 

+ 	movl	$ARCH_CET_ALLOC_SHSTK, %ebx

+ 	movl	$__NR_arch_prctl, %eax

+ 	ENTER_KERNEL

+ 	testl	%eax, %eax

+ 	jne	L(hlt)		/* This should never happen.  */

+ 

+ 	/* Copy the base address of the new shadow stack to __ssp[1].  */

+ 	movl	(%esp), %eax

+ 	movl	%eax, (oSSP + 4)(%edi)

+ 

+ 	addl	$16, %esp

+ 

+ 	/* Restore EBX from the first scratch register slot.  */

+ 	movl	oSCRATCH1(%edi), %ebx

+ 

+ 	/* Get the size of the new shadow stack.  */

+ 	movl	(oSSP + 8)(%edi), %ecx

+ 

+ 	/* Use the restore stoken to restore the new shadow stack.  */

+ 	rstorssp -8(%eax, %ecx)

+ 

+ 	/* Save the restore token at the next 8 byte aligned boundary

+ 	   on the original shadow stack.  */

+ 	saveprevssp

+ 

+ 	/* Push the address of "jmp exitcode" onto the new stack as

+ 	   well as the new shadow stack.  */

+ 	call	1f

+ 	jmp	L(exitcode)

+ 1:

+ 

+ 	/* Get the new shadow stack pointer.  */

+ 	rdsspd	%eax

+ 

+ 	/* Use the restore stoken to restore the original shadow stack.  */

+ 	rstorssp -8(%esi)

+ 

+ 	/* Save the restore token on the new shadow stack.  */

+ 	saveprevssp

+ 

+ 	/* Store the new shadow stack pointer in __ssp[0].  */

+ 	movl	%eax, oSSP(%edi)

+ 

+ 	/* Restore the original stack.  */

+ 	mov	%edx, %esp

+ 

+ 	cfi_startproc

+ 

+ 	/* Restore ESI from the second scratch register slot.  */

+ 	movl	oSCRATCH2(%edi), %esi

+ 	/* Restore EDI from the third scratch register slot.  */

+ 	movl	oSCRATCH3(%edi), %edi

+ 

+ 	ret

+ 

+ L(skip_ssp):

+ #endif

+ 

  	/* If the function we call returns we must continue with the

  	   context which is given in the uc_link element.  To do this

  	   set the return address for the function the user provides
@@ -123,6 +245,7 @@ 

  	call	HIDDEN_JUMPTARGET(exit)

  	/* The 'exit' call should never return.  In case it does cause

  	   the process to terminate.  */

+ L(hlt):

  	hlt

  	cfi_startproc

  END(__makecontext)

@@ -18,6 +18,7 @@ 

     <http://www.gnu.org/licenses/>.  */

  

  #include <sysdep.h>

+ #include <asm/prctl.h>

  

  #include "ucontext_i.h"

  
@@ -56,31 +57,122 @@ 

  	movl	oFS(%eax), %ecx

  	movw	%cx, %fs

  

- 	/* Fetch the address to return to.  */

- 	movl	oEIP(%eax), %ecx

- 

  	/* Load the new stack pointer.  */

  	cfi_def_cfa (eax, 0)

  	cfi_offset (edi, oEDI)

  	cfi_offset (esi, oESI)

  	cfi_offset (ebp, oEBP)

  	cfi_offset (ebx, oEBX)

- 	cfi_offset (edx, oEDX)

- 	cfi_offset (ecx, oECX)

  	movl	oESP(%eax), %esp

  

+ #if SHSTK_ENABLED

+ 	/* Check if Shadow Stack is enabled.  */

+ 	testl	$X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET

+ 	jz	L(no_shstk)

+ 

+ 	/* If the base of the target shadow stack is the same as the

+ 	   base of the current shadow stack, we unwind the shadow

+ 	   stack.  Otherwise it is a stack switch and we look for a

+ 	   restore token.  */

+ 	movl	oSSP(%eax), %esi

+ 	movl	%esi, %edi

+ 

+ 	/* Get the base of the target shadow stack.  */

+ 	movl	(oSSP + 4)(%eax), %ecx

+ 	cmpl	%gs:SSP_BASE_OFFSET, %ecx

+ 	je	L(unwind_shadow_stack)

+ 

+ 	/* Align the saved original shadow stack pointer to the next

+ 	   8 byte aligned boundary.  */

+ 	andl	$-8, %esi

+ 

+ L(find_restore_token_loop):

+ 	/* Look for a restore token.  */

+ 	movl	-8(%esi), %ebx

+ 	andl	$-8, %ebx

+ 	cmpl	%esi, %ebx

+ 	je	L(restore_shadow_stack)

+ 

+ 	/* Try the next slot.  */

+ 	subl	$8, %esi

+ 	jmp	L(find_restore_token_loop)

+ 

+ L(restore_shadow_stack):

+ 	/* Pop return address from the shadow stack since setcontext

+ 	   will not return.  */

+ 	movl	$1, %ebx

+ 	incsspd	%ebx

+ 

+ 	/* Use the restore stoken to restore the target shadow stack.  */

+ 	rstorssp -8(%esi)

+ 

+ 	/* Save the restore token on the old shadow stack.  NB: This

+ 	   restore token may be checked by setcontext or swapcontext

+ 	   later.  */

+ 	saveprevssp

+ 

+ 	/* Record the new shadow stack base that was switched to.  */

+ 	movl	(oSSP + 4)(%eax), %ebx

+ 	movl	%ebx, %gs:SSP_BASE_OFFSET

+ 

+ L(unwind_shadow_stack):

+ 	rdsspd	%ebx

+ 	subl	%edi, %ebx

+ 	je	L(skip_unwind_shadow_stack)

+ 	negl	%ebx

+ 	shrl	$2, %ebx

+ 	movl	$255, %esi

+ L(loop):

+ 	cmpl	%esi, %ebx

+ 	cmovb	%ebx, %esi

+ 	incsspd	%esi

+ 	subl	%esi, %ebx

+ 	ja	L(loop)

+ 

+ L(skip_unwind_shadow_stack):

+ 

+ 	/* Load the values of all the preserved registers (except ESP).  */

+ 	movl	oEDI(%eax), %edi

+ 	movl	oESI(%eax), %esi

+ 	movl	oEBP(%eax), %ebp

+ 	movl	oEBX(%eax), %ebx

+ 

+ 	/* Get the return address set with getcontext.  */

+ 	movl	oEIP(%eax), %ecx

+ 

+ 	/* Check if return address is valid for the case when setcontext

+ 	   is invoked from L(exitcode) with linked context.  */

+ 	rdsspd	%eax

+ 	cmpl	(%eax), %ecx

+ 	/* Clear EAX to indicate success.  NB: Don't use xorl to keep

+ 	   EFLAGS for jne.  */

+ 	movl	$0, %eax

+ 	jne	L(jmp)

+ 	/* Return to the new context if return address valid.  */

+ 	pushl	%ecx

+ 	ret

+ 

+ L(jmp):

+ 	/* Jump to the new context directly.  */

+ 	jmp	*%ecx

+ 

+ L(no_shstk):

+ #endif

+ 

+ 	/* Fetch the address to return to.  */

+ 	movl	oEIP(%eax), %ecx

+ 

  	/* Push the return address on the new stack so we can return there.  */

  	pushl	%ecx

  

- 	/* Load the values of all the 32-bit registers (except ESP).

- 	   Since we are loading from EAX, it must be last.  */

+ 	/* Load the values of all the preserved registers (except ESP).  */

  	movl	oEDI(%eax), %edi

  	movl	oESI(%eax), %esi

  	movl	oEBP(%eax), %ebp

  	movl	oEBX(%eax), %ebx

- 	movl	oEDX(%eax), %edx

- 	movl	oECX(%eax), %ecx

- 	movl	oEAX(%eax), %eax

+ 

+ 	/* All done, return 0 for success.  */

+ 	xorl	%eax, %eax

  

  	/* End FDE here, we fall into another context.  */

  	cfi_endproc

@@ -18,6 +18,7 @@ 

     <http://www.gnu.org/licenses/>.  */

  

  #include <sysdep.h>

+ #include <asm/prctl.h>

  

  #include "ucontext_i.h"

  
@@ -26,13 +27,7 @@ 

  	/* Load address of the context data structure we save in.  */

  	movl	4(%esp), %eax

  

- 	/* Return value of swapcontext.  EAX is the only register whose

- 	   value is not preserved.  */

- 	movl	$0, oEAX(%eax)

- 

- 	/* Save the 32-bit register values and the return address.  */

- 	movl	%ecx, oECX(%eax)

- 	movl	%edx, oEDX(%eax)

+ 	/* Save the preserved register values and the return address.  */

  	movl	%edi, oEDI(%eax)

  	movl	%esi, oESI(%eax)

  	movl	%ebp, oEBP(%eax)
@@ -82,6 +77,144 @@ 

  	movl	oFS(%eax), %edx

  	movw	%dx, %fs

  

+ #if SHSTK_ENABLED

+ 	/* Check if Shadow Stack is enabled.  */

+ 	testl	$X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET

+ 	jz	L(no_shstk)

+ 

+ 	xorl	%eax, %eax

+ 	cmpl	%gs:SSP_BASE_OFFSET, %eax

+ 	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, %esp

+ 	mov	%esp, %ecx

+ 	movl	$ARCH_CET_STATUS, %ebx

+ 	movl	$__NR_arch_prctl, %eax

+ 	ENTER_KERNEL

+ 	testl	%eax, %eax

+ 	jz	L(continue_no_err)

+ 

+ 	/* This should never happen.  */

+ 	hlt

+ 

+ L(continue_no_err):

+ 	/* Record the base of the current shadow stack.  */

+ 	movl	8(%esp), %eax

+ 	movl	%eax, %gs:SSP_BASE_OFFSET

+ 	add	$24, %esp

+ 

+ L(shadow_stack_bound_recorded):

+ 	/* Load address of the context data structure we save in.  */

+ 	movl	4(%esp), %eax

+ 

+ 	/* Load address of the context data structure we swap in  */

+ 	movl	8(%esp), %edx

+ 

+        /* If we unwind the stack, we can't undo stack unwinding.  Just

+ 	   save the target shadow stack pointer as the current shadow

+ 	   stack pointer.   */

+ 	movl	oSSP(%edx), %ecx

+ 	movl	%ecx, oSSP(%eax)

+ 

+ 	/* Save the current shadow stack base in ucontext.  */

+ 	movl	%gs:SSP_BASE_OFFSET, %ecx

+ 	movl	%ecx, (oSSP + 4)(%eax)

+ 

+ 	/* If the base of the target shadow stack is the same as the

+ 	   base of the current shadow stack, we unwind the shadow

+ 	   stack.  Otherwise it is a stack switch and we look for a

+ 	   restore token.  */

+ 	movl	oSSP(%edx), %esi

+ 	movl	%esi, %edi

+ 

+ 	/* Get the base of the target shadow stack.  */

+ 	movl	(oSSP + 4)(%edx), %ecx

+ 	cmpl	%gs:SSP_BASE_OFFSET, %ecx

+ 	je	L(unwind_shadow_stack)

+ 

+ 	/* Align the saved original shadow stack pointer to the next

+ 	   8 byte aligned boundary.  */

+ 	andl	$-8, %esi

+ 

+ L(find_restore_token_loop):

+ 	/* Look for a restore token.  */

+ 	movl	-8(%esi), %ebx

+ 	andl	$-8, %ebx

+ 	cmpl	%esi, %ebx

+ 	je	L(restore_shadow_stack)

+ 

+ 	/* Try the next slot.  */

+ 	subl	$8, %esi

+ 	jmp	L(find_restore_token_loop)

+ 

+ L(restore_shadow_stack):

+ 	/* The target shadow stack will be restored.  Save the current

+ 	   shadow stack pointer.  */

+ 	rdsspd	%ecx

+ 	movl	%ecx, oSSP(%eax)

+ 

+ 	/* Use the restore stoken to restore the target shadow stack.  */

+ 	rstorssp -8(%esi)

+ 

+ 	/* Save the restore token on the old shadow stack.  NB: This

+ 	   restore token may be checked by setcontext or swapcontext

+ 	   later.  */

+ 	saveprevssp

+ 

+ 	/* Record the new shadow stack base that was switched to.  */

+ 	movl	(oSSP + 4)(%edx), %ebx

+ 	movl	%ebx, %gs:SSP_BASE_OFFSET

+ 

+ L(unwind_shadow_stack):

+ 	rdsspd	%ebx

+ 	subl	%edi, %ebx

+ 	je	L(skip_unwind_shadow_stack)

+ 	negl	%ebx

+ 	shrl	$2, %ebx

+ 	movl	$255, %esi

+ L(loop):

+ 	cmpl	%esi, %ebx

+ 	cmovb	%ebx, %esi

+ 	incsspd	%esi

+ 	subl	%esi, %ebx

+ 	ja	L(loop)

+ 

+ L(skip_unwind_shadow_stack):

+ 

+ 	/* Load the new stack pointer.  */

+ 	movl	oESP(%edx), %esp

+ 

+ 	/* Load the values of all the preserved registers (except ESP).  */

+ 	movl	oEDI(%edx), %edi

+ 	movl	oESI(%edx), %esi

+ 	movl	oEBP(%edx), %ebp

+ 	movl	oEBX(%edx), %ebx

+ 

+ 	/* Get the return address set with getcontext.  */

+ 	movl	oEIP(%edx), %ecx

+ 

+ 	/* Check if return address is valid for the case when setcontext

+ 	   is invoked from L(exitcode) with linked context.  */

+ 	rdsspd	%eax

+ 	cmpl	(%eax), %ecx

+ 	/* Clear EAX to indicate success.  NB: Don't use xorl to keep

+ 	   EFLAGS for jne.  */

+ 	movl	$0, %eax

+ 	jne	L(jmp)

+ 	/* Return to the new context if return address valid.  */

+ 	pushl	%ecx

+ 	ret

+ 

+ L(jmp):

+ 	/* Jump to the new context directly.  */

+ 	jmp	*%ecx

+ 

+ L(no_shstk):

+ #endif

+ 

  	/* Fetch the address to return to.  */

  	movl	oEIP(%eax), %ecx

  
@@ -91,15 +224,14 @@ 

  	/* Push the return address on the new stack so we can return there.  */

  	pushl	%ecx

  

- 	/* Load the values of all the 32-bit registers (except ESP).

- 	   Since we are loading from EAX, it must be last.  */

+ 	/* Load the values of all the preserved registers (except ESP).  */

  	movl	oEDI(%eax), %edi

  	movl	oESI(%eax), %esi

  	movl	oEBP(%eax), %ebp

  	movl	oEBX(%eax), %ebx

- 	movl	oEDX(%eax), %edx

- 	movl	oECX(%eax), %ecx

- 	movl	oEAX(%eax), %eax

+ 

+ 	/* All done, return 0 for success.  */

+ 	xorl	%eax, %eax

  

  	/* The following 'ret' will pop the address of the code and jump

  	   to it.  */

@@ -656,4 +656,9 @@ 

  # endif

  #endif

  

+ /* Each shadow stack slot takes 4 bytes.  Assuming that each stack

+    frame takes 128 bytes, this is used to compute shadow stack size

+    from stack size.  */

+ #define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5

+ 

  #endif /* linux/i386/sysdep.h */

@@ -21,10 +21,11 @@ 

  oEBP		mreg (EBP)

  oESP		mreg (ESP)

  oEBX		mreg (EBX)

- oEDX		mreg (EDX)

- oECX		mreg (ECX)

- oEAX		mreg (EAX)

  oEIP		mreg (EIP)

+ oSCRATCH1	mreg (EAX)

+ oSCRATCH2	mreg (ECX)

+ oSCRATCH3	mreg (EDX)

  oFPREGS		mcontext (fpregs)

  oSIGMASK	ucontext (uc_sigmask)

  oFPREGSMEM	ucontext (__fpregs_mem)

+ oSSP		ucontext (__ssp)

@@ -24,7 +24,7 @@ 

  tests += tst-saved_mask-1

  endif

  

- ifeq ($(enable-cet),yes)

+ ifneq ($(enable-cet),no)

  ifeq ($(subdir),elf)

  tests += tst-cet-property-1 tst-cet-property-2

  

@@ -36,7 +36,7 @@ 

  x86_setup_tls (void)

  {

    __libc_setup_tls ();

-   THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)[0]);

+   THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1));

  }

  

  #  define ARCH_SETUP_TLS() x86_setup_tls ()

@@ -19,27 +19,6 @@ 

  #include <asm/prctl.h>

  

  static inline int __attribute__ ((always_inline))

- dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)

- {

-   /* Allocate legacy bitmap.  */

-   INTERNAL_SYSCALL_DECL (err);

- #ifdef __LP64__

-   return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,

- 				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);

- #else

-   unsigned long long legacy_bitmap_u64[2];

-   int res = INTERNAL_SYSCALL (arch_prctl, err, 2,

- 			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);

-   if (res == 0)

-     {

-       legacy_bitmap[0] = legacy_bitmap_u64[0];

-       legacy_bitmap[1] = legacy_bitmap_u64[1];

-     }

-   return res;

- #endif

- }

- 

- static inline int __attribute__ ((always_inline))

  dl_cet_disable_cet (unsigned int cet_feature)

  {

    INTERNAL_SYSCALL_DECL (err);

@@ -24,9 +24,4 @@ 

       OUT: allocated shadow stack address: *addr.

   */

  # define ARCH_CET_ALLOC_SHSTK	0x3004

- /* Return legacy region bitmap info in unsigned long long *addr:

-      address: addr[0].

-      size: addr[1].

-  */

- # define ARCH_CET_LEGACY_BITMAP	0x3005

  #endif /* ARCH_CET_STATUS */

file modified
+19 -8
@@ -14,13 +14,14 @@ 

  sysdep_routines += __longjmp_cancel

  endif

  

- ifeq ($(enable-cet),yes)

+ ifneq ($(enable-cet),no)

  ifeq ($(subdir),elf)

  sysdep-dl-routines += dl-cet

  

  tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \

  	 tst-cet-legacy-3 tst-cet-legacy-4 \

- 	 tst-cet-legacy-5a tst-cet-legacy-6a

+ 	 tst-cet-legacy-5a tst-cet-legacy-6a tst-cet-legacy-7 \

+ 	 tst-cet-legacy-8

  ifneq (no,$(have-tunables))

  tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c \

  	 tst-cet-legacy-5b tst-cet-legacy-6b
@@ -40,16 +41,26 @@ 

  CFLAGS-tst-cet-legacy-4a.c += -fcf-protection

  CFLAGS-tst-cet-legacy-4b.c += -fcf-protection

  CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none

- CFLAGS-tst-cet-legacy-5a.c += -fcf-protection

- CFLAGS-tst-cet-legacy-5b.c += -fcf-protection

- CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none

+ CFLAGS-tst-cet-legacy-5a.c += -fcf-protection -mshstk

+ ifeq ($(enable-cet),permissive)

+ CPPFLAGS-tst-cet-legacy-5a.c += -DCET_IS_PERMISSIVE=1

+ endif

+ CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -mshstk

+ CPPFLAGS-tst-cet-legacy-5b.c += -DCET_DISABLED_BY_ENV=1

+ CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=branch

  CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection

  CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection

- CFLAGS-tst-cet-legacy-6a.c += -fcf-protection

- CFLAGS-tst-cet-legacy-6b.c += -fcf-protection

- CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none

+ CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -mshstk

+ ifeq ($(enable-cet),permissive)

+ CPPFLAGS-tst-cet-legacy-6a.c += -DCET_IS_PERMISSIVE=1

+ endif

+ CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -mshstk

+ CPPFLAGS-tst-cet-legacy-6b.c += -DCET_DISABLED_BY_ENV=1

+ CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=branch

  CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection

  CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection

+ CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none

+ CFLAGS-tst-cet-legacy-8.c += -mshstk

  

  $(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \

  		       $(objpfx)tst-cet-legacy-mod-2.so

@@ -0,0 +1,41 @@ 

+ /* x86 CET tuning.

+    This file is part of the GNU C Library.

+    Copyright (C) 2018 Free Software Foundation, Inc.

+ 

+    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

+    <http://www.gnu.org/licenses/>.  */

+ 

+ #ifndef _CET_CONTROL_H

+ #define _CET_CONTROL_H

+ 

+ /* For each CET feature, IBT and SHSTK, valid control values.  */

+ enum dl_x86_cet_control

+ {

+   /* Enable CET features based on ELF property note.  */

+   cet_elf_property = 0,

+   /* Always enable CET features.  */

+   cet_always_on,

+   /* Always disable CET features.  */

+   cet_always_off,

+   /* Enable CET features permissively.  */

+   cet_permissive

+ };

+ 

+ struct dl_x86_feature_control

+ {

+   enum dl_x86_cet_control ibt : 2;

+   enum dl_x86_cet_control shstk : 2;

+ };

+ 

+ #endif /* cet-control.h */

@@ -1,29 +0,0 @@ 

- /* x86 CET tuning.

-    This file is part of the GNU C Library.

-    Copyright (C) 2018 Free Software Foundation, Inc.

- 

-    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

-    <http://www.gnu.org/licenses/>.  */

- 

- /* Valid control values:

-    0: Enable CET features based on ELF property note.

-    1: Always disable CET features.

-    2: Always enable CET features.

-    3: Enable CET features permissively.

-  */

- #define CET_ELF_PROPERTY	0

- #define CET_ALWAYS_OFF		1

- #define CET_ALWAYS_ON		2

- #define CET_PERMISSIVE		3

- #define CET_MAX			CET_PERMISSIVE

file modified
+11 -10
@@ -1,7 +1,7 @@ 

  # This file is generated from configure.ac by Autoconf.  DO NOT EDIT!

   # Local configure fragment for sysdeps/x86.

  

- if test x"$enable_cet" = xyes; then

+ if test $enable_cet != no; then

    # Check if CET can be enabled.

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CET can be enabled" >&5

  $as_echo_n "checking whether CET can be enabled... " >&6; }
@@ -27,17 +27,11 @@ 

  fi

  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_available" >&5

  $as_echo "$libc_cv_x86_cet_available" >&6; }

-   if test $libc_cv_x86_cet_available = yes; then

-     enable_cet=yes

-   else

-     if test x"$enable_cet" = xdefault; then

-       enable_cet=no

-     else

-       as_fn_error $? "$CC doesn't support CET" "$LINENO" 5

-     fi

+   if test $libc_cv_x86_cet_available != yes; then

+     as_fn_error $? "$CC doesn't support CET" "$LINENO" 5

    fi

  fi

- if test $enable_cet = yes; then

+ if test $enable_cet != no; then

    # Check if assembler supports CET.

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $AS supports CET" >&5

  $as_echo_n "checking whether $AS supports CET... " >&6; }
@@ -65,5 +59,12 @@ 

      as_fn_error $? "$AS doesn't support CET" "$LINENO" 5

    fi

  fi

+ if test $enable_cet = yes; then

+   $as_echo "#define DEFAULT_DL_X86_CET_CONTROL cet_elf_property" >>confdefs.h

+ 

+ elif test $enable_cet = permissive; then

+   $as_echo "#define DEFAULT_DL_X86_CET_CONTROL cet_permissive" >>confdefs.h

+ 

+ fi

  config_vars="$config_vars

  enable-cet = $enable_cet"

file modified
+9 -10
@@ -1,7 +1,7 @@ 

  GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.

  # Local configure fragment for sysdeps/x86.

  

- if test x"$enable_cet" = xyes; then

+ if test $enable_cet != no; then

    # Check if CET can be enabled.

    AC_CACHE_CHECK(whether CET can be enabled,

  		 libc_cv_x86_cet_available, [dnl
@@ -16,17 +16,11 @@ 

  		   libc_cv_x86_cet_available=no

  		 fi

  		 rm -rf conftest*])

-   if test $libc_cv_x86_cet_available = yes; then

-     enable_cet=yes

-   else

-     if test x"$enable_cet" = xdefault; then

-       enable_cet=no

-     else

-       AC_MSG_ERROR([$CC doesn't support CET])

-     fi

+   if test $libc_cv_x86_cet_available != yes; then

+     AC_MSG_ERROR([$CC doesn't support CET])

    fi

  fi

- if test $enable_cet = yes; then

+ if test $enable_cet != no; then

    # Check if assembler supports CET.

    AC_CACHE_CHECK(whether $AS supports CET,

  		 libc_cv_x86_cet_as, [dnl
@@ -43,4 +37,9 @@ 

      AC_MSG_ERROR([$AS doesn't support CET])

    fi

  fi

+ if test $enable_cet = yes; then

+   AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_elf_property)

+ elif test $enable_cet = permissive; then

+   AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_permissive)

+ fi

  LIBC_CONFIG_VAR([enable-cet], [$enable_cet])

file modified
+5 -7
@@ -39,7 +39,6 @@ 

  

  #if CET_ENABLED

  # include <dl-cet.h>

- # include <cet-tunables.h>

  #endif

  

  static void
@@ -490,7 +489,7 @@ 

  

    if (cet_status)

      {

-       GL(dl_x86_feature_1)[0] = cet_status;

+       GL(dl_x86_feature_1) = cet_status;

  

  # ifndef SHARED

        /* Check if IBT and SHSTK are enabled by kernel.  */
@@ -514,14 +513,13 @@ 

  

  	      /* Clear the disabled bits in dl_x86_feature_1.  */

  	      if (res == 0)

- 		GL(dl_x86_feature_1)[0] &= ~cet_feature;

+ 		GL(dl_x86_feature_1) &= ~cet_feature;

  	    }

  

  	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't

- 	     lock CET if SHSTK is enabled permissively.  */

- 	  if (((GL(dl_x86_feature_1)[1] >> CET_MAX)

- 	       & ((1 << CET_MAX) - 1))

- 	       != CET_PERMISSIVE)

+ 	     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 ();

  	}

  # endif

file modified
+6 -25
@@ -336,28 +336,18 @@ 

  }

  

  # if CET_ENABLED

- #  include <cet-tunables.h>

  

  attribute_hidden

  void

  TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *valp)

  {

    if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);

-       GL(dl_x86_feature_1)[1] |= CET_ALWAYS_ON;

-     }

+     GL(dl_x86_feature_control).ibt = cet_always_on;

    else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);

-       GL(dl_x86_feature_1)[1] |= CET_ALWAYS_OFF;

-     }

+     GL(dl_x86_feature_control).ibt = cet_always_off;

    else if (DEFAULT_MEMCMP (valp->strval, "permissive",

  			   sizeof ("permissive")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);

-       GL(dl_x86_feature_1)[1] |= CET_PERMISSIVE;

-     }

+     GL(dl_x86_feature_control).ibt = cet_permissive;

  }

  

  attribute_hidden
@@ -365,21 +355,12 @@ 

  TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *valp)

  {

    if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);

-       GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_ON << CET_MAX);

-     }

+     GL(dl_x86_feature_control).shstk = cet_always_on;

    else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);

-       GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_OFF << CET_MAX);

-     }

+     GL(dl_x86_feature_control).shstk = cet_always_off;

    else if (DEFAULT_MEMCMP (valp->strval, "permissive",

  			   sizeof ("permissive")) == 0)

-     {

-       GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);

-       GL(dl_x86_feature_1)[1] |= (CET_PERMISSIVE << CET_MAX);

-     }

+     GL(dl_x86_feature_control).shstk = cet_permissive;

  }

  # endif

  #endif

file modified
+74 -172
@@ -20,7 +20,6 @@ 

  #include <libintl.h>

  #include <ldsodefs.h>

  #include <dl-cet.h>

- #include <cet-tunables.h>

  

  /* GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK

     are defined in <elf.h>, which are only available for C sources.
@@ -33,96 +32,41 @@ 

  # error GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK

  #endif

  

- static int

- dl_cet_mark_legacy_region (struct link_map *l)

- {

-   /* Mark PT_LOAD segments with PF_X in legacy code page bitmap.  */

-   size_t i, phnum = l->l_phnum;

-   const ElfW(Phdr) *phdr = l->l_phdr;

- #ifdef __x86_64__

-   typedef unsigned long long word_t;

- #else

-   typedef unsigned long word_t;

- #endif

-   unsigned int bits_to_set;

-   word_t mask_to_set;

- #define BITS_PER_WORD (sizeof (word_t) * 8)

- #define BITMAP_FIRST_WORD_MASK(start) \

-   (~((word_t) 0) << ((start) & (BITS_PER_WORD - 1)))

- #define BITMAP_LAST_WORD_MASK(nbits) \

-   (~((word_t) 0) >> (-(nbits) & (BITS_PER_WORD - 1)))

- 

-   word_t *bitmap = (word_t *) GL(dl_x86_legacy_bitmap)[0];

-   word_t bitmap_size = GL(dl_x86_legacy_bitmap)[1];

-   word_t *p;

-   size_t page_size = GLRO(dl_pagesize);

- 

-   for (i = 0; i < phnum; i++)

-     if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X))

-       {

- 	/* One bit in legacy bitmap represents a page.  */

- 	ElfW(Addr) start = (phdr[i].p_vaddr + l->l_addr) / page_size;

- 	ElfW(Addr) len = (phdr[i].p_memsz + page_size - 1) / page_size;

- 	ElfW(Addr) end = start + len;

- 

- 	if ((end / 8) > bitmap_size)

- 	  return -EINVAL;

- 

- 	p = bitmap + (start / BITS_PER_WORD);

- 	bits_to_set = BITS_PER_WORD - (start % BITS_PER_WORD);

- 	mask_to_set = BITMAP_FIRST_WORD_MASK (start);

- 

- 	while (len >= bits_to_set)

- 	  {

- 	    *p |= mask_to_set;

- 	    len -= bits_to_set;

- 	    bits_to_set = BITS_PER_WORD;

- 	    mask_to_set = ~((word_t) 0);

- 	    p++;

- 	  }

- 	if (len)

- 	  {

- 	    mask_to_set &= BITMAP_LAST_WORD_MASK (end);

- 	    *p |= mask_to_set;

- 	  }

-       }

- 

-   return 0;

- }

- 

  /* Check if object M is compatible with CET.  */

  

  static void

  dl_cet_check (struct link_map *m, const char *program)

  {

    /* Check how IBT should be enabled.  */

-   unsigned int enable_ibt_type

-     = GL(dl_x86_feature_1)[1] & ((1 << CET_MAX) - 1);

+   enum dl_x86_cet_control enable_ibt_type

+     = GL(dl_x86_feature_control).ibt;

    /* Check how SHSTK should be enabled.  */

-   unsigned int enable_shstk_type

-     = ((GL(dl_x86_feature_1)[1] >> CET_MAX) & ((1 << CET_MAX) - 1));

+   enum dl_x86_cet_control enable_shstk_type

+     = GL(dl_x86_feature_control).shstk;

  

    /* No legacy object check if both IBT and SHSTK are always on.  */

-   if (enable_ibt_type == CET_ALWAYS_ON

-       && enable_shstk_type == CET_ALWAYS_ON)

+   if (enable_ibt_type == cet_always_on

+       && enable_shstk_type == cet_always_on)

      return;

  

    /* Check if IBT is enabled by kernel.  */

    bool ibt_enabled

-     = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0;

+     = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0;

    /* Check if SHSTK is enabled by kernel.  */

    bool shstk_enabled

-     = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;

+     = (GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;

  

    if (ibt_enabled || shstk_enabled)

      {

        struct link_map *l = NULL;

+       unsigned int ibt_legacy = 0, shstk_legacy = 0;

+       bool found_ibt_legacy = false, found_shstk_legacy = false;

  

        /* Check if IBT and SHSTK are enabled in object.  */

        bool enable_ibt = (ibt_enabled

- 			 && enable_ibt_type != CET_ALWAYS_OFF);

+ 			 && enable_ibt_type != cet_always_off);

        bool enable_shstk = (shstk_enabled

- 			   && enable_shstk_type != CET_ALWAYS_OFF);

+ 			   && enable_shstk_type != cet_always_off);

        if (program)

  	{

  	  /* Enable IBT and SHSTK only if they are enabled in executable.
@@ -131,10 +75,10 @@ 

  	     GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK

  	   */

  	  enable_ibt &= (HAS_CPU_FEATURE (IBT)

- 			 && (enable_ibt_type == CET_ALWAYS_ON

+ 			 && (enable_ibt_type == cet_always_on

  			     || (m->l_cet & lc_ibt) != 0));

  	  enable_shstk &= (HAS_CPU_FEATURE (SHSTK)

- 			   && (enable_shstk_type == CET_ALWAYS_ON

+ 			   && (enable_shstk_type == cet_always_on

  			       || (m->l_cet & lc_shstk) != 0));

  	}

  
@@ -142,10 +86,7 @@ 

  	 support IBT nor SHSTK.  */

        if (enable_ibt || enable_shstk)

  	{

- 	  int res;

  	  unsigned int i;

- 	  unsigned int first_legacy, last_legacy;

- 	  bool need_legacy_bitmap = false;

  

  	  i = m->l_searchlist.r_nlist;

  	  while (i-- > 0)
@@ -167,91 +108,25 @@ 

  		continue;

  #endif

  

- 	      if (enable_ibt

- 		  && enable_ibt_type != CET_ALWAYS_ON

- 		  && !(l->l_cet & lc_ibt))

+ 	      /* IBT is enabled only if it is enabled in executable as

+ 		 well as all shared objects.  */

+ 	      enable_ibt &= (enable_ibt_type == cet_always_on

+ 			     || (l->l_cet & lc_ibt) != 0);

+ 	      if (!found_ibt_legacy && enable_ibt != ibt_enabled)

  		{

- 		  /* Remember the first and last legacy objects.  */

- 		  if (!need_legacy_bitmap)

- 		    last_legacy = i;

- 		  first_legacy = i;

- 		  need_legacy_bitmap = true;

+ 		  found_ibt_legacy = true;

+ 		  ibt_legacy = i;

  		}

  

  	      /* SHSTK is enabled only if it is enabled in executable as

  		 well as all shared objects.  */

- 	      enable_shstk &= (enable_shstk_type == CET_ALWAYS_ON

+ 	      enable_shstk &= (enable_shstk_type == cet_always_on

  			       || (l->l_cet & lc_shstk) != 0);

- 	    }

- 

- 	  if (need_legacy_bitmap)

- 	    {

- 	      if (GL(dl_x86_legacy_bitmap)[0])

- 		{

- 		  /* Change legacy bitmap to writable.  */

- 		  if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],

- 				  GL(dl_x86_legacy_bitmap)[1],

- 				  PROT_READ | PROT_WRITE) < 0)

- 		    {

- mprotect_failure:

- 		      if (program)

- 			_dl_fatal_printf ("%s: mprotect legacy bitmap failed\n",

- 					  l->l_name);

- 		      else

- 			_dl_signal_error (EINVAL, l->l_name, "dlopen",

- 					  N_("mprotect legacy bitmap failed"));

- 		    }

- 		}

- 	      else

+ 	      if (enable_shstk != shstk_enabled)

  		{

- 		  /* Allocate legacy bitmap.  */

- 		  int res = dl_cet_allocate_legacy_bitmap

- 		    (GL(dl_x86_legacy_bitmap));

- 		  if (res != 0)

- 		    {

- 		      if (program)

- 			_dl_fatal_printf ("%s: legacy bitmap isn't available\n",

- 					  l->l_name);

- 		      else

- 			_dl_signal_error (EINVAL, l->l_name, "dlopen",

- 					  N_("legacy bitmap isn't available"));

- 		    }

+ 		  found_shstk_legacy = true;

+ 		  shstk_legacy = i;

  		}

- 

- 	      /* Put legacy shared objects in legacy bitmap.  */

- 	      for (i = first_legacy; i <= last_legacy; i++)

- 		{

- 		  l = m->l_initfini[i];

- 

- 		  if (l->l_init_called || (l->l_cet & lc_ibt))

- 		    continue;

- 

- #ifdef SHARED

- 		  if (l == &GL(dl_rtld_map)

- 		      ||  l->l_real == &GL(dl_rtld_map)

- 		      || (program && l == m))

- 		    continue;

- #endif

- 

- 		  /* If IBT is enabled in executable and IBT isn't enabled

- 		     in this shard object, mark PT_LOAD segments with PF_X

- 		     in legacy code page bitmap.  */

- 		  res = dl_cet_mark_legacy_region (l);

- 		  if (res != 0)

- 		    {

- 		      if (program)

- 			_dl_fatal_printf ("%s: failed to mark legacy code region\n",

- 					  l->l_name);

- 		      else

- 			_dl_signal_error (-res, l->l_name, "dlopen",

- 					  N_("failed to mark legacy code region"));

- 		    }

- 		}

- 

- 	      /* Change legacy bitmap to read-only.  */

- 	      if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],

- 			      GL(dl_x86_legacy_bitmap)[1], PROT_READ) < 0)

- 		goto mprotect_failure;

  	    }

  	}

  
@@ -259,23 +134,40 @@ 

  

        if (enable_ibt != ibt_enabled || enable_shstk != shstk_enabled)

  	{

- 	  if (!program

- 	      && enable_shstk_type != CET_PERMISSIVE)

+ 	  if (!program)

  	    {

- 	      /* When SHSTK is enabled, we can't dlopening a shared

- 		 object without SHSTK.  */

- 	      if (enable_shstk != shstk_enabled)

- 		_dl_signal_error (EINVAL, l->l_name, "dlopen",

- 				  N_("shadow stack isn't enabled"));

- 	      return;

+ 	      if (enable_ibt_type != cet_permissive)

+ 		{

+ 		  /* When IBT is enabled, we cannot dlopen a shared

+ 		     object without IBT.  */

+ 		  if (found_ibt_legacy)

+ 		    _dl_signal_error (0,

+ 				      m->l_initfini[ibt_legacy]->l_name,

+ 				      "dlopen",

+ 				      N_("rebuild shared object with IBT support enabled"));

+ 		}

+ 

+ 	      if (enable_shstk_type != cet_permissive)

+ 		{

+ 		  /* When SHSTK is enabled, we cannot dlopen a shared

+ 		     object without SHSTK.  */

+ 		  if (found_shstk_legacy)

+ 		    _dl_signal_error (0,

+ 				      m->l_initfini[shstk_legacy]->l_name,

+ 				      "dlopen",

+ 				      N_("rebuild shared object with SHSTK support enabled"));

+ 		}

+ 

+ 	      if (enable_ibt_type != cet_permissive

+ 		  && enable_shstk_type != cet_permissive)

+ 		return;

  	    }

  

  	  /* Disable IBT and/or SHSTK if they are enabled by kernel, but

  	     disabled in executable or shared objects.  */

  	  unsigned int cet_feature = 0;

  

- 	  /* Disable IBT only during program startup.  */

- 	  if (program && !enable_ibt)

+ 	  if (!enable_ibt)

  	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;

  	  if (!enable_shstk)

  	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
@@ -286,28 +178,38 @@ 

  	      if (program)

  		_dl_fatal_printf ("%s: can't disable CET\n", program);

  	      else

- 		_dl_signal_error (-res, l->l_name, "dlopen",

- 				  N_("can't disable CET"));

+ 		{

+ 		  if (found_ibt_legacy)

+ 		    l = m->l_initfini[ibt_legacy];

+ 		  else

+ 		    l = m->l_initfini[shstk_legacy];

+ 		  _dl_signal_error (-res, l->l_name, "dlopen",

+ 				    N_("can't disable CET"));

+ 		}

  	    }

  

  	  /* Clear the disabled bits in dl_x86_feature_1.  */

- 	  GL(dl_x86_feature_1)[0] &= ~cet_feature;

+ 	  GL(dl_x86_feature_1) &= ~cet_feature;

  

  	  cet_feature_changed = true;

  	}

  

  #ifdef SHARED

-       if (program

- 	  && (!shstk_enabled

- 	      || enable_shstk_type != CET_PERMISSIVE)

- 	  && (ibt_enabled || shstk_enabled))

+       if (program && (ibt_enabled || shstk_enabled))

  	{

- 	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't

- 	     lock CET if SHSTK is enabled permissively.  */

- 	  int res = dl_cet_lock_cet ();

- 	  if (res != 0)

- 	    _dl_fatal_printf ("%s: can't lock CET\n", program);

+ 	  if ((!ibt_enabled

+ 	       || enable_ibt_type != cet_permissive)

+ 	      && (!shstk_enabled

+ 		  || enable_shstk_type != cet_permissive))

+ 	    {

+ 	      /* Lock CET if IBT or SHSTK is enabled in executable unless

+ 	         IBT or SHSTK is enabled permissively.  */

+ 	      int res = dl_cet_lock_cet ();

+ 	      if (res != 0)

+ 		_dl_fatal_printf ("%s: can't lock CET\n", program);

+ 	    }

  

+ 	  /* Set feature_1 if IBT or SHSTK is enabled in executable.  */

  	  cet_feature_changed = true;

  	}

  #endif

file modified
+12 -3
@@ -47,7 +47,10 @@ 

  # if !defined PROCINFO_DECL && defined SHARED

    ._dl_x86_feature_1

  # else

- PROCINFO_CLASS unsigned int _dl_x86_feature_1[2]

+ PROCINFO_CLASS unsigned int _dl_x86_feature_1

+ # endif

+ # ifndef PROCINFO_DECL

+ = 0

  # endif

  # if !defined SHARED || defined PROCINFO_DECL

  ;
@@ -56,9 +59,15 @@ 

  # endif

  

  # if !defined PROCINFO_DECL && defined SHARED

-   ._dl_x86_legacy_bitmap

+   ._dl_x86_feature_control

  # else

- PROCINFO_CLASS unsigned long _dl_x86_legacy_bitmap[2]

+ PROCINFO_CLASS struct dl_x86_feature_control _dl_x86_feature_control

+ # endif

+ # ifndef PROCINFO_DECL

+ = {

+     .ibt = DEFAULT_DL_X86_CET_CONTROL,

+     .shstk = DEFAULT_DL_X86_CET_CONTROL,

+   }

  # endif

  # if !defined SHARED || defined PROCINFO_DECL

  ;

file modified
+1
@@ -61,6 +61,7 @@ 

  				     struct La_x86_64_retval *,		\

  				     const char *)

  

+ #include <cet-control.h>

  #include_next <ldsodefs.h>

  

  #endif

@@ -20,6 +20,9 @@ 

  #include <dlfcn.h>

  #include <stdio.h>

  #include <stdlib.h>

+ #include <string.h>

+ 

+ #include <support/check.h>

  

  static int

  do_test (void)
@@ -31,22 +34,18 @@ 

    h = dlopen (modname, RTLD_LAZY);

    if (h == NULL)

      {

-       printf ("cannot open '%s': %s\n", modname, dlerror ());

-       exit (1);

+       const char *err = dlerror ();

+       if (!strstr (err, "rebuild shared object with IBT support enabled"))

+ 	FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);

+       return 0;

      }

  

    fp = dlsym (h, "test");

    if (fp == NULL)

-     {

-       printf ("cannot get symbol 'test': %s\n", dlerror ());

-       exit (1);

-     }

+     FAIL_EXIT1 ("cannot get symbol 'test': %s\n", dlerror ());

  

    if (fp () != 0)

-     {

-       puts ("test () != 0");

-       exit (1);

-     }

+     FAIL_EXIT1 ("test () != 0");

  

    dlclose (h);

  

@@ -22,6 +22,14 @@ 

  #include <stdlib.h>

  #include <stdbool.h>

  #include <string.h>

+ #include <x86intrin.h>

+ #include <support/check.h>

+ 

+ #if defined CET_IS_PERMISSIVE || defined CET_DISABLED_BY_ENV

+ # define CET_MAYBE_DISABLED 1

+ #else

+ # define CET_MAYBE_DISABLED 0

+ #endif

  

  static void

  do_test_1 (const char *modname, bool fail)
@@ -32,23 +40,25 @@ 

    h = dlopen (modname, RTLD_LAZY);

    if (h == NULL)

      {

+       const char *err = dlerror ();

        if (fail)

  	{

- 	  const char *err = dlerror ();

- 	  if (strstr (err, "shadow stack isn't enabled") == NULL)

- 	    {

- 	      printf ("incorrect dlopen '%s' error: %s\n", modname,

- 		      dlerror ());

- 	      exit (1);

- 	    }

+ 	  if (strstr (err, "rebuild shared object with SHSTK support enabled")

+ 	      == NULL)

+ 	    FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);

  

  	  return;

  	}

  

-       printf ("cannot open '%s': %s\n", modname, dlerror ());

-       exit (1);

+       FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err);

      }

  

+   /* NB: dlopen should never fail on non-CET platforms.  If SHSTK is

+      disabled, assuming IBT is also disabled.  */

+   bool cet_enabled = _get_ssp () != 0 && !CET_MAYBE_DISABLED;

+   if (fail && cet_enabled)

+     FAIL_EXIT1 ("dlopen should have failed\n");

+ 

    fp = dlsym (h, "test");

    if (fp == NULL)

      {

@@ -22,6 +22,14 @@ 

  #include <stdlib.h>

  #include <stdbool.h>

  #include <string.h>

+ #include <x86intrin.h>

+ #include <support/check.h>

+ 

+ #if defined CET_IS_PERMISSIVE || defined CET_DISABLED_BY_ENV

+ # define CET_MAYBE_DISABLED 1

+ #else

+ # define CET_MAYBE_DISABLED 0

+ #endif

  

  static void

  do_test_1 (const char *modname, bool fail)
@@ -32,23 +40,25 @@ 

    h = dlopen (modname, RTLD_LAZY);

    if (h == NULL)

      {

+       const char *err = dlerror ();

        if (fail)

  	{

- 	  const char *err = dlerror ();

- 	  if (strstr (err, "shadow stack isn't enabled") == NULL)

- 	    {

- 	      printf ("incorrect dlopen '%s' error: %s\n", modname,

- 		      dlerror ());

- 	      exit (1);

- 	    }

+ 	  if (strstr (err, "rebuild shared object with SHSTK support enabled")

+ 	      == NULL)

+ 	    FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);

  

  	  return;

  	}

  

-       printf ("cannot open '%s': %s\n", modname, dlerror ());

-       exit (1);

+       FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err);

      }

  

+   /* NB: dlopen should never fail on non-CET platforms.  If SHSTK is

+      disabled, assuming IBT is also disabled.  */

+   bool cet_enabled = _get_ssp () != 0 && !CET_MAYBE_DISABLED;

+   if (fail && cet_enabled)

+     FAIL_EXIT1 ("dlopen should have failed\n");

+ 

    fp = dlsym (h, "test");

    if (fp == NULL)

      {

@@ -0,0 +1,38 @@ 

+ /* Check compatibility of legacy executable with a JIT engine.

+    Copyright (C) 2020 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 <stdio.h>

+ #include <sys/mman.h>

+ #include <support/xunistd.h>

+ 

+ /* Check that mmapped legacy code works with -fcf-protection=none.  */

+ 

+ static int

+ do_test (void)

+ {

+   void (*funcp) (void);

+   funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE,

+ 		 MAP_ANONYMOUS | MAP_PRIVATE, -1);

+   printf ("mmap = %p\n", funcp);

+   /* Write RET instruction.  */

+   *(char *) funcp = 0xc3;

+   funcp ();

+   return 0;

+ }

+ 

+ #include <support/test-driver.c>

@@ -0,0 +1,48 @@ 

+ /* Check incompatibility with legacy JIT engine.

+    Copyright (C) 2020 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 <stdio.h>

+ #include <stdlib.h>

+ #include <x86intrin.h>

+ #include <sys/mman.h>

+ #include <support/test-driver.h>

+ #include <support/xsignal.h>

+ #include <support/xunistd.h>

+ 

+ /* Check that mmapped legacy code trigges segfault with -fcf-protection.  */

+ 

+ static int

+ do_test (void)

+ {

+   /* NB: This test should trigger SIGSEGV on CET platforms.  If SHSTK

+      is disabled, assuming IBT is also disabled.  */

+   if (_get_ssp () == 0)

+     return EXIT_UNSUPPORTED;

+ 

+   void (*funcp) (void);

+   funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE,

+ 		 MAP_ANONYMOUS | MAP_PRIVATE, -1);

+   printf ("mmap = %p\n", funcp);

+   /* Write RET instruction.  */

+   *(char *) funcp = 0xc3;

+   funcp ();

+   return EXIT_FAILURE;

+ }

+ 

+ #define EXPECTED_SIGNAL (_get_ssp () == 0 ? 0 : SIGSEGV)

+ #include <support/test-driver.c>

For

https://bugzilla.redhat.com/show_bug.cgi?id=1855790

b324591 x86: Add --enable-cet=permissive
eecf51e x86: Don't make 2 calls to dlerror () in a row
85cee34 x86: Move CET control to _dl_x86_feature_control [BZ #25887]
6800f76 x86: Remove ARCH_CET_LEGACY_BITMAP [BZ #25397]
9498ead i386: Enable CET support in ucontext functions
b8b19c8 i386: Remove _exit.S
ad5b1c8 i386: Use ENTRY/END in assembly codes
35e2de4 i386-mcount.S: Add _CET_ENDBR to _mcount and fentry
4126519 i386/sub_n.S: Add a missing _CET_ENDBR to indirect jump target
28076c5 i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262]

Hi @hjl, thank you for your contribution!

I just shared it with the maintainer and you can expect a proper review soon.

I just spoke to the maintainers of glibc (namely Florian Weimer) and he let me know there is already a BZ referencing this work: https://bugzilla.redhat.com/show_bug.cgi?id=1855790

I can also see in the BZ that you are already in touch with Carlos O'Donell, I'll let him handle this - I'd suggest using the referenced bugzilla for further communication. Thanks!

HJ, Thanks for the PR :-)

3 new commits added

  • x86: Add --enable-cet=permissive
  • x86: Don't make 2 calls to dlerror () in a row
  • x86: Move CET control to _dl_x86_feature_control [BZ #25887]
3 years ago
Changes Summary 36
+15 -11
file changed
INSTALL
+3 -0
file changed
config.h.in
+2 -0
file changed
elf/rtld.c
+8 -4
file changed
manual/install.texi
+1 -1
file changed
sysdeps/i386/dl-machine.h
+2 -0
file changed
sysdeps/i386/i386-mcount.S
+3 -5
file changed
sysdeps/i386/nptl/pthread_spin_lock.S
+4 -5
file changed
sysdeps/i386/nptl/pthread_spin_unlock.S
+3 -5
file changed
sysdeps/i386/pthread_spin_trylock.S
+1 -0
file changed
sysdeps/i386/sub_n.S
-44
file removed
sysdeps/unix/sysv/linux/i386/_exit.S
+57 -7
file changed
sysdeps/unix/sysv/linux/i386/getcontext.S
+123 -0
file changed
sysdeps/unix/sysv/linux/i386/makecontext.S
+102 -10
file changed
sysdeps/unix/sysv/linux/i386/setcontext.S
+144 -12
file changed
sysdeps/unix/sysv/linux/i386/swapcontext.S
+5 -0
file changed
sysdeps/unix/sysv/linux/i386/sysdep.h
+4 -3
file changed
sysdeps/unix/sysv/linux/i386/ucontext_i.sym
+1 -1
file changed
sysdeps/unix/sysv/linux/x86/Makefile
+1 -1
file changed
sysdeps/unix/sysv/linux/x86/cpu-features.c
+0 -21
file changed
sysdeps/unix/sysv/linux/x86/dl-cet.h
+0 -5
file changed
sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
+19 -8
file changed
sysdeps/x86/Makefile
+41
file added
sysdeps/x86/cet-control.h
-29
file removed
sysdeps/x86/cet-tunables.h
+11 -10
file changed
sysdeps/x86/configure
+9 -10
file changed
sysdeps/x86/configure.ac
+5 -7
file changed
sysdeps/x86/cpu-features.c
+6 -25
file changed
sysdeps/x86/cpu-tunables.c
+74 -172
file changed
sysdeps/x86/dl-cet.c
+12 -3
file changed
sysdeps/x86/dl-procruntime.c
+1 -0
file changed
sysdeps/x86/ldsodefs.h
+9 -10
file changed
sysdeps/x86/tst-cet-legacy-4.c
+19 -9
file changed
sysdeps/x86/tst-cet-legacy-5.c
+19 -9
file changed
sysdeps/x86/tst-cet-legacy-6.c
+38
file added
sysdeps/x86/tst-cet-legacy-7.c
+48
file added
sysdeps/x86/tst-cet-legacy-8.c