This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.27.9000-572-gfaaee1f


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  faaee1f07ed25b2779bfd935ffb29f431b80d6d3 (commit)
       via  ebff9c5cfae62e84dbd0456d564bd882818dc15f (commit)
      from  0a83bad2aae6807a108d5bb3eb3389060702265b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=faaee1f07ed25b2779bfd935ffb29f431b80d6d3

commit faaee1f07ed25b2779bfd935ffb29f431b80d6d3
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Jul 14 05:59:29 2018 -0700

    x86: Support shadow stack pointer in setjmp/longjmp
    
    Save and restore shadow stack pointer in setjmp and longjmp to support
    shadow stack in Intel CET.  Use feature_1 in tcbhead_t to check if
    shadow stack is enabled before saving and restoring shadow stack pointer.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    
    	* sysdeps/i386/__longjmp.S: Include <jmp_buf-ssp.h>.
    	(__longjmp): Restore shadow stack pointer if shadow stack is
    	enabled, SHADOW_STACK_POINTER_OFFSET is defined and __longjmp
    	isn't defined for __longjmp_cancel.
    	* sysdeps/i386/bsd-_setjmp.S: Include <jmp_buf-ssp.h>.
    	(_setjmp): Save shadow stack pointer if shadow stack is enabled
    	and SHADOW_STACK_POINTER_OFFSET is defined.
    	* sysdeps/i386/bsd-setjmp.S: Include <jmp_buf-ssp.h>.
    	(setjmp): Save shadow stack pointer if shadow stack is enabled
    	and SHADOW_STACK_POINTER_OFFSET is defined.
    	* sysdeps/i386/setjmp.S: Include <jmp_buf-ssp.h>.
    	(__sigsetjmp): Save shadow stack pointer if shadow stack is
    	enabled and SHADOW_STACK_POINTER_OFFSET is defined.
    	* sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: Include
    	<jmp_buf-ssp.h>.
    	(____longjmp_chk): Restore shadow stack pointer if shadow stack
    	is enabled and SHADOW_STACK_POINTER_OFFSET is defined.
    	* sysdeps/unix/sysv/linux/x86/Makefile (gen-as-const-headers):
    	Remove jmp_buf-ssp.sym.
    	* sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S: Include
    	<jmp_buf-ssp.h>.
    	(____longjmp_chk): Restore shadow stack pointer if shadow stack
    	is enabled and SHADOW_STACK_POINTER_OFFSET is defined.
    	* sysdeps/x86/Makefile (gen-as-const-headers): Add
    	jmp_buf-ssp.sym.
    	* sysdeps/x86/jmp_buf-ssp.sym: New dummy file.
    	* sysdeps/x86_64/__longjmp.S: Include <jmp_buf-ssp.h>.
    	(__longjmp): Restore shadow stack pointer if shadow stack is
    	enabled, SHADOW_STACK_POINTER_OFFSET is defined and __longjmp
    	isn't defined for __longjmp_cancel.
    	* sysdeps/x86_64/setjmp.S: Include <jmp_buf-ssp.h>.
    	(__sigsetjmp): Save shadow stack pointer if shadow stack is
    	enabled and SHADOW_STACK_POINTER_OFFSET is defined.

