[02/24] x86: Support shadow stack pointer in setjmp/longjmp

Message ID 20180613153207.57232-3-hjl.tools@gmail.com
State Superseded
Headers show
Series
  • CET: Prepare for CET enabling
Related show

Commit Message

H.J. Lu June 13, 2018, 3:31 p.m.
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 so that it works with the old smaller cancel_jmp_buf which
doesn't have space for shadow stack pointer.

2017-12-07  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.
---
 sysdeps/i386/__longjmp.S                      | 78 +++++++++++++++++++
 sysdeps/i386/bsd-_setjmp.S                    | 21 +++++
 sysdeps/i386/bsd-setjmp.S                     | 21 +++++
 sysdeps/i386/setjmp.S                         | 21 +++++
 .../unix/sysv/linux/i386/____longjmp_chk.S    | 40 ++++++++++
 sysdeps/unix/sysv/linux/x86/Makefile          |  1 -
 .../unix/sysv/linux/x86_64/____longjmp_chk.S  | 41 ++++++++++
 sysdeps/x86/Makefile                          |  1 +
 sysdeps/x86/jmp_buf-ssp.sym                   |  1 +
 sysdeps/x86_64/__longjmp.S                    | 45 +++++++++++
 sysdeps/x86_64/setjmp.S                       | 21 +++++
 11 files changed, 290 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/x86/jmp_buf-ssp.sym

-- 
2.17.1

Comments

Carlos O'Donell July 12, 2018, 6:13 p.m. | #1
On 06/13/2018 11:31 AM, H.J. Lu wrote:
> 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 so that it works with the old smaller cancel_jmp_buf which

> doesn't have space for shadow stack pointer.


This comment can't be accurate. For the older smaller cancel_jmp_buf
we found another way to solve this because you just don't restore the
shadowstack since we're jumping out through the unwinder. So we only
need this logically for setjmp/longjmp and *context functions?

In general this is OK, I'd like to see a v2:

- New accurate commit message.
- Replace (1 << 1) with meaningful macro constants that help a future
  reader identify which FEATURE_1 flag we're looking at.

> 

> 2017-12-07  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.

> ---

>  sysdeps/i386/__longjmp.S                      | 78 +++++++++++++++++++

>  sysdeps/i386/bsd-_setjmp.S                    | 21 +++++

>  sysdeps/i386/bsd-setjmp.S                     | 21 +++++

>  sysdeps/i386/setjmp.S                         | 21 +++++

>  .../unix/sysv/linux/i386/____longjmp_chk.S    | 40 ++++++++++

>  sysdeps/unix/sysv/linux/x86/Makefile          |  1 -

>  .../unix/sysv/linux/x86_64/____longjmp_chk.S  | 41 ++++++++++

>  sysdeps/x86/Makefile                          |  1 +

>  sysdeps/x86/jmp_buf-ssp.sym                   |  1 +

>  sysdeps/x86_64/__longjmp.S                    | 45 +++++++++++

>  sysdeps/x86_64/setjmp.S                       | 21 +++++

>  11 files changed, 290 insertions(+), 1 deletion(-)

>  create mode 100644 sysdeps/x86/jmp_buf-ssp.sym

> 

> diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S

> index b38333bead..8b5d7f3d44 100644

> --- a/sysdeps/i386/__longjmp.S

> +++ b/sysdeps/i386/__longjmp.S

> @@ -18,14 +18,57 @@

>  

>  #include <sysdep.h>

>  #include <jmpbuf-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  #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 !defined __CET__ || (__CET__ & 2) == 0 || defined __longjmp

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  	.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 $(1 << 1), %gs:FEATURE_1_OFFSET


Please replace all instances of "1" here with some kind of macro
that actually defines which flag we're checking.

> +	jz .Lnoadj

> +#  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 .Lnoadj

> +	/* 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

> +	cmpl $255, %edx

> +	jbe .Lonetime

> +.Loopadj:

> +	incsspd %edx

> +	subl $255, %edx

> +	cmpl $255, %edx

> +	ja .Loopadj

> +.Lonetime:

> +	incsspd %edx

> +.Lnoadj:

> +# endif


OK.

>  	/* Save the return address now.  */

>  	movl (JB_PC*4)(%eax), %edx

>  	/* Get the stack pointer.  */

> @@ -56,6 +99,41 @@ 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 $(1 << 1), %gs:FEATURE_1_OFFSET

> +	jz .Lnoadj

> +#  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 .Lnoadj

> +	/* 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.  */


OK.

> +	addl $1, %edx

> +	cmpl $255, %edx

> +	jbe .Lonetime

> +	movl $255, %ebx

> +.Loopadj:

