mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-04 08:02:32 +03:00
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.
This commit is contained in:
37
ChangeLog
37
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>
|
2018-07-14 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
[BZ #22563]
|
[BZ #22563]
|
||||||
|
@ -18,14 +18,55 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.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
|
.text
|
||||||
ENTRY (__longjmp)
|
ENTRY (__longjmp)
|
||||||
#ifdef PTR_DEMANGLE
|
#ifdef PTR_DEMANGLE
|
||||||
movl 4(%esp), %eax /* User's jmp_buf in %eax. */
|
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. */
|
/* Save the return address now. */
|
||||||
movl (JB_PC*4)(%eax), %edx
|
movl (JB_PC*4)(%eax), %edx
|
||||||
/* Get the stack pointer. */
|
/* Get the stack pointer. */
|
||||||
@ -56,6 +97,38 @@ ENTRY (__longjmp)
|
|||||||
#else
|
#else
|
||||||
movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */
|
movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */
|
||||||
movl 8(%esp), %eax /* Second argument is return value. */
|
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. */
|
/* Save the return address now. */
|
||||||
movl (JB_PC*4)(%ecx), %edx
|
movl (JB_PC*4)(%ecx), %edx
|
||||||
LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx)
|
LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx)
|
||||||
|
@ -22,12 +22,18 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <stap-probe.h>
|
#include <stap-probe.h>
|
||||||
|
|
||||||
#define PARMS 4 /* no space for saved regs */
|
#define PARMS 4 /* no space for saved regs */
|
||||||
#define JMPBUF PARMS
|
#define JMPBUF PARMS
|
||||||
#define SIGMSK JMPBUF+4
|
#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)
|
ENTRY (_setjmp)
|
||||||
|
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
@ -51,6 +57,21 @@ ENTRY (_setjmp)
|
|||||||
movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
|
movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
|
||||||
|
|
||||||
movl %eax, JB_SIZE(%edx) /* No signal mask set. */
|
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
|
ret
|
||||||
END (_setjmp)
|
END (_setjmp)
|
||||||
libc_hidden_def (_setjmp)
|
libc_hidden_def (_setjmp)
|
||||||
|
@ -22,12 +22,18 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <stap-probe.h>
|
#include <stap-probe.h>
|
||||||
|
|
||||||
#define PARMS 4 /* no space for saved regs */
|
#define PARMS 4 /* no space for saved regs */
|
||||||
#define JMPBUF PARMS
|
#define JMPBUF PARMS
|
||||||
#define SIGMSK JMPBUF+4
|
#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)
|
ENTRY (setjmp)
|
||||||
/* Note that we have to use a non-exported symbol in the next
|
/* 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
|
jump since otherwise gas will emit it as a jump through the
|
||||||
@ -51,6 +57,21 @@ ENTRY (setjmp)
|
|||||||
#endif
|
#endif
|
||||||
movl %ecx, (JB_PC*4)(%eax)
|
movl %ecx, (JB_PC*4)(%eax)
|
||||||
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
|
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. */
|
/* Call __sigjmp_save. */
|
||||||
pushl $1
|
pushl $1
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.h>
|
#include <stap-probe.h>
|
||||||
|
|
||||||
@ -25,6 +26,11 @@
|
|||||||
#define JMPBUF PARMS
|
#define JMPBUF PARMS
|
||||||
#define SIGMSK JMPBUF+4
|
#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)
|
ENTRY (__sigsetjmp)
|
||||||
|
|
||||||
movl JMPBUF(%esp), %eax
|
movl JMPBUF(%esp), %eax
|
||||||
@ -46,6 +52,21 @@ ENTRY (__sigsetjmp)
|
|||||||
movl %ecx, (JB_PC*4)(%eax)
|
movl %ecx, (JB_PC*4)(%eax)
|
||||||
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
|
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)
|
#if IS_IN (rtld)
|
||||||
/* In ld.so we never save the signal mask. */
|
/* In ld.so we never save the signal mask. */
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
|
@ -17,9 +17,14 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.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
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
.type longjmp_msg,@object
|
.type longjmp_msg,@object
|
||||||
@ -46,6 +51,38 @@ longjmp_msg:
|
|||||||
ENTRY (____longjmp_chk)
|
ENTRY (____longjmp_chk)
|
||||||
movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */
|
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. */
|
/* Save the return address now. */
|
||||||
movl (JB_PC*4)(%ecx), %edx
|
movl (JB_PC*4)(%ecx), %edx
|
||||||
/* Get the stack pointer. */
|
/* Get the stack pointer. */
|
||||||
|
@ -21,6 +21,5 @@ sysdep_routines += dl-vdso
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),setjmp)
|
ifeq ($(subdir),setjmp)
|
||||||
gen-as-const-headers += jmp_buf-ssp.sym
|
|
||||||
tests += tst-saved_mask-1
|
tests += tst-saved_mask-1
|
||||||
endif
|
endif
|
||||||
|
@ -20,7 +20,13 @@
|
|||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.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 <sigaltstack-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
|
|
||||||
.section .rodata.str1.1,"aMS",@progbits,1
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
.type longjmp_msg,@object
|
.type longjmp_msg,@object
|
||||||
@ -105,6 +111,38 @@ ENTRY(____longjmp_chk)
|
|||||||
cfi_restore (%rsi)
|
cfi_restore (%rsi)
|
||||||
|
|
||||||
.Lok:
|
.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)
|
LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
|
||||||
/* We add unwind information for the target here. */
|
/* We add unwind information for the target here. */
|
||||||
cfi_def_cfa(%rdi, 0)
|
cfi_def_cfa(%rdi, 0)
|
||||||
|
@ -10,5 +10,6 @@ tests-static += tst-get-cpu-features-static
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),setjmp)
|
ifeq ($(subdir),setjmp)
|
||||||
|
gen-as-const-headers += jmp_buf-ssp.sym
|
||||||
sysdep_routines += __longjmp_cancel
|
sysdep_routines += __longjmp_cancel
|
||||||
endif
|
endif
|
||||||
|
1
sysdeps/x86/jmp_buf-ssp.sym
Normal file
1
sysdeps/x86/jmp_buf-ssp.sym
Normal file
@ -0,0 +1 @@
|
|||||||
|
-- FIXME: Define SHADOW_STACK_POINTER_OFFSET to support shadow stack.
|
@ -17,9 +17,18 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.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
|
/* Jump to the position specified by ENV, causing the
|
||||||
setjmp call there to return VAL, or 1 if VAL is 0.
|
setjmp call there to return VAL, or 1 if VAL is 0.
|
||||||
void __longjmp (__jmp_buf env, int val). */
|
void __longjmp (__jmp_buf env, int val). */
|
||||||
@ -41,6 +50,41 @@ ENTRY(__longjmp)
|
|||||||
shlq $32, %rax
|
shlq $32, %rax
|
||||||
orq %rax, %r9
|
orq %rax, %r9
|
||||||
# endif
|
# 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
|
#endif
|
||||||
LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
|
LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
|
||||||
/* We add unwind information for the target here. */
|
/* We add unwind information for the target here. */
|
||||||
|
@ -18,9 +18,15 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <jmpbuf-offsets.h>
|
#include <jmpbuf-offsets.h>
|
||||||
|
#include <jmp_buf-ssp.h>
|
||||||
#include <asm-syntax.h>
|
#include <asm-syntax.h>
|
||||||
#include <stap-probe.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)
|
ENTRY (__sigsetjmp)
|
||||||
/* Save registers. */
|
/* Save registers. */
|
||||||
movq %rbx, (JB_RBX*8)(%rdi)
|
movq %rbx, (JB_RBX*8)(%rdi)
|
||||||
@ -54,6 +60,21 @@ ENTRY (__sigsetjmp)
|
|||||||
#endif
|
#endif
|
||||||
movq %rax, (JB_PC*8)(%rdi)
|
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)
|
#if IS_IN (rtld)
|
||||||
/* In ld.so we never save the signal mask. */
|
/* In ld.so we never save the signal mask. */
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
|
Reference in New Issue
Block a user