diff --git a/ChangeLog b/ChangeLog
index e5eead0..c984482 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2018-07-14  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
+	    H.J. Lu  <hongjiu.lu@intel.com>
+
+	* sysdeps/i386/__longjmp.S: Include <jmp_buf-ssp.h>.
+	(__longjmp): Restore shadow stack pointer if shadow stack is
+	enabled, SHADOW_STACK_POINTER_OFFSET is defined and __longjmp
+	isn't defined for __longjmp_cancel.
+	* sysdeps/i386/bsd-_setjmp.S: Include <jmp_buf-ssp.h>.
+	(_setjmp): Save shadow stack pointer if shadow stack is enabled
+	and SHADOW_STACK_POINTER_OFFSET is defined.
+	* sysdeps/i386/bsd-setjmp.S: Include <jmp_buf-ssp.h>.
+	(setjmp): Save shadow stack pointer if shadow stack is enabled
+	and SHADOW_STACK_POINTER_OFFSET is defined.
+	* sysdeps/i386/setjmp.S: Include <jmp_buf-ssp.h>.
+	(__sigsetjmp): Save shadow stack pointer if shadow stack is
+	enabled and SHADOW_STACK_POINTER_OFFSET is defined.
+	* sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: Include
+	<jmp_buf-ssp.h>.
+	(____longjmp_chk): Restore shadow stack pointer if shadow stack
+	is enabled and SHADOW_STACK_POINTER_OFFSET is defined.
+	* sysdeps/unix/sysv/linux/x86/Makefile (gen-as-const-headers):
+	Remove jmp_buf-ssp.sym.
+	* sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S: Include
+	<jmp_buf-ssp.h>.
+	(____longjmp_chk): Restore shadow stack pointer if shadow stack
+	is enabled and SHADOW_STACK_POINTER_OFFSET is defined.
+	* sysdeps/x86/Makefile (gen-as-const-headers): Add
+	jmp_buf-ssp.sym.
+	* sysdeps/x86/jmp_buf-ssp.sym: New dummy file.
+	* sysdeps/x86_64/__longjmp.S: Include <jmp_buf-ssp.h>.
+	(__longjmp): Restore shadow stack pointer if shadow stack is
+	enabled, SHADOW_STACK_POINTER_OFFSET is defined and __longjmp
+	isn't defined for __longjmp_cancel.
+	* sysdeps/x86_64/setjmp.S: Include <jmp_buf-ssp.h>.
+	(__sigsetjmp): Save shadow stack pointer if shadow stack is
+	enabled and SHADOW_STACK_POINTER_OFFSET is defined.
+
 2018-07-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	[BZ #22563]
diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S
index b38333b..6e98ed5 100644
--- a/sysdeps/i386/__longjmp.S
+++ b/sysdeps/i386/__longjmp.S
@@ -18,14 +18,55 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't restore shadow stack register if
+   1. Shadow stack isn't enabled.  Or
+   2. __longjmp is defined for __longjmp_cancel.
+ */
+#if !SHSTK_ENABLED || defined __longjmp
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 	.text
 ENTRY (__longjmp)
 #ifdef PTR_DEMANGLE
 	movl 4(%esp), %eax	/* User's jmp_buf in %eax.  */
 
+# ifdef SHADOW_STACK_POINTER_OFFSET
+#  if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+#  else
+	xorl %edx, %edx
+#  endif
+	/* Check and adjust the Shadow-Stack-Pointer.  */
+	rdsspd %edx
+	/* And compare it with the saved ssp value.  */
+	subl SHADOW_STACK_POINTER_OFFSET(%eax), %edx
+	je L(skip_ssp)
+	/* 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
+	   the number of frames is bigger than 255.  */
+	negl %edx
+	shrl $2, %edx
+	/* NB: We saved Shadow-Stack-Pointer of setjmp.  Since we are
+	       restoring Shadow-Stack-Pointer of setjmp's caller, we
+	       need to unwind shadow stack by one more frame.  */
+	addl $1, %edx
+	movl	$255, %ebx
+L(loop):
+	cmpl	%ebx, %edx
+	cmovb	%edx, %ebx
+	incsspd	%ebx
+	subl	%ebx, %edx
+	ja	L(loop)
+L(skip_ssp):
+# endif
 	/* Save the return address now.  */
 	movl (JB_PC*4)(%eax), %edx
 	/* Get the stack pointer.  */
@@ -56,6 +97,38 @@ ENTRY (__longjmp)
 #else
 	movl 4(%esp), %ecx	/* User's jmp_buf in %ecx.  */
 	movl 8(%esp), %eax	/* Second argument is return value.  */
+# ifdef SHADOW_STACK_POINTER_OFFSET
+#  if IS_IN (libc) && defined SHARED
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+#  endif
+	/* Check and adjust the Shadow-Stack-Pointer.  */
+	xorl %edx, %edx
+	/* Get the current ssp.  */
+	rdsspd	%edx
+	/* And compare it with the saved ssp value.  */
+	subl SHADOW_STACK_POINTER_OFFSET(%ecx), %edx
+	je L(skip_ssp)
+	/* 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
+	   the number of frames is bigger than 255.  */
+	negl %edx
+	shrl $2, %edx
+	/* NB: We saved Shadow-Stack-Pointer of setjmp.  Since we are
+	       restoring Shadow-Stack-Pointer of setjmp's caller, we
+	       need to unwind shadow stack by one more frame.  */
+	addl $1, %edx
+	movl	$255, %ebx
+L(loop):
+	cmpl	%ebx, %edx
+	cmovb	%edx, %ebx
+	incsspd	%ebx
+	subl	%ebx, %edx
+	ja	L(loop)
+L(skip_ssp):
+# endif
 	/* Save the return address now.  */
 	movl (JB_PC*4)(%ecx), %edx
 	LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx)
diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S
index a626cc6..db47df0 100644
--- a/sysdeps/i386/bsd-_setjmp.S
+++ b/sysdeps/i386/bsd-_setjmp.S
@@ -22,12 +22,18 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <stap-probe.h>
 
 #define PARMS	4		/* no space for saved regs */
 #define JMPBUF	PARMS
 #define SIGMSK	JMPBUF+4
 
+/* Don't save shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 ENTRY (_setjmp)
 
 	xorl %eax, %eax
@@ -51,6 +57,21 @@ ENTRY (_setjmp)
 	movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer.  */
 
 	movl %eax, JB_SIZE(%edx) /* No signal mask set.  */
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+# else
+	xorl %ecx, %ecx
+# endif
+	/* Get the current Shadow-Stack-Pointer and save it.  */
+	rdsspd %ecx
+	movl %ecx, SHADOW_STACK_POINTER_OFFSET(%edx)
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+L(skip_ssp):
+# endif
+#endif
 	ret
 END (_setjmp)
 libc_hidden_def (_setjmp)
diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S
index 2da8b73..1290d0d 100644
--- a/sysdeps/i386/bsd-setjmp.S
+++ b/sysdeps/i386/bsd-setjmp.S
@@ -22,12 +22,18 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <stap-probe.h>
 
 #define PARMS  4		/* no space for saved regs */
 #define JMPBUF PARMS
 #define SIGMSK JMPBUF+4
 
+/* Don't save shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 ENTRY (setjmp)
 	/* Note that we have to use a non-exported symbol in the next
 	   jump since otherwise gas will emit it as a jump through the
@@ -51,6 +57,21 @@ ENTRY (setjmp)
 #endif
 	movl %ecx, (JB_PC*4)(%eax)
 	movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer.  */
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+# else
+	xorl %ecx, %ecx
+# endif
+	/* Get the current Shadow-Stack-Pointer and save it.  */
+	rdsspd %ecx
+	movl %ecx, SHADOW_STACK_POINTER_OFFSET(%eax)
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+L(skip_ssp):
+# endif
+#endif
 
 	/* Call __sigjmp_save.  */
 	pushl $1
diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S
index 6a08701..889337b 100644
--- a/sysdeps/i386/setjmp.S
+++ b/sysdeps/i386/setjmp.S
@@ -18,6 +18,7 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
@@ -25,6 +26,11 @@
 #define JMPBUF	PARMS
 #define SIGMSK	JMPBUF+4
 
+/* Don't save shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 ENTRY (__sigsetjmp)
 
 	movl JMPBUF(%esp), %eax
@@ -46,6 +52,21 @@ ENTRY (__sigsetjmp)
 	movl %ecx, (JB_PC*4)(%eax)
 	movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer.  */
 
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+# else
+	xorl %ecx, %ecx
+# endif
+	/* Get the current Shadow-Stack-Pointer and save it.  */
+	rdsspd %ecx
+	movl %ecx, SHADOW_STACK_POINTER_OFFSET(%eax)
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+L(skip_ssp):
+# endif
+#endif
 #if IS_IN (rtld)
 	/* In ld.so we never save the signal mask.  */
 	xorl %eax, %eax
diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
index 3452433..a7640d9 100644
--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
@@ -17,9 +17,14 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't restore shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
 
 	.section .rodata.str1.1,"aMS",@progbits,1
 	.type	longjmp_msg,@object
