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-615-g3650e1d


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  3650e1d9284926be67e368707a9a2276fb77a167 (commit)
      from  ca027e0f62789a0958b69dac4133616a90de6f7c (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=3650e1d9284926be67e368707a9a2276fb77a167

commit 3650e1d9284926be67e368707a9a2276fb77a167
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 24 05:20:48 2018 -0700

    x86: Update vfork to pop shadow stack
    
    The shadow stack prevents us from pushing the saved return PC onto
    the stack and returning normally.  Instead we pop the shadow stack
    and return directly.  This is the safest way to return and ensures
    any stack manipulations done by the vfork'd child doesn't cause the
    parent to terminate when CET is enabled.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    
    	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
    	Redefine if shadow stack is enabled.
    	(SYSCALL_ERROR_LABEL): Likewise.
    	(__vfork): Pop shadow stack and jump back to to caller directly
    	when shadow stack is in use.
    	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
    	Redefine if shadow stack is enabled.
    	(SYSCALL_ERROR_LABEL): Likewise.
    	(__vfork): Pop shadow stack and jump back to to caller directly
    	when shadow stack is in use.

diff --git a/ChangeLog b/ChangeLog
index 2a1a53d..8b892eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2018-07-24  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
+	Redefine if shadow stack is enabled.
+	(SYSCALL_ERROR_LABEL): Likewise.
+	(__vfork): Pop shadow stack and jump back to to caller directly
+	when shadow stack is in use.
+	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
+	Redefine if shadow stack is enabled.
+	(SYSCALL_ERROR_LABEL): Likewise.
+	(__vfork): Pop shadow stack and jump back to to caller directly
+	when shadow stack is in use.
+
+2018-07-24  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
 	enabled.
 	(foo): Likewise.
diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S
index 8f40d02..ce6dbfa 100644
--- a/sysdeps/unix/sysv/linux/i386/vfork.S
+++ b/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -21,6 +21,38 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* The shadow stack prevents us from pushing the saved return PC onto
+   the stack and returning normally.  Instead we pop the shadow stack
+   and return directly.  This is the safest way to return and ensures
+   any stack manipulations done by the vfork'd child doesn't cause the
+   parent to terminate when CET is enabled.  */
+# undef SYSCALL_ERROR_HANDLER
+# ifdef PIC
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  calll .L1;						\
+.L1:							\
+  popl %edx;						\
+.L2:							\
+  addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx;	\
+  movl __libc_errno@gotntpoff(%edx), %edx;		\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# else
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  movl __libc_errno@indntpoff, %edx;			\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# endif
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,16 +70,41 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	int	$0x80
 
+#if !SHSTK_ENABLED
 	/* Jump to the return PC.  Don't jump directly since this
 	   disturbs the branch target cache.  Instead push the return
 	   address back on the stack.  */
 	pushl	%ecx
 	cfi_adjust_cfa_offset (4)
+#endif
 
 	cmpl	$-4095, %eax
 	/* Branch forward if it failed.  */
 	jae	SYSCALL_ERROR_LABEL
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%edx, %edx
+	rdsspd	%edx
+	testl	%edx, %edx
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %edx
+	incsspd	%edx
+	jmp	*%ecx
+
+L(no_shstk):
+	/* Jump to the return PC.  Don't jump directly since this
+	   disturbs the branch target cache.  Instead push the return
+	   address back on the stack.  */
+	pushl	%ecx
+	cfi_adjust_cfa_offset (4)
+#endif
+
 	ret
 
 PSEUDO_END (__vfork)
diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
index e4c8269..8f1ca9f 100644
--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -20,6 +20,21 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* The shadow stack prevents us from pushing the saved return PC onto
+   the stack and returning normally.  Instead we pop the shadow stack
+   and return directly.  This is the safest way to return and ensures
+   any stack manipulations done by the vfork'd child doesn't cause the
+   parent to terminate when CET is enabled.  */
+# undef SYSCALL_ERROR_HANDLER
+# define SYSCALL_ERROR_HANDLER			\
+0:						\
+  SYSCALL_SET_ERRNO;				\
+  or $-1, %RAX_LP;				\
+  jmp 1b;
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,13 +53,36 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	syscall
 
+#if !SHSTK_ENABLED
 	/* Push back the return PC.  */
 	pushq	%rdi
 	cfi_adjust_cfa_offset(8)
+#endif
 
 	cmpl	$-4095, %eax
 	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%esi, %esi
+	rdsspq	%rsi
+	testq	%rsi, %rsi
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %esi
+	incsspq	%rsi
+	jmp	*%rdi
+
+L(no_shstk):
+	/* Push back the return PC.  */
+	pushq	%rdi
+	cfi_adjust_cfa_offset(8)
+#endif
+
 	/* Normal return.  */
 	ret
 

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

Summary of changes:
 ChangeLog                              |   13 +++++++
 sysdeps/unix/sysv/linux/i386/vfork.S   |   57 ++++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/vfork.S |   38 +++++++++++++++++++++
 3 files changed, 108 insertions(+), 0 deletions(-)


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]