> +	incsspd %ebx

> +	subl $255, %edx

> +	cmpl $255, %edx

> +	ja .Loopadj

> +.Lonetime:

> +	incsspd %edx

> +.Lnoadj:


OK.

> +# endif

>  	/* Save the return address now.  */

>  	movl (JB_PC*4)(%ecx), %edx

>  	LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx)

> diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S

> index a626cc6d22..5b09e5dbf8 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>


OK.

>  #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 !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif


OK.

> +

>  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 $(1 << 1), %gs:FEATURE_1_OFFSET

> +	jz .Lskip_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

> +.Lskip_ssp:

> +# endif

> +#endif


OK.

>  	ret

>  END (_setjmp)

>  libc_hidden_def (_setjmp)

> diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S

> index 2da8b73c49..5f5db092e5 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>


OK.

>  #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 !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  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 $(1 << 1), %gs:FEATURE_1_OFFSET

> +	jz .Lskip_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

> +.Lskip_ssp:

> +# endif

> +#endif


OK.

>  

>  	/* Call __sigjmp_save.  */

>  	pushl $1

> diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S

> index 6a08701717..31e26fd6d4 100644

> --- a/sysdeps/i386/setjmp.S

> +++ b/sysdeps/i386/setjmp.S

> @@ -18,6 +18,7 @@

>  

>  #include <sysdep.h>

>  #include <jmpbuf-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  #include <asm-syntax.h>

>  #include <stap-probe.h>

>  

> @@ -25,6 +26,11 @@

>  #define JMPBUF	PARMS

>  #define SIGMSK	JMPBUF+4

>  

> +/* Don't save shadow stack register if shadow stack isn't enabled.  */

> +#if !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  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 $(1 << 1), %gs:FEATURE_1_OFFSET

> +	jz .Lskip_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

> +.Lskip_ssp:

> +# endif

> +#endif


OK.

>  #if IS_IN (rtld)

>  	/* In ld.so we never save the signal mask.  */

>  	xorl %eax, %eax

> diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S

> index 3452433112..7b4f4caa35 100644

> --- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S

> +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S

> @@ -17,9 +17,14 @@

>  

>  #include <sysdep.h>

>  #include <jmpbuf-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  #include <asm-syntax.h>

>  #include <stap-probe.h>

>  

> +/* Don't restore shadow stack register if shadow stack isn't enabled.  */

> +#if !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif


OK.

>  

>  	.section .rodata.str1.1,"aMS",@progbits,1

>  	.type	longjmp_msg,@object

> @@ -46,6 +51,41 @@ 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   $(1 << 1), %gs:FEATURE_1_OFFSET

> +	jz      .Lnoadj

> +# 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	.Lnoadj

> +	/* 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

> +	cmpl	$255, %edx

> +	jbe	.Lonetime

> +	movl	$255, %ebx

> +.Loopadj:

> +	incsspd	%ebx

> +	subl	$255, %edx

> +	cmpl	$255, %edx

> +	ja	.Loopadj

> +.Lonetime:

> +	incsspd	%edx

> +.Lnoadj:

> +#endif


OK.

>  	/* Save the return address now.  */

>  	movl	(JB_PC*4)(%ecx), %edx

>  	/* Get the stack pointer.  */

> diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile

> index c55a43e58d..111ff9ff58 100644

> --- a/sysdeps/unix/sysv/linux/x86/Makefile

> +++ b/sysdeps/unix/sysv/linux/x86/Makefile

> @@ -21,6 +21,5 @@ sysdep_routines += dl-vdso

>  endif

>  

>  ifeq ($(subdir),setjmp)

> -gen-as-const-headers += jmp_buf-ssp.sym


OK.

>  tests += tst-saved_mask-1

>  endif

> diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S

> index 8a9f2e1a3c..d42289221d 100644

> --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S

> +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S

> @@ -20,7 +20,13 @@

>  #include <asm-syntax.h>

>  #include <stap-probe.h>

>  

> +/* Don't restore shadow stack register if shadow stack isn't enabled.  */

> +#if !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  #include <sigaltstack-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  

>  	.section .rodata.str1.1,"aMS",@progbits,1

>  	.type	longjmp_msg,@object

> @@ -105,6 +111,41 @@ 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	$(1 << 1), %fs:FEATURE_1_OFFSET

> +	jz	.Lnoadj

> +# 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	.Lnoadj