@@ -46,6 +51,38 @@ longjmp_msg:
 ENTRY (____longjmp_chk)
 	movl	4(%esp), %ecx	/* User's jmp_buf in %ecx.  */
 
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl	$X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
+	jz	L(skip_ssp)
+# else
+	xorl	%edx, %edx
+# endif
+	/* Check and adjust the Shadow-Stack-Pointer.  */
+	rdsspd	%edx
+	/* And compare it with the saved ssp value.  */
+	subl	SHADOW_STACK_POINTER_OFFSET(%ecx), %edx
+	je	L(skip_ssp)
+	/* 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
+	   the number of frames is bigger than 255.  */
+	negl	%edx
+	shrl	$2, %edx
+	/* NB: We saved Shadow-Stack-Pointer of setjmp.  Since we are
+	       restoring Shadow-Stack-Pointer of setjmp's caller, we
+	       need to unwind shadow stack by one more frame.  */
+	addl	$1, %edx
+	movl	$255, %ebx
+L(loop):
+	cmpl	%ebx, %edx
+	cmovb	%edx, %ebx
+	incsspd	%ebx
+	subl	%ebx, %edx
+	ja	L(loop)
+L(skip_ssp):
+#endif
 	/* Save the return address now.  */
 	movl	(JB_PC*4)(%ecx), %edx
 	/* Get the stack pointer.  */
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index c55a43e..111ff9f 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -21,6 +21,5 @@ sysdep_routines += dl-vdso
 endif
 
 ifeq ($(subdir),setjmp)
-gen-as-const-headers += jmp_buf-ssp.sym
 tests += tst-saved_mask-1
 endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
index 8a9f2e1..7eb26fa 100644
--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
@@ -20,7 +20,13 @@
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't restore shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 #include <sigaltstack-offsets.h>
+#include <jmp_buf-ssp.h>
 
 	.section .rodata.str1.1,"aMS",@progbits,1
 	.type	longjmp_msg,@object
@@ -105,6 +111,38 @@ ENTRY(____longjmp_chk)
 	cfi_restore (%rsi)
 
 .Lok:
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz	L(skip_ssp)
+# else
+	xorl	%eax, %eax
+# endif
+	/* Check and adjust the Shadow-Stack-Pointer.  */
+	rdsspq	%rax
+	/* And compare it with the saved ssp value.  */
+	subq	SHADOW_STACK_POINTER_OFFSET(%rdi), %rax
+	je	L(skip_ssp)
+	/* 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
+	   the number of frames is bigger than 255.  */
+	negq	%rax
+	shrq	$3, %rax
+	/* NB: We saved Shadow-Stack-Pointer of setjmp.  Since we are
+	       restoring Shadow-Stack-Pointer of setjmp's caller, we
+	       need to unwind shadow stack by one more frame.  */
+	addq	$1, %rax
+	movl	$255, %ebx
+L(loop):
+	cmpq	%rbx, %rax
+	cmovb	%rax, %rbx
+	incsspq	%rbx
+	subq	%rbx, %rax
+	ja	L(loop)
+L(skip_ssp):
+#endif
 	LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
 	/* We add unwind information for the target here.  */
 	cfi_def_cfa(%rdi, 0)
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index d25d6f0..65292f4 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -10,5 +10,6 @@ tests-static += tst-get-cpu-features-static
 endif
 
 ifeq ($(subdir),setjmp)
+gen-as-const-headers += jmp_buf-ssp.sym
 sysdep_routines += __longjmp_cancel
 endif
diff --git a/sysdeps/x86/jmp_buf-ssp.sym b/sysdeps/x86/jmp_buf-ssp.sym
new file mode 100644
index 0000000..1aaaedc
--- /dev/null
+++ b/sysdeps/x86/jmp_buf-ssp.sym
@@ -0,0 +1 @@
+-- FIXME: Define SHADOW_STACK_POINTER_OFFSET to support shadow stack.
diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S
index a487e0e..d7d123e 100644
--- a/sysdeps/x86_64/__longjmp.S
+++ b/sysdeps/x86_64/__longjmp.S
@@ -17,9 +17,18 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't restore shadow stack register if
+   1. Shadow stack isn't enabled.  Or
+   2. __longjmp is defined for __longjmp_cancel.
+ */
+#if !SHSTK_ENABLED || defined __longjmp
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 /* Jump to the position specified by ENV, causing the
    setjmp call there to return VAL, or 1 if VAL is 0.
    void __longjmp (__jmp_buf env, int val).  */
