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 hjl/setjmp/pad created. glibc-2.27.9000-117-g4c5ed35


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, hjl/setjmp/pad has been created
        at  4c5ed35228662e066cab2865ad3cf19bc0d2ef2b (commit)

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

commit 4c5ed35228662e066cab2865ad3cf19bc0d2ef2b
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Feb 24 17:23:54 2018 -0800

    x86: Use pad in pthread_unwind_buf to preserve shadow stack register
    
    Use pad array in truct pthread_unwind_buf to save and restore shadow
    stack register if size of struct pthread_unwind_buf is no less than
    offset of shadow stack pointer + shadow stack pointer size.
    
    Add a check in  x86-64 setjmp/longjmp by storing (int64_t) -1 as
    shadow stack register.

diff --git a/sysdeps/unix/sysv/linux/x86/setjmpP.h b/sysdeps/unix/sysv/linux/x86/setjmpP.h
index c0ed767..6853af9 100644
--- a/sysdeps/unix/sysv/linux/x86/setjmpP.h
+++ b/sysdeps/unix/sysv/linux/x86/setjmpP.h
@@ -21,9 +21,8 @@
 
 #include <bits/types/__sigset_t.h>
 
-/* The biggest signal number + 1.  As of kernel 4.14, x86 _NSIG is 64.
-   Define it to 513 to leave some rooms for future use.  */
-#define _JUMP_BUF_SIGSET_NSIG	513
+/* The biggest signal number + 1.  As of kernel 4.15, x86 _NSIG is 64.  */
+#define _JUMP_BUF_SIGSET_NSIG	65
 /* Number of longs to hold all signals.  */
 #define _JUMP_BUF_SIGSET_NWORDS \
   ((_JUMP_BUF_SIGSET_NSIG - 1 + 7) / (8 * sizeof (unsigned long int)))
@@ -64,4 +63,47 @@ extern  __typeof (___buf[0].__saved_mask) ___saved_mask;
 _Static_assert (sizeof (___saved_mask) >= sizeof (__sigprocmask_sigset_t),
 		"size of ___saved_mask < size of __sigprocmask_sigset_t");
 
+#if IS_IN (libpthread)
+/* <nptl/descr.h> has
+
+struct pthread_unwind_buf
+{
+  struct
+  {
+    __jmp_buf jmp_buf;
+    int mask_was_saved;
+  } cancel_jmp_buf[1];
+
+  union
+  {
+    void *pad[4];
+    struct
+    {
+      struct pthread_unwind_buf *prev;
+      struct _pthread_cleanup_buffer *cleanup;
+      int canceltype;
+    } data;
+  } priv;
+};
+
+  Use pad array in truct pthread_unwind_buf to save and restore shadow
+  stack register if size of struct pthread_unwind_buf is no less than
+  offset of shadow stack pointer + shadow stack pointer size.   */
+
+# include <pthreadP.h>
+# include <jmp_buf-ssp.h>
+
+# ifdef __x86_64__
+#  define SHADOW_STACK_POINTER_SIZE 8
+# else
+#  define SHADOW_STACK_POINTER_SIZE 4
+# endif
+
+_Static_assert ((sizeof (struct pthread_unwind_buf)
+		 >= (SHADOW_STACK_POINTER_OFFSET
+		     + SHADOW_STACK_POINTER_SIZE)),
+		"size of struct pthread_unwind_buf < "
+		"(SHADOW_STACK_POINTER_OFFSET + SHADOW_STACK_POINTER_SIZE)");
+#endif
+
 #endif /* setjmpP.h  */
diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S
index a487e0e..642f6f8 100644
--- a/sysdeps/x86_64/__longjmp.S
+++ b/sysdeps/x86_64/__longjmp.S
@@ -17,6 +17,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 @@
    void __longjmp (__jmp_buf env, int val).  */
 	.text
 ENTRY(__longjmp)
+	/* Verify that shadow stack field isn't changed by struct
+	   pthread_unwind_buf.  */
+	cmpq $-1, SHADOW_STACK_POINTER_OFFSET(%rdi)
+	jnz L(hlt)
+
 	/* Restore registers.  */
 	mov (JB_RSP*8)(%rdi),%R8_LP
 	mov (JB_RBP*8)(%rdi),%R9_LP
@@ -65,4 +71,7 @@ ENTRY(__longjmp)
 	LIBC_PROBE (longjmp_target, 3,
 		    LP_SIZE@%RDI_LP, -4@%eax, LP_SIZE@%RDX_LP)
 	jmpq *%rdx
+
+L(hlt):
+	hlt
 END (__longjmp)
diff --git a/sysdeps/x86_64/setjmp.S b/sysdeps/x86_64/setjmp.S
index e0a648e..c15bbf8 100644
--- a/sysdeps/x86_64/setjmp.S
+++ b/sysdeps/x86_64/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>
 
@@ -54,6 +55,10 @@ ENTRY (__sigsetjmp)
 #endif
 	movq %rax, (JB_PC*8)(%rdi)
 
+	/* Set shadow stack field to see if it works with struct
+	   pthread_unwind_buf.  */
+	movq $-1, SHADOW_STACK_POINTER_OFFSET(%rdi)
+
 #if IS_IN (rtld)
 	/* In ld.so we never save the signal mask.  */
 	xorl %eax, %eax

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


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]