> +	/* 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

> +	cmpq	$255, %rax

> +	jbe	.Lonetime

> +	movl	$255, %ebx

> +.Loopadj:

> +	incsspq	%rbx

> +	subq	$255, %rax

> +	cmpq	$255, %rax

> +	ja	.Loopadj

> +.Lonetime:

> +	incsspq	%rax

> +.Lnoadj:

> +#endif


OK.

>  	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)

> diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile

> index d25d6f0ae4..65292f4032 100644

> --- a/sysdeps/x86/Makefile

> +++ b/sysdeps/x86/Makefile

> @@ -10,5 +10,6 @@ tests-static += tst-get-cpu-features-static

>  endif

>  

>  ifeq ($(subdir),setjmp)

> +gen-as-const-headers += jmp_buf-ssp.sym


OK.

>  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

> index 0000000000..1aaaedc9ec

> --- /dev/null

> +++ b/sysdeps/x86/jmp_buf-ssp.sym

> @@ -0,0 +1 @@

> +-- FIXME: Define SHADOW_STACK_POINTER_OFFSET to support shadow stack.

> diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S

> index a487e0efd0..a9ebe3226e 100644

> --- a/sysdeps/x86_64/__longjmp.S

> +++ b/sysdeps/x86_64/__longjmp.S

> @@ -17,9 +17,18 @@

>  

>  #include <sysdep.h>

>  #include <jmpbuf-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  #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 !defined __CET__ || (__CET__ & 2) == 0 || defined __longjmp

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  /* 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,42 @@ 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 $(1 << 1), %fs:FEATURE_1_OFFSET

> +	jz .Lnoadj

> +# 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 .Lnoadj

> +	/* 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

> +	cmpq $255, %rax

> +	jbe .Lonetime

> +	movl $255, %ebx

> +.Loopadj:

> +	incsspq %rbx

> +	subq $255, %rax

> +	cmpq $255, %rax

> +	ja .Loopadj

> +.Lonetime:

> +	incsspq %rax

> +.Lnoadj:


OK.

>  #endif

>  	LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)

>  	/* We add unwind information for the target here.  */

> diff --git a/sysdeps/x86_64/setjmp.S b/sysdeps/x86_64/setjmp.S

> index e0a648e3e4..bd9bb0ee6b 100644

> --- a/sysdeps/x86_64/setjmp.S

> +++ b/sysdeps/x86_64/setjmp.S

> @@ -18,9 +18,15 @@

>  

>  #include <sysdep.h>

>  #include <jmpbuf-offsets.h>

> +#include <jmp_buf-ssp.h>


OK.

>  #include <asm-syntax.h>

>  #include <stap-probe.h>

>  

> +/* Don't save shadow stack register if shadow stack isn't enabled.  */

> +#if !defined __CET__ || (__CET__ & 2) == 0

> +# undef SHADOW_STACK_POINTER_OFFSET

> +#endif

> +


OK.

>  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 $(1 << 1), %fs:FEATURE_1_OFFSET

> +	jz .Lskip_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

> +.Lskip_ssp:

> +# endif

> +#endif


OK.

>  #if IS_IN (rtld)

>  	/* In ld.so we never save the signal mask.  */

>  	xorl %eax, %eax

> 



-- 
Cheers,
Carlos.

Patch

diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S
index b38333bead..8b5d7f3d44 100644
--- a/sysdeps/i386/__longjmp.S
+++ b/sysdeps/i386/__longjmp.S
@@ -18,14 +18,57 @@ 
 
 #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 !defined __CET__ || (__CET__ & 2) == 0 || 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 $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz .Lnoadj
+#  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 .Lnoadj
+	/* 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
+	cmpl $255, %edx
+	jbe .Lonetime
+.Loopadj:
+	incsspd %edx
+	subl $255, %edx
+	cmpl $255, %edx
+	ja .Loopadj
+.Lonetime:
+	incsspd %edx
+.Lnoadj:
+# endif
 	/* Save the return address now.  */
 	movl (JB_PC*4)(%eax), %edx
 	/* Get the stack pointer.  */
@@ -56,6 +99,41 @@  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 $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz .Lnoadj
+#  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 .Lnoadj
+	/* 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
+	cmpl $255, %edx
+	jbe .Lonetime
+	movl $255, %ebx
+.Loopadj:
+	incsspd %ebx
+	subl $255, %edx
+	cmpl $255, %edx
+	ja .Loopadj
+.Lonetime:
+	incsspd %edx
+.Lnoadj:
+# endif
 	/* Save the return address now.  */
 	movl (JB_PC*4)(%ecx), %edx
 	LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx)
diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S
index a626cc6d22..5b09e5dbf8 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 !defined __CET__ || (__CET__ & 2) == 0
+# 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 $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz .Lskip_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
+.Lskip_ssp:
+# endif
+#endif
 	ret
 END (_setjmp)
 libc_hidden_def (_setjmp)
diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S
index 2da8b73c49..5f5db092e5 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 !defined __CET__ || (__CET__ & 2) == 0
+# 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 $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz .Lskip_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
+.Lskip_ssp:
+# endif
+#endif
 
 	/* Call __sigjmp_save.  */
 	pushl $1
diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S
index 6a08701717..31e26fd6d4 100644
--- a/sysdeps/i386/setjmp.S
+++ b/sysdeps/i386/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>
 
@@ -25,6 +26,11 @@ 
 #define JMPBUF	PARMS
 #define SIGMSK	JMPBUF+4
 
+/* Don't save shadow stack register if shadow stack isn't enabled.  */
+#if !defined __CET__ || (__CET__ & 2) == 0
+# 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 $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz .Lskip_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
+.Lskip_ssp:
+# endif
+#endif
 #if IS_IN (rtld)
 	/* In ld.so we never save the signal mask.  */
 	xorl %eax, %eax
diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
index 3452433112..7b4f4caa35 100644
--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
@@ -17,9 +17,14 @@ 
 
 #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 !defined __CET__ || (__CET__ & 2) == 0
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
 
 	.section .rodata.str1.1,"aMS",@progbits,1
 	.type	longjmp_msg,@object
@@ -46,6 +51,41 @@  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   $(1 << 1), %gs:FEATURE_1_OFFSET
+	jz      .Lnoadj
+# 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	.Lnoadj
+	/* 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
+	cmpl	$255, %edx
+	jbe	.Lonetime
+	movl	$255, %ebx
+.Loopadj:
+	incsspd	%ebx
+	subl	$255, %edx
+	cmpl	$255, %edx
+	ja	.Loopadj
+.Lonetime:
+	incsspd	%edx
+.Lnoadj:
+#endif
 	/* Save the return address now.  */
 	movl	(JB_PC*4)(%ecx), %edx
 	/* Get the stack pointer.  */
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index c55a43e58d..111ff9ff58 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -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
diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
index 8a9f2e1a3c..d42289221d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
@@ -20,7 +20,13 @@ 
 #include <asm-syntax.h>
 #include <stap-probe.h>
 
+/* Don't restore shadow stack register if shadow stack isn't enabled.  */
+#if !defined __CET__ || (__CET__ & 2) == 0
+# 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,41 @@  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	$(1 << 1), %fs:FEATURE_1_OFFSET
+	jz	.Lnoadj
+# 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	.Lnoadj
+	/* 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
+	cmpq	$255, %rax
+	jbe	.Lonetime
+	movl	$255, %ebx
+.Loopadj:
+	incsspq	%rbx
+	subq	$255, %rax
+	cmpq	$255, %rax
+	ja	.Loopadj
+.Lonetime:
+	incsspq	%rax
+.Lnoadj:
+#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)
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index d25d6f0ae4..65292f4032 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -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
index 0000000000..1aaaedc9ec
--- /dev/null
+++ b/sysdeps/x86/jmp_buf-ssp.sym
@@ -0,0 +1 @@ 
+-- FIXME: Define SHADOW_STACK_POINTER_OFFSET to support shadow stack.
diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S
index a487e0efd0..a9ebe3226e 100644
--- a/sysdeps/x86_64/__longjmp.S
+++ b/sysdeps/x86_64/__longjmp.S
@@ -17,9 +17,18 @@ 
 
 #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 !defined __CET__ || (__CET__ & 2) == 0 || 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,42 @@  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 $(1 << 1), %fs:FEATURE_1_OFFSET
+	jz .Lnoadj
+# 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 .Lnoadj
+	/* 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
+	cmpq $255, %rax
+	jbe .Lonetime
+	movl $255, %ebx
+.Loopadj:
+	incsspq %rbx
+	subq $255, %rax
+	cmpq $255, %rax
+	ja .Loopadj
+.Lonetime:
+	incsspq %rax
+.Lnoadj:
 #endif
 	LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
 	/* We add unwind information for the target here.  */
diff --git a/sysdeps/x86_64/setjmp.S b/sysdeps/x86_64/setjmp.S
index e0a648e3e4..bd9bb0ee6b 100644
--- a/sysdeps/x86_64/setjmp.S
+++ b/sysdeps/x86_64/setjmp.S
@@ -18,9 +18,15 @@ 
 
 #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 !defined __CET__ || (__CET__ & 2) == 0
+# 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 $(1 << 1), %fs:FEATURE_1_OFFSET
+	jz .Lskip_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
+.Lskip_ssp:
+# endif
+#endif
 #if IS_IN (rtld)
 	/* In ld.so we never save the signal mask.  */
 	xorl %eax, %eax