@@ -42,6 +51,41 @@ ENTRY(__longjmp)
 	orq %rax, %r9
 # endif
 #endif
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+# else
+	xorl %eax, %eax
+# endif
+	/* Check and adjust the Shadow-Stack-Pointer.  */
+	/* Get the current ssp.  */
+	rdsspq %rax
+	/* And compare it with the saved ssp value.  */
+	subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax
+	je L(skip_ssp)
+	/* 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
+	   the number of frames is bigger than 255.  */
+	negq %rax
+	shrq $3, %rax
+	/* NB: We saved Shadow-Stack-Pointer of setjmp.  Since we are
+	       restoring Shadow-Stack-Pointer of setjmp's caller, we
+	       need to unwind shadow stack by one more frame.  */
+	addq $1, %rax
+
+	movl $255, %ebx
+L(loop):
+	cmpq %rbx, %rax
+	cmovb %rax, %rbx
+	incsspq %rbx
+	subq %rbx, %rax
+	ja L(loop)
+
+L(skip_ssp):
+#endif
 	LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
 	/* We add unwind information for the target here.  */
 	cfi_def_cfa(%rdi, 0)
diff --git a/sysdeps/x86_64/setjmp.S b/sysdeps/x86_64/setjmp.S
index e0a648e..78a8bf4 100644
--- a/sysdeps/x86_64/setjmp.S
+++ b/sysdeps/x86_64/setjmp.S
@@ -18,9 +18,15 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't save shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
 ENTRY (__sigsetjmp)
 	/* Save registers.  */
 	movq %rbx, (JB_RBX*8)(%rdi)
@@ -54,6 +60,21 @@ ENTRY (__sigsetjmp)
 #endif
 	movq %rax, (JB_PC*8)(%rdi)
 
+#ifdef SHADOW_STACK_POINTER_OFFSET
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+	/* Check if Shadow Stack is enabled.  */
+	testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz L(skip_ssp)
+# else
+	xorl %eax, %eax
+# endif
+	/* Get the current Shadow-Stack-Pointer and save it.  */
+	rdsspq %rax
+	movq %rax, SHADOW_STACK_POINTER_OFFSET(%rdi)
+# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
+L(skip_ssp):
+# endif
+#endif
 #if IS_IN (rtld)
 	/* In ld.so we never save the signal mask.  */
 	xorl %eax, %eax

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ebff9c5cfae62e84dbd0456d564bd882818dc15f

