aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/i386/bsd-_setjmp.S
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-07-14 05:59:29 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-07-14 05:59:53 -0700
commitfaaee1f07ed25b2779bfd935ffb29f431b80d6d3 (patch)
tree3c85f88e2312c67e0f0e54be10b0bec833c7541f /sysdeps/i386/bsd-_setjmp.S
parentebff9c5cfae62e84dbd0456d564bd882818dc15f (diff)
downloadglibc-faaee1f07ed25b2779bfd935ffb29f431b80d6d3.zip
glibc-faaee1f07ed25b2779bfd935ffb29f431b80d6d3.tar.gz
glibc-faaee1f07ed25b2779bfd935ffb29f431b80d6d3.tar.bz2
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.
Diffstat (limited to 'sysdeps/i386/bsd-_setjmp.S')
-rw-r--r--sysdeps/i386/bsd-_setjmp.S21
1 files changed, 21 insertions, 0 deletions
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)