This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch hjl/setjmp/pad created. glibc-2.27.9000-117-g4c5ed35
- From: hjl at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 25 Feb 2018 01:26:53 -0000
- Subject: 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