commit ebff9c5cfae62e84dbd0456d564bd882818dc15f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Jul 14 05:53:05 2018 -0700

    x86: Rename __glibc_reserved1 to feature_1 in tcbhead_t [BZ #22563]
    
    feature_1 has X86_FEATURE_1_IBT and X86_FEATURE_1_SHSTK bits for CET
    run-time control.
    
    CET_ENABLED, IBT_ENABLED and SHSTK_ENABLED are defined to 1 or 0 to
    indicate that if CET, IBT and SHSTK are enabled.
    
    <tls-setup.h> is added to set up thread-local data.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    
    	[BZ #22563]
    	* nptl/pthread_create.c: Include <tls-setup.h>.
    	(__pthread_create_2_1): Call tls_setup_tcbhead.
    	* sysdeps/generic/tls-setup.h: New file.
    	* sysdeps/x86/nptl/tls-setup.h: Likewise.
    	* sysdeps/i386/nptl/tcb-offsets.sym (FEATURE_1_OFFSET): New.
    	* sysdeps/x86_64/nptl/tcb-offsets.sym (FEATURE_1_OFFSET):
    	Likewise.
    	* sysdeps/i386/nptl/tls.h (tcbhead_t): Rename __glibc_reserved1
    	to feature_1.
    	* sysdeps/x86_64/nptl/tls.h (tcbhead_t): Likewise.
    	* sysdeps/x86/sysdep.h (X86_FEATURE_1_IBT): New.
    	(X86_FEATURE_1_SHSTK): Likewise.
    	(CET_ENABLED): Likewise.
    	(IBT_ENABLED): Likewise.
    	(SHSTK_ENABLED): Likewise.

diff --git a/ChangeLog b/ChangeLog
index 981e65e..e5eead0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2018-07-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+	[BZ #22563]
+	* nptl/pthread_create.c: Include <tls-setup.h>.
+	(__pthread_create_2_1): Call tls_setup_tcbhead.
+	* sysdeps/generic/tls-setup.h: New file.
+	* sysdeps/x86/nptl/tls-setup.h: Likewise.
+	* sysdeps/i386/nptl/tcb-offsets.sym (FEATURE_1_OFFSET): New.
+	* sysdeps/x86_64/nptl/tcb-offsets.sym (FEATURE_1_OFFSET):
+	Likewise.
+	* sysdeps/i386/nptl/tls.h (tcbhead_t): Rename __glibc_reserved1
+	to feature_1.
+	* sysdeps/x86_64/nptl/tls.h (tcbhead_t): Likewise.
+	* sysdeps/x86/sysdep.h (X86_FEATURE_1_IBT): New.
+	(X86_FEATURE_1_SHSTK): Likewise.
+	(CET_ENABLED): Likewise.
+	(IBT_ENABLED): Likewise.
+	(SHSTK_ENABLED): Likewise.
+
 2018-07-13  Rafal Luzynski  <digitalfreak@lingonborough.com>
 
 	[BZ #23208]
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 92c945b..5f5a007 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -32,6 +32,7 @@
 #include <exit-thread.h>
 #include <default-sched.h>
 #include <futex-internal.h>
+#include <tls-setup.h>
 #include "libioP.h"
 
 #include <shlib-compat.h>
@@ -712,6 +713,9 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
   THREAD_COPY_POINTER_GUARD (pd);
 #endif
 
+  /* Setup tcbhead.  */
+  tls_setup_tcbhead (pd);
+
   /* Verify the sysinfo bits were copied in allocate_stack if needed.  */
 #ifdef NEED_DL_SYSINFO
   CHECK_THREAD_SYSINFO (pd);
diff --git a/sysdeps/generic/tls-setup.h b/sysdeps/generic/tls-setup.h
new file mode 100644
index 0000000..8d0c36d
--- /dev/null
+++ b/sysdeps/generic/tls-setup.h
@@ -0,0 +1,22 @@
+/* Definitions to set up thread-local data.  Generic version.
+   Copyright (C) 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/>.  */
+
+static inline void __attribute__ ((always_inline))
+tls_setup_tcbhead (struct pthread *pd)
+{
+}
diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
index 7d7fe5e..fbac241 100644
--- a/sysdeps/i386/nptl/tcb-offsets.sym
+++ b/sysdeps/i386/nptl/tcb-offsets.sym
@@ -12,3 +12,4 @@ CLEANUP			offsetof (struct pthread, cleanup)
 CLEANUP_PREV		offsetof (struct _pthread_cleanup_buffer, __prev)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
+FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index afb71ce..21e23cd 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -41,7 +41,10 @@ typedef struct
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
   int gscope_flag;
-  int __glibc_reserved1;
+  /* Bit 0: X86_FEATURE_1_IBT.
+     Bit 1: X86_FEATURE_1_SHSTK.
+   */
+  unsigned int feature_1;
   /* Reservation of some values for the TM ABI.  */
   void *__private_tm[3];
   /* GCC split stack support.  */
diff --git a/sysdeps/x86/nptl/tls-setup.h b/sysdeps/x86/nptl/tls-setup.h
new file mode 100644
index 0000000..ef5a4df
--- /dev/null
+++ b/sysdeps/x86/nptl/tls-setup.h
@@ -0,0 +1,23 @@
+/* Definitions to set up thread-local data.  x86 version.
+   Copyright (C) 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/>.  */
+
+static inline void __attribute__ ((always_inline))
+tls_setup_tcbhead (struct pthread *pd)
+{
+  pd->header.feature_1 = THREAD_GETMEM (THREAD_SELF, header.feature_1);
+}
diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
index afcb7cf..976566a 100644
--- a/sysdeps/x86/sysdep.h
+++ b/sysdeps/x86/sysdep.h
@@ -21,6 +21,33 @@
 
 #include <sysdeps/generic/sysdep.h>
 
+/* __CET__ is defined by GCC with Control-Flow Protection values:
+
+enum cf_protection_level
+{
+  CF_NONE = 0,
+  CF_BRANCH = 1 << 0,
+  CF_RETURN = 1 << 1,
+  CF_FULL = CF_BRANCH | CF_RETURN,
+  CF_SET = 1 << 2
+};
+*/
+
+/* Set if CF_BRANCH (IBT) is enabled.  */
+#define X86_FEATURE_1_IBT	(1U << 0)
+/* Set if CF_RETURN (SHSTK) is enabled.  */
+#define X86_FEATURE_1_SHSTK	(1U << 1)
+
+#ifdef __CET__
+# define CET_ENABLED	1
+# define IBT_ENABLED	(__CET__ & X86_FEATURE_1_IBT)
+# define SHSTK_ENABLED	(__CET__ & X86_FEATURE_1_SHSTK)
+#else
+# define CET_ENABLED	0
+# define IBT_ENABLED	0
+# define SHSTK_ENABLED	0
+#endif
+
 #ifdef	__ASSEMBLER__
 
 /* Syntactic details of assembler.  */
diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
index be63404..387621e 100644
--- a/sysdeps/x86_64/nptl/tcb-offsets.sym
+++ b/sysdeps/x86_64/nptl/tcb-offsets.sym
@@ -12,6 +12,7 @@ MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
 VGETCPU_CACHE_OFFSET	offsetof (tcbhead_t, vgetcpu_cache)
+FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
 
 -- Not strictly offsets, but these values are also used in the TCB.
 TCB_CANCELSTATE_BITMASK	 CANCELSTATE_BITMASK
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 65c0051..f042a02 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -51,7 +51,10 @@ typedef struct
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
   unsigned long int vgetcpu_cache[2];
-  int __glibc_reserved1;
+  /* Bit 0: X86_FEATURE_1_IBT.
+     Bit 1: X86_FEATURE_1_SHSTK.
+   */
+  unsigned int feature_1;
   int __glibc_unused1;
   /* Reservation of some values for the TM ABI.  */
   void *__private_tm[4];

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                        |   56 +++++++++++++++++
 nptl/pthread_create.c                            |    4 +
 sysdeps/generic/tls-setup.h                      |   22 +++++++
 sysdeps/i386/__longjmp.S                         |   73 ++++++++++++++++++++++
 sysdeps/i386/bsd-_setjmp.S                       |   21 ++++++
 sysdeps/i386/bsd-setjmp.S                        |   21 ++++++
 sysdeps/i386/nptl/tcb-offsets.sym                |    1 +
 sysdeps/i386/nptl/tls.h                          |    5 +-
 sysdeps/i386/setjmp.S                            |   21 ++++++
 sysdeps/unix/sysv/linux/i386/____longjmp_chk.S   |   37 +++++++++++
 sysdeps/unix/sysv/linux/x86/Makefile             |    1 -
 sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S |   38 +++++++++++
 sysdeps/x86/Makefile                             |    1 +
 sysdeps/x86/jmp_buf-ssp.sym                      |    1 +
 sysdeps/x86/nptl/tls-setup.h                     |   23 +++++++
 sysdeps/x86/sysdep.h                             |   27 ++++++++
 sysdeps/x86_64/__longjmp.S                       |   44 +++++++++++++
 sysdeps/x86_64/nptl/tcb-offsets.sym              |    1 +
 sysdeps/x86_64/nptl/tls.h                        |    5 +-
 sysdeps/x86_64/setjmp.S                          |   21 ++++++
 20 files changed, 420 insertions(+), 3 deletions(-)
 create mode 100644 sysdeps/generic/tls-setup.h
 create mode 100644 sysdeps/x86/jmp_buf-ssp.sym
 create mode 100644 sysdeps/x86/nptl/tls-setup.h


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]