]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Support shadow stack pointer in setjmp/longjmp
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 14 Jul 2018 12:59:29 +0000 (05:59 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 14 Jul 2018 12:59:53 +0000 (05:59 -0700)
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.

12 files changed:
ChangeLog
sysdeps/i386/__longjmp.S
sysdeps/i386/bsd-_setjmp.S
sysdeps/i386/bsd-setjmp.S
sysdeps/i386/setjmp.S
sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
sysdeps/unix/sysv/linux/x86/Makefile
sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
sysdeps/x86/Makefile
sysdeps/x86/jmp_buf-ssp.sym [new file with mode: 0644]
sysdeps/x86_64/__longjmp.S
sysdeps/x86_64/setjmp.S

index e5eead0f0fe74a595806e7783495dbc881be6b13..c9844826b04661255d763bb5b129b6b12a53177a 100644 (file)
--- 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]
index b38333bead753e4634f820234ad628f85b74a994..6e98ed538da6aaad6c7aca04b56cd32fcaee31be 100644 (file)
 
 #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)
index a626cc6d220a7d90af63f5cf63fa8c62eaf7ce95..db47df0ba1fcebdf34cc3908cd1e799c51e94c07 100644 (file)
 
 #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)
index 2da8b73c49b6a85b756cf64c4bcd7d5f9e81f914..1290d0d82ba6508a65872822fb6e319e45ac3a00 100644 (file)
 
 #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
index 6a0870171782fc9f4dd76511946f7b65b9872fe7..889337b8aeb244b89fd2d5bcbf0173422b5b638c 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <sysdep.h>
 #include <jmpbuf-offsets.h>
+#include <jmp_buf-ssp.h>
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
 #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
index 34524331122c237f3095a4169b3c7070f03be5ce..a7640d989248529b140be490c958d5a74a918037 100644 (file)
 
 #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.  */
index c55a43e58d848896c7be6c09ab5657a6bd33a48f..111ff9ff58c098c9abf59955149ec827f1302b0b 100644 (file)
@@ -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
index 8a9f2e1a3c624bb43702009a5e13de872a5031a1..7eb26fafca4827f8681a8bec692edc90406f4df9 100644 (file)
 #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)
index d25d6f0ae43c29a050787f47333edcbe72ac98f0..65292f40323e4527490a4888b66c86c1e8a1e64a 100644 (file)
@@ -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 (file)
index 0000000..1aaaedc
--- /dev/null
@@ -0,0 +1 @@
+-- FIXME: Define SHADOW_STACK_POINTER_OFFSET to support shadow stack.
index a487e0efd0ca44a122ef915acaced41a101068d4..d7d123e4bcc65dea08e9bfb4a9043047410de6f7 100644 (file)
 
 #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).  */
@@ -41,6 +50,41 @@ ENTRY(__longjmp)
        shlq $32, %rax
        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.  */
index e0a648e3e4ffd0b7fa8be6c9a5f574b3502ead35..78a8bf46442dedfbf5ccce4c2017da33f313d9cf 100644 (file)
 
 #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