mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
i386: Remove CET support
CET is only support for x86_64, this patch reverts: -faaee1f07e
x86: Support shadow stack pointer in setjmp/longjmp. -be9ccd27c0
i386: Add _CET_ENDBR to indirect jump targets in add_n.S/sub_n.S -c02695d776
x86/CET: Update vfork to prevent child return -5d844e1b72
i386: Enable CET support in ucontext functions -124bcde683
x86: Add _CET_ENDBR to functions in crti.S -562837c002
x86: Add _CET_ENDBR to functions in dl-tlsdesc.S -f753fa7dea
x86: Support IBT and SHSTK in Intel CET [BZ #21598] -825b58f3fb
i386-mcount.S: Add _CET_ENDBR to _mcount and __fentry__ -7e119cd582
i386: Use _CET_NOTRACK in i686/memcmp.S -177824e232
i386: Use _CET_NOTRACK in memcmp-sse4.S -0a899af097
i386: Use _CET_NOTRACK in memcpy-ssse3-rep.S -7fb613361c
i386: Use _CET_NOTRACK in memcpy-ssse3.S -77a8ae0948
i386: Use _CET_NOTRACK in memset-sse2-rep.S -00e7b76a8f
i386: Use _CET_NOTRACK in memset-sse2.S -90d15dc577
i386: Use _CET_NOTRACK in strcat-sse2.S -f1574581c7
i386: Use _CET_NOTRACK in strcpy-sse2.S -4031d7484a
i386/sub_n.S: Add a missing _CET_ENDBR to indirect jump - target - Checked on i686-linux-gnu.
This commit is contained in:
@@ -18,14 +18,9 @@
|
||||
#include <sysdep.h>
|
||||
#include <pointer_guard.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
|
||||
@@ -52,38 +47,6 @@ 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. */
|
||||
|
@@ -17,7 +17,6 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <asm/prctl.h>
|
||||
|
||||
#include "ucontext_i.h"
|
||||
|
||||
@@ -42,61 +41,6 @@ ENTRY(__getcontext)
|
||||
movw %fs, %dx
|
||||
movl %edx, oFS(%eax)
|
||||
|
||||
#if SHSTK_ENABLED
|
||||
/* Check if shadow stack is enabled. */
|
||||
testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
|
||||
jz L(no_shstk)
|
||||
|
||||
/* Save EAX in EDX. */
|
||||
movl %eax, %edx
|
||||
|
||||
xorl %eax, %eax
|
||||
cmpl %gs:SSP_BASE_OFFSET, %eax
|
||||
jnz L(shadow_stack_bound_recorded)
|
||||
|
||||
/* Save EBX in the first scratch register slot. */
|
||||
movl %ebx, oSCRATCH1(%edx)
|
||||
|
||||
/* Get the base address and size of the default shadow stack
|
||||
which must be the current shadow stack since nothing has
|
||||
been recorded yet. */
|
||||
sub $24, %esp
|
||||
mov %esp, %ecx
|
||||
movl $ARCH_CET_STATUS, %ebx
|
||||
movl $__NR_arch_prctl, %eax
|
||||
ENTER_KERNEL
|
||||
testl %eax, %eax
|
||||
jz L(continue_no_err)
|
||||
|
||||
/* This should never happen. */
|
||||
hlt
|
||||
|
||||
L(continue_no_err):
|
||||
/* Restore EBX from the first scratch register slot. */
|
||||
movl oSCRATCH1(%edx), %ebx
|
||||
|
||||
/* Record the base of the current shadow stack. */
|
||||
movl 8(%esp), %eax
|
||||
movl %eax, %gs:SSP_BASE_OFFSET
|
||||
add $24, %esp
|
||||
|
||||
L(shadow_stack_bound_recorded):
|
||||
/* Load address of the context data structure. */
|
||||
movl 4(%esp), %eax
|
||||
|
||||
/* Get the current shadow stack pointer. */
|
||||
rdsspd %edx
|
||||
/* NB: Save the caller's shadow stack so that we can jump back
|
||||
to the caller directly. */
|
||||
addl $4, %edx
|
||||
movl %edx, oSSP(%eax)
|
||||
|
||||
/* Save the current shadow stack base in ucontext. */
|
||||
movl %gs:SSP_BASE_OFFSET, %edx
|
||||
movl %edx, (oSSP + 4)(%eax)
|
||||
|
||||
L(no_shstk):
|
||||
#endif
|
||||
/* We have separate floating-point register content memory on the
|
||||
stack. We use the __fpregs_mem block in the context. Set the
|
||||
links up correctly. */
|
||||
|
@@ -17,7 +17,6 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <asm/prctl.h>
|
||||
|
||||
#include "ucontext_i.h"
|
||||
|
||||
@@ -68,127 +67,6 @@ ENTRY(__makecontext)
|
||||
jnz 1b
|
||||
2:
|
||||
|
||||
#if SHSTK_ENABLED
|
||||
/* Check if Shadow Stack is enabled. */
|
||||
testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
|
||||
jz L(skip_ssp)
|
||||
|
||||
/* Reload the pointer to ucontext. */
|
||||
movl 4(%esp), %eax
|
||||
|
||||
/* Shadow stack is enabled. We need to allocate a new shadow
|
||||
stack. */
|
||||
subl oSS_SP(%eax), %edx
|
||||
shrl $STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT, %edx
|
||||
|
||||
/* Align shadow stack size to 8 bytes. */
|
||||
addl $7, %edx
|
||||
andl $-8, %edx
|
||||
|
||||
/* Store shadow stack size in __ssp[2]. */
|
||||
movl %edx, (oSSP + 8)(%eax)
|
||||
|
||||
/* Save ESI in the second scratch register slot. */
|
||||
movl %esi, oSCRATCH2(%eax)
|
||||
/* Save EDI in the third scratch register slot. */
|
||||
movl %edi, oSCRATCH3(%eax)
|
||||
|
||||
/* Save the pointer to ucontext. */
|
||||
movl %eax, %edi
|
||||
|
||||
/* Get the original shadow stack pointer. */
|
||||
rdsspd %esi
|
||||
|
||||
/* Align the saved original shadow stack pointer to the next
|
||||
8 byte aligned boundary. */
|
||||
andl $-8, %esi
|
||||
|
||||
/* Load the top of the new stack into EDX. */
|
||||
movl oESP(%eax), %edx
|
||||
|
||||
/* We need to terminate the FDE here because the unwinder looks
|
||||
at ra-1 for unwind information. */
|
||||
cfi_endproc
|
||||
|
||||
/* Swap the original stack pointer with the top of the new
|
||||
stack. */
|
||||
xchgl %esp, %edx
|
||||
|
||||
/* Add 4 bytes since CALL will push the 4-byte return address
|
||||
onto stack. */
|
||||
addl $4, %esp
|
||||
|
||||
/* Allocate the new shadow stack. Save EBX in the first scratch
|
||||
register slot. */
|
||||
movl %ebx, oSCRATCH1(%eax)
|
||||
|
||||
/* CET syscall takes 64-bit sizes. */
|
||||
subl $16, %esp
|
||||
movl (oSSP + 8)(%eax), %ecx
|
||||
movl %ecx, (%esp)
|
||||
movl $0, 4(%esp)
|
||||
movl %ecx, 8(%esp)
|
||||
movl $0, 12(%esp)
|
||||
movl %esp, %ecx
|
||||
|
||||
movl $ARCH_CET_ALLOC_SHSTK, %ebx
|
||||
movl $__NR_arch_prctl, %eax
|
||||
ENTER_KERNEL
|
||||
testl %eax, %eax
|
||||
jne L(hlt) /* This should never happen. */
|
||||
|
||||
/* Copy the base address of the new shadow stack to __ssp[1]. */
|
||||
movl (%esp), %eax
|
||||
movl %eax, (oSSP + 4)(%edi)
|
||||
|
||||
addl $16, %esp
|
||||
|
||||
/* Restore EBX from the first scratch register slot. */
|
||||
movl oSCRATCH1(%edi), %ebx
|
||||
|
||||
/* Get the size of the new shadow stack. */
|
||||
movl (oSSP + 8)(%edi), %ecx
|
||||
|
||||
/* Use the restore stoken to restore the new shadow stack. */
|
||||
rstorssp -8(%eax, %ecx)
|
||||
|
||||
/* Save the restore token at the next 8 byte aligned boundary
|
||||
on the original shadow stack. */
|
||||
saveprevssp
|
||||
|
||||
/* Push the address of "jmp exitcode" onto the new stack as
|
||||
well as the new shadow stack. */
|
||||
call 1f
|
||||
jmp L(exitcode)
|
||||
1:
|
||||
|
||||
/* Get the new shadow stack pointer. */
|
||||
rdsspd %eax
|
||||
|
||||
/* Use the restore stoken to restore the original shadow stack. */
|
||||
rstorssp -8(%esi)
|
||||
|
||||
/* Save the restore token on the new shadow stack. */
|
||||
saveprevssp
|
||||
|
||||
/* Store the new shadow stack pointer in __ssp[0]. */
|
||||
movl %eax, oSSP(%edi)
|
||||
|
||||
/* Restore the original stack. */
|
||||
mov %edx, %esp
|
||||
|
||||
cfi_startproc
|
||||
|
||||
/* Restore ESI from the second scratch register slot. */
|
||||
movl oSCRATCH2(%edi), %esi
|
||||
/* Restore EDI from the third scratch register slot. */
|
||||
movl oSCRATCH3(%edi), %edi
|
||||
|
||||
ret
|
||||
|
||||
L(skip_ssp):
|
||||
#endif
|
||||
|
||||
/* If the function we call returns we must continue with the
|
||||
context which is given in the uc_link element. To do this
|
||||
set the return address for the function the user provides
|
||||
@@ -244,7 +122,6 @@ L(call_exit):
|
||||
call HIDDEN_JUMPTARGET(exit)
|
||||
/* The 'exit' call should never return. In case it does cause
|
||||
the process to terminate. */
|
||||
L(hlt):
|
||||
hlt
|
||||
cfi_startproc
|
||||
END(__makecontext)
|
||||
|
@@ -17,7 +17,6 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <asm/prctl.h>
|
||||
|
||||
#include "ucontext_i.h"
|
||||
|
||||
@@ -56,6 +55,9 @@ ENTRY(__setcontext)
|
||||
movl oFS(%eax), %ecx
|
||||
movw %cx, %fs
|
||||
|
||||
/* Fetch the address to return to. */
|
||||
movl oEIP(%eax), %ecx
|
||||
|
||||
/* Load the new stack pointer. */
|
||||
cfi_def_cfa (eax, 0)
|
||||
cfi_offset (edi, oEDI)
|
||||
@@ -64,103 +66,6 @@ ENTRY(__setcontext)
|
||||
cfi_offset (ebx, oEBX)
|
||||
movl oESP(%eax), %esp
|
||||
|
||||
#if SHSTK_ENABLED
|
||||
/* Check if Shadow Stack is enabled. */
|
||||
testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
|
||||
jz L(no_shstk)
|
||||
|
||||
/* If the base of the target shadow stack is the same as the
|
||||
base of the current shadow stack, we unwind the shadow
|
||||
stack. Otherwise it is a stack switch and we look for a
|
||||
restore token. */
|
||||
movl oSSP(%eax), %esi
|
||||
movl %esi, %edi
|
||||
|
||||
/* Get the base of the target shadow stack. */
|
||||
movl (oSSP + 4)(%eax), %ecx
|
||||
cmpl %gs:SSP_BASE_OFFSET, %ecx
|
||||
je L(unwind_shadow_stack)
|
||||
|
||||
/* Align the saved original shadow stack pointer to the next
|
||||
8 byte aligned boundary. */
|
||||
andl $-8, %esi
|
||||
|
||||
L(find_restore_token_loop):
|
||||
/* Look for a restore token. */
|
||||
movl -8(%esi), %ebx
|
||||
andl $-8, %ebx
|
||||
cmpl %esi, %ebx
|
||||
je L(restore_shadow_stack)
|
||||
|
||||
/* Try the next slot. */
|
||||
subl $8, %esi
|
||||
jmp L(find_restore_token_loop)
|
||||
|
||||
L(restore_shadow_stack):
|
||||
/* Pop return address from the shadow stack since setcontext
|
||||
will not return. */
|
||||
movl $1, %ebx
|
||||
incsspd %ebx
|
||||
|
||||
/* Use the restore stoken to restore the target shadow stack. */
|
||||
rstorssp -8(%esi)
|
||||
|
||||
/* Save the restore token on the old shadow stack. NB: This
|
||||
restore token may be checked by setcontext or swapcontext
|
||||
later. */
|
||||
saveprevssp
|
||||
|
||||
/* Record the new shadow stack base that was switched to. */
|
||||
movl (oSSP + 4)(%eax), %ebx
|
||||
movl %ebx, %gs:SSP_BASE_OFFSET
|
||||
|
||||
L(unwind_shadow_stack):
|
||||
rdsspd %ebx
|
||||
subl %edi, %ebx
|
||||
je L(skip_unwind_shadow_stack)
|
||||
negl %ebx
|
||||
shrl $2, %ebx
|
||||
movl $255, %esi
|
||||
L(loop):
|
||||
cmpl %esi, %ebx
|
||||
cmovb %ebx, %esi
|
||||
incsspd %esi
|
||||
subl %esi, %ebx
|
||||
ja L(loop)
|
||||
|
||||
L(skip_unwind_shadow_stack):
|
||||
|
||||
/* Load the values of all the preserved registers (except ESP). */
|
||||
movl oEDI(%eax), %edi
|
||||
movl oESI(%eax), %esi
|
||||
movl oEBP(%eax), %ebp
|
||||
movl oEBX(%eax), %ebx
|
||||
|
||||
/* Get the return address set with getcontext. */
|
||||
movl oEIP(%eax), %ecx
|
||||
|
||||
/* Check if return address is valid for the case when setcontext
|
||||
is invoked from L(exitcode) with linked context. */
|
||||
rdsspd %eax
|
||||
cmpl (%eax), %ecx
|
||||
/* Clear EAX to indicate success. NB: Don't use xorl to keep
|
||||
EFLAGS for jne. */
|
||||
movl $0, %eax
|
||||
jne L(jmp)
|
||||
/* Return to the new context if return address valid. */
|
||||
pushl %ecx
|
||||
ret
|
||||
|
||||
L(jmp):
|
||||
/* Jump to the new context directly. */
|
||||
jmp *%ecx
|
||||
|
||||
L(no_shstk):
|
||||
#endif
|
||||
|
||||
/* Fetch the address to return to. */
|
||||
movl oEIP(%eax), %ecx
|
||||
|
||||
/* Push the return address on the new stack so we can return there. */
|
||||
pushl %ecx
|
||||
|
||||
|
@@ -17,7 +17,6 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <asm/prctl.h>
|
||||
|
||||
#include "ucontext_i.h"
|
||||
|
||||
@@ -76,144 +75,6 @@ ENTRY(__swapcontext)
|
||||
movl oFS(%eax), %edx
|
||||
movw %dx, %fs
|
||||
|
||||
#if SHSTK_ENABLED
|
||||
/* Check if Shadow Stack is enabled. */
|
||||
testl $X86_FEATURE_1_SHSTK, %gs:FEATURE_1_OFFSET
|
||||
jz L(no_shstk)
|
||||
|
||||
xorl %eax, %eax
|
||||
cmpl %gs:SSP_BASE_OFFSET, %eax
|
||||
jnz L(shadow_stack_bound_recorded)
|
||||
|
||||
/* Get the base address and size of the default shadow stack
|
||||
which must be the current shadow stack since nothing has
|
||||
been recorded yet. */
|
||||
sub $24, %esp
|
||||
mov %esp, %ecx
|
||||
movl $ARCH_CET_STATUS, %ebx
|
||||
movl $__NR_arch_prctl, %eax
|
||||
ENTER_KERNEL
|
||||
testl %eax, %eax
|
||||
jz L(continue_no_err)
|
||||
|
||||
/* This should never happen. */
|
||||
hlt
|
||||
|
||||
L(continue_no_err):
|
||||
/* Record the base of the current shadow stack. */
|
||||
movl 8(%esp), %eax
|
||||
movl %eax, %gs:SSP_BASE_OFFSET
|
||||
add $24, %esp
|
||||
|
||||
L(shadow_stack_bound_recorded):
|
||||
/* Load address of the context data structure we save in. */
|
||||
movl 4(%esp), %eax
|
||||
|
||||
/* Load address of the context data structure we swap in */
|
||||
movl 8(%esp), %edx
|
||||
|
||||
/* If we unwind the stack, we can't undo stack unwinding. Just
|
||||
save the target shadow stack pointer as the current shadow
|
||||
stack pointer. */
|
||||
movl oSSP(%edx), %ecx
|
||||
movl %ecx, oSSP(%eax)
|
||||
|
||||
/* Save the current shadow stack base in ucontext. */
|
||||
movl %gs:SSP_BASE_OFFSET, %ecx
|
||||
movl %ecx, (oSSP + 4)(%eax)
|
||||
|
||||
/* If the base of the target shadow stack is the same as the
|
||||
base of the current shadow stack, we unwind the shadow
|
||||
stack. Otherwise it is a stack switch and we look for a
|
||||
restore token. */
|
||||
movl oSSP(%edx), %esi
|
||||
movl %esi, %edi
|
||||
|
||||
/* Get the base of the target shadow stack. */
|
||||
movl (oSSP + 4)(%edx), %ecx
|
||||
cmpl %gs:SSP_BASE_OFFSET, %ecx
|
||||
je L(unwind_shadow_stack)
|
||||
|
||||
/* Align the saved original shadow stack pointer to the next
|
||||
8 byte aligned boundary. */
|
||||
andl $-8, %esi
|
||||
|
||||
L(find_restore_token_loop):
|
||||
/* Look for a restore token. */
|
||||
movl -8(%esi), %ebx
|
||||
andl $-8, %ebx
|
||||
cmpl %esi, %ebx
|
||||
je L(restore_shadow_stack)
|
||||
|
||||
/* Try the next slot. */
|
||||
subl $8, %esi
|
||||
jmp L(find_restore_token_loop)
|
||||
|
||||
L(restore_shadow_stack):
|
||||
/* The target shadow stack will be restored. Save the current
|
||||
shadow stack pointer. */
|
||||
rdsspd %ecx
|
||||
movl %ecx, oSSP(%eax)
|
||||
|
||||
/* Use the restore stoken to restore the target shadow stack. */
|
||||
rstorssp -8(%esi)
|
||||
|
||||
/* Save the restore token on the old shadow stack. NB: This
|
||||
restore token may be checked by setcontext or swapcontext
|
||||
later. */
|
||||
saveprevssp
|
||||
|
||||
/* Record the new shadow stack base that was switched to. */
|
||||
movl (oSSP + 4)(%edx), %ebx
|
||||
movl %ebx, %gs:SSP_BASE_OFFSET
|
||||
|
||||
L(unwind_shadow_stack):
|
||||
rdsspd %ebx
|
||||
subl %edi, %ebx
|
||||
je L(skip_unwind_shadow_stack)
|
||||
negl %ebx
|
||||
shrl $2, %ebx
|
||||
movl $255, %esi
|
||||
L(loop):
|
||||
cmpl %esi, %ebx
|
||||
cmovb %ebx, %esi
|
||||
incsspd %esi
|
||||
subl %esi, %ebx
|
||||
ja L(loop)
|
||||
|
||||
L(skip_unwind_shadow_stack):
|
||||
|
||||
/* Load the new stack pointer. */
|
||||
movl oESP(%edx), %esp
|
||||
|
||||
/* Load the values of all the preserved registers (except ESP). */
|
||||
movl oEDI(%edx), %edi
|
||||
movl oESI(%edx), %esi
|
||||
movl oEBP(%edx), %ebp
|
||||
movl oEBX(%edx), %ebx
|
||||
|
||||
/* Get the return address set with getcontext. */
|
||||
movl oEIP(%edx), %ecx
|
||||
|
||||
/* Check if return address is valid for the case when setcontext
|
||||
is invoked from L(exitcode) with linked context. */
|
||||
rdsspd %eax
|
||||
cmpl (%eax), %ecx
|
||||
/* Clear EAX to indicate success. NB: Don't use xorl to keep
|
||||
EFLAGS for jne. */
|
||||
movl $0, %eax
|
||||
jne L(jmp)
|
||||
/* Return to the new context if return address valid. */
|
||||
pushl %ecx
|
||||
ret
|
||||
|
||||
L(jmp):
|
||||
/* Jump to the new context directly. */
|
||||
jmp *%ecx
|
||||
|
||||
L(no_shstk):
|
||||
#endif
|
||||
|
||||
/* Fetch the address to return to. */
|
||||
movl oEIP(%eax), %ecx
|
||||
|
||||
|
@@ -446,9 +446,4 @@ struct libc_do_syscall_args
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Each shadow stack slot takes 4 bytes. Assuming that each stack
|
||||
frame takes 128 bytes, this is used to compute shadow stack size
|
||||
from stack size. */
|
||||
#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5
|
||||
|
||||
#endif /* linux/i386/sysdep.h */
|
||||
|
@@ -22,10 +22,6 @@ oEBP mreg (EBP)
|
||||
oESP mreg (ESP)
|
||||
oEBX mreg (EBX)
|
||||
oEIP mreg (EIP)
|
||||
oSCRATCH1 mreg (EAX)
|
||||
oSCRATCH2 mreg (ECX)
|
||||
oSCRATCH3 mreg (EDX)
|
||||
oFPREGS mcontext (fpregs)
|
||||
oSIGMASK ucontext (uc_sigmask)
|
||||
oFPREGSMEM ucontext (__fpregs_mem)
|
||||
oSSP ucontext (__ssp)
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <bits/errno.h>
|
||||
#include <tcb-offsets.h>
|
||||
|
||||
|
||||
/* Clone the calling process, but without copying the whole address space.
|
||||
The calling process is suspended until the new process exits or is
|
||||
replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
|
||||
@@ -46,29 +47,6 @@ ENTRY (__vfork)
|
||||
/* Branch forward if it failed. */
|
||||
jae SYSCALL_ERROR_LABEL
|
||||
|
||||
#if SHSTK_ENABLED
|
||||
/* Check if shadow stack is in use. */
|
||||
xorl %edx, %edx
|
||||
rdsspd %edx
|
||||
testl %edx, %edx
|
||||
/* Normal return if shadow stack isn't in use. */
|
||||
je L(no_shstk)
|
||||
|
||||
testl %eax, %eax
|
||||
/* In parent, normal return. */
|
||||
jnz L(no_shstk)
|
||||
|
||||
/* NB: In child, jump back to caller via indirect branch without
|
||||
popping shadow stack which is shared with parent. Keep shadow
|
||||
stack mismatched so that child returns in the vfork-calling
|
||||
function will trigger SIGSEGV. */
|
||||
popl %ecx
|
||||
cfi_adjust_cfa_offset (-4)
|
||||
jmp *%ecx
|
||||
|
||||
L(no_shstk):
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
PSEUDO_END (__vfork)
|
||||
|
Reference in New Issue
Block a user