diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index e28513b3..5bb222ab 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -797,7 +797,7 @@ alias asm_sources asm/jump_x86_64_sysv_elf_gas.S asm/ontop_x86_64_sysv_elf_gas.S : x32 - 64 + 32 x86 elf clang @@ -808,7 +808,7 @@ alias asm_sources asm/jump_x86_64_sysv_elf_gas.S asm/ontop_x86_64_sysv_elf_gas.S : x32 - 64 + 32 x86 elf gcc @@ -819,7 +819,7 @@ alias asm_sources asm/jump_x86_64_sysv_elf_gas.S asm/ontop_x86_64_sysv_elf_gas.S : x32 - 64 + 32 x86 elf intel diff --git a/doc/stack.qbk b/doc/stack.qbk index 25dd4e20..84848329 100644 --- a/doc/stack.qbk +++ b/doc/stack.qbk @@ -364,4 +364,20 @@ when linking against Boost binaries. [endsect] +[section:stack_protect Support for stack protection] + +Compiler switch `-fstack-protector` changes the default context switching logic. +Users must define `BOOST_CONTEXT_TLS_STACK_PROTECTOR` before including any +Boost.Context headers if stack protection is enabled. + +[endsect] + +[section:shadow_stack Support for shadow stack protection] + +Shadow stack is part of Intel's Control-Flow Enforcement Technology. Users must +define `BOOST_CONTEXT_SHADOW_STACK` before including any Boost.Context headers +if shadow stack protection is enabled. + +[endsect] + [endsect] diff --git a/include/boost/context/continuation_fcontext.hpp b/include/boost/context/continuation_fcontext.hpp index 881e6f26..32c8d156 100644 --- a/include/boost/context/continuation_fcontext.hpp +++ b/include/boost/context/continuation_fcontext.hpp @@ -44,6 +44,17 @@ # include BOOST_ABI_PREFIX #endif +#if defined __CET__ +# include +# include +# define SHSTK_ENABLED (__CET__ & 0x2) +# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL) +# define __NR_map_shadow_stack 451 +#ifndef SHADOW_STACK_SET_TOKEN +# define SHADOW_STACK_SET_TOKEN 0x1 +#endif +#endif + #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4702) @@ -62,6 +73,12 @@ transfer_t context_unwind( transfer_t t) { template< typename Rec > transfer_t context_exit( transfer_t t) noexcept { Rec * rec = static_cast< Rec * >( t.data); +#if BOOST_CONTEXT_SHADOW_STACK + // destory shadow stack + std::size_t ss_size = *((unsigned long*)(reinterpret_cast< uintptr_t >( rec)- 16)); + long unsigned int ss_base = *((unsigned long*)(reinterpret_cast< uintptr_t >( rec)- 8)); + munmap((void *)ss_base, ss_size); +#endif // destroy context stack rec->deallocate(); return { nullptr, nullptr }; @@ -168,6 +185,25 @@ fcontext_t create_context1( StackAlloc && salloc, Fn && fn) { reinterpret_cast< uintptr_t >( sctx.sp) - static_cast< uintptr_t >( sctx.size) ); // create fast-context const std::size_t size = reinterpret_cast< uintptr_t >( stack_top) - reinterpret_cast< uintptr_t >( stack_bottom); + +#if BOOST_CONTEXT_SHADOW_STACK + std::size_t ss_size = size >> 5; + // align shadow stack to 8 bytes. + ss_size = (ss_size + 7) & ~7; + // Todo: shadow stack occupies at least 4KB + ss_size = (ss_size > 4096) ? size : 4096; + // create shadow stack + void *ss_base = (void *)syscall(__NR_map_shadow_stack, 0, ss_size, SHADOW_STACK_SET_TOKEN); + BOOST_ASSERT(ss_base != -1); + unsigned long ss_sp = (unsigned long)ss_base + ss_size; + /* pass the shadow stack pointer to make_fcontext + i.e., link the new shadow stack with the new fcontext + TODO should be a better way? */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( stack_top)- 8)) = ss_sp; + /* Todo: place shadow stack info in 64byte gap */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base; + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size; +#endif const fcontext_t fctx = make_fcontext( stack_top, size, & context_entry< Record >); BOOST_ASSERT( nullptr != fctx); // transfer control structure to context-stack @@ -190,6 +226,25 @@ fcontext_t create_context2( preallocated palloc, StackAlloc && salloc, Fn && fn) reinterpret_cast< uintptr_t >( palloc.sctx.sp) - static_cast< uintptr_t >( palloc.sctx.size) ); // create fast-context const std::size_t size = reinterpret_cast< uintptr_t >( stack_top) - reinterpret_cast< uintptr_t >( stack_bottom); + +#if BOOST_CONTEXT_SHADOW_STACK + std::size_t ss_size = size >> 5; + // align shadow stack to 8 bytes. + ss_size = (ss_size + 7) & ~7; + // Todo: shadow stack occupies at least 4KB + ss_size = (ss_size > 4096) ? size : 4096; + // create shadow stack + void *ss_base = (void *)syscall(__NR_map_shadow_stack, 0, ss_size, SHADOW_STACK_SET_TOKEN); + BOOST_ASSERT(ss_base != -1); + unsigned long ss_sp = (unsigned long)ss_base + ss_size; + /* pass the shadow stack pointer to make_fcontext + i.e., link the new shadow stack with the new fcontext + TODO should be a better way? */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( stack_top)- 8)) = ss_sp; + /* Todo: place shadow stack info in 64byte gap */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base; + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size; +#endif const fcontext_t fctx = make_fcontext( stack_top, size, & context_entry< Record >); BOOST_ASSERT( nullptr != fctx); // transfer control structure to context-stack diff --git a/include/boost/context/fiber_fcontext.hpp b/include/boost/context/fiber_fcontext.hpp index 88d77930..4f6e5d75 100644 --- a/include/boost/context/fiber_fcontext.hpp +++ b/include/boost/context/fiber_fcontext.hpp @@ -44,6 +44,17 @@ # include BOOST_ABI_PREFIX #endif +#if defined __CET__ +# include +# include +# define SHSTK_ENABLED (__CET__ & 0x2) +# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL) +# define __NR_map_shadow_stack 451 +#ifndef SHADOW_STACK_SET_TOKEN +# define SHADOW_STACK_SET_TOKEN 0x1 +#endif +#endif + #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4702) @@ -62,6 +73,12 @@ transfer_t fiber_unwind( transfer_t t) { template< typename Rec > transfer_t fiber_exit( transfer_t t) noexcept { Rec * rec = static_cast< Rec * >( t.data); +#if BOOST_CONTEXT_SHADOW_STACK + // destory shadow stack + std::size_t ss_size = *((unsigned long*)(reinterpret_cast< uintptr_t >( rec)- 16)); + long unsigned int ss_base = *((unsigned long*)(reinterpret_cast< uintptr_t >( rec)- 8)); + munmap((void *)ss_base, ss_size); +#endif // destroy context stack rec->deallocate(); return { nullptr, nullptr }; @@ -165,6 +182,25 @@ fcontext_t create_fiber1( StackAlloc && salloc, Fn && fn) { reinterpret_cast< uintptr_t >( sctx.sp) - static_cast< uintptr_t >( sctx.size) ); // create fast-context const std::size_t size = reinterpret_cast< uintptr_t >( stack_top) - reinterpret_cast< uintptr_t >( stack_bottom); + +#if BOOST_CONTEXT_SHADOW_STACK + std::size_t ss_size = size >> 5; + // align shadow stack to 8 bytes. + ss_size = (ss_size + 7) & ~7; + // Todo: shadow stack occupies at least 4KB + ss_size = (ss_size > 4096) ? size : 4096; + // create shadow stack + void *ss_base = (void *)syscall(__NR_map_shadow_stack, 0, ss_size, SHADOW_STACK_SET_TOKEN); + BOOST_ASSERT(ss_base != -1); + unsigned long ss_sp = (unsigned long)ss_base + ss_size; + /* pass the shadow stack pointer to make_fcontext + i.e., link the new shadow stack with the new fcontext + TODO should be a better way? */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( stack_top)- 8)) = ss_sp; + /* Todo: place shadow stack info in 64byte gap */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base; + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size; +#endif const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_entry< Record >); BOOST_ASSERT( nullptr != fctx); // transfer control structure to context-stack @@ -187,6 +223,25 @@ fcontext_t create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) { reinterpret_cast< uintptr_t >( palloc.sctx.sp) - static_cast< uintptr_t >( palloc.sctx.size) ); // create fast-context const std::size_t size = reinterpret_cast< uintptr_t >( stack_top) - reinterpret_cast< uintptr_t >( stack_bottom); + +#if BOOST_CONTEXT_SHADOW_STACK + std::size_t ss_size = size >> 5; + // align shadow stack to 8 bytes. + ss_size = (ss_size + 7) & ~7; + // Todo: shadow stack occupies at least 4KB + ss_size = (ss_size > 4096) ? size : 4096; + // create shadow stack + void *ss_base = (void *)syscall(__NR_map_shadow_stack, 0, ss_size, SHADOW_STACK_SET_TOKEN); + BOOST_ASSERT(ss_base != -1); + unsigned long ss_sp = (unsigned long)ss_base + ss_size; + /* pass the shadow stack pointer to make_fcontext + i.e., link the new shadow stack with the new fcontext + TODO should be a better way? */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( stack_top)- 8)) = ss_sp; + /* Todo: place shadow stack info in 64byte gap */ + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base; + *((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size; +#endif const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_entry< Record >); BOOST_ASSERT( nullptr != fctx); // transfer control structure to context-stack @@ -204,14 +259,6 @@ class fiber { friend detail::transfer_t detail::fiber_ontop( detail::transfer_t); - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, StackAlloc &&, Fn &&); - - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, preallocated, StackAlloc &&, Fn &&); - detail::fcontext_t fctx_{ nullptr }; fiber( detail::fcontext_t fctx) noexcept : diff --git a/include/boost/context/fiber_ucontext.hpp b/include/boost/context/fiber_ucontext.hpp index 97537f01..696ce580 100644 --- a/include/boost/context/fiber_ucontext.hpp +++ b/include/boost/context/fiber_ucontext.hpp @@ -397,14 +397,6 @@ class BOOST_CONTEXT_DECL fiber { template< typename Ctx, typename StackAlloc, typename Fn > friend detail::fiber_activation_record * detail::create_fiber2( preallocated, StackAlloc &&, Fn &&); - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, StackAlloc &&, Fn &&); - - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, preallocated, StackAlloc &&, Fn &&); - detail::fiber_activation_record * ptr_{ nullptr }; fiber( detail::fiber_activation_record * ptr) noexcept : diff --git a/include/boost/context/fiber_winfib.hpp b/include/boost/context/fiber_winfib.hpp index 727b3742..cd496d1b 100644 --- a/include/boost/context/fiber_winfib.hpp +++ b/include/boost/context/fiber_winfib.hpp @@ -290,14 +290,6 @@ class BOOST_CONTEXT_DECL fiber { template< typename Ctx, typename StackAlloc, typename Fn > friend detail::fiber_activation_record * detail::create_fiber2( preallocated, StackAlloc &&, Fn &&); - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, StackAlloc &&, Fn &&); - - template< typename StackAlloc, typename Fn > - friend fiber - callcc( std::allocator_arg_t, preallocated, StackAlloc &&, Fn &&); - detail::fiber_activation_record * ptr_{ nullptr }; fiber( detail::fiber_activation_record * ptr) noexcept : diff --git a/src/asm/jump_i386_sysv_elf_gas.S b/src/asm/jump_i386_sysv_elf_gas.S index b96d4b5c..47be9e77 100644 --- a/src/asm/jump_i386_sysv_elf_gas.S +++ b/src/asm/jump_i386_sysv_elf_gas.S @@ -12,14 +12,14 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * | fc_mxcsr|fc_x87_cw| guard | EDI | ESI | EBX | EBP | EIP | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * - * | 0x20 | 0x24 | | * + * | 0x20 | 0x24 | 0x28 | | * * ---------------------------------------------------------------------------------- * - * | to | data | | * + * | hidden | to | data | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ @@ -30,50 +30,60 @@ .align 2 .type jump_fcontext,@function jump_fcontext: - leal -0x18(%esp), %esp /* prepare stack */ + leal -0x1c(%esp), %esp /* prepare stack */ #if !defined(BOOST_USE_TSX) stmxcsr (%esp) /* save MMX control- and status-word */ fnstcw 0x4(%esp) /* save x87 control-word */ #endif - movl %edi, 0x8(%esp) /* save EDI */ - movl %esi, 0xc(%esp) /* save ESI */ - movl %ebx, 0x10(%esp) /* save EBX */ - movl %ebp, 0x14(%esp) /* save EBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movl %gs:0x14, %ecx /* read stack guard from TLS record */ + movl %ecx, 0x8(%esp) /* save stack guard */ +#endif + + movl %edi, 0xc(%esp) /* save EDI */ + movl %esi, 0x10(%esp) /* save ESI */ + movl %ebx, 0x14(%esp) /* save EBX */ + movl %ebp, 0x18(%esp) /* save EBP */ /* store ESP (pointing to context-data) in ECX */ movl %esp, %ecx /* first arg of jump_fcontext() == fcontext to jump to */ - movl 0x20(%esp), %eax + movl 0x24(%esp), %eax /* second arg of jump_fcontext() == data to be transferred */ - movl 0x24(%esp), %edx + movl 0x28(%esp), %edx /* restore ESP (pointing to context-data) from EAX */ movl %eax, %esp /* address of returned transport_t */ - movl 0x1c(%esp), %eax + movl 0x20(%esp), %eax /* return parent fcontext_t */ movl %ecx, (%eax) /* return data */ movl %edx, 0x4(%eax) - movl 0x18(%esp), %ecx /* restore EIP */ + movl 0x1c(%esp), %ecx /* restore EIP */ #if !defined(BOOST_USE_TSX) ldmxcsr (%esp) /* restore MMX control- and status-word */ fldcw 0x4(%esp) /* restore x87 control-word */ #endif - movl 0x8(%esp), %edi /* restore EDI */ - movl 0xc(%esp), %esi /* restore ESI */ - movl 0x10(%esp), %ebx /* restore EBX */ - movl 0x14(%esp), %ebp /* restore EBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movl 0x8(%esp), %edx /* load stack guard */ + movl %edx, %gs:0x14 /* restore stack guard to TLS record */ +#endif + + movl 0xc(%esp), %edi /* restore EDI */ + movl 0x10(%esp), %esi /* restore ESI */ + movl 0x14(%esp), %ebx /* restore EBX */ + movl 0x18(%esp), %ebp /* restore EBP */ - leal 0x20(%esp), %esp /* prepare stack */ + leal 0x24(%esp), %esp /* prepare stack */ /* jump to context */ jmp *%ecx diff --git a/src/asm/jump_ppc32_sysv_macho_gas.S b/src/asm/jump_ppc32_sysv_macho_gas.S index c555237a..fef90c29 100644 --- a/src/asm/jump_ppc32_sysv_macho_gas.S +++ b/src/asm/jump_ppc32_sysv_macho_gas.S @@ -80,122 +80,122 @@ _jump_fcontext: ; reserve space on stack subi r1, r1, 244 - stfd f14, 0(r1) # save F14 - stfd f15, 8(r1) # save F15 - stfd f16, 16(r1) # save F16 - stfd f17, 24(r1) # save F17 - stfd f18, 32(r1) # save F18 - stfd f19, 40(r1) # save F19 - stfd f20, 48(r1) # save F20 - stfd f21, 56(r1) # save F21 - stfd f22, 64(r1) # save F22 - stfd f23, 72(r1) # save F23 - stfd f24, 80(r1) # save F24 - stfd f25, 88(r1) # save F25 - stfd f26, 96(r1) # save F26 - stfd f27, 104(r1) # save F27 - stfd f28, 112(r1) # save F28 - stfd f29, 120(r1) # save F29 - stfd f30, 128(r1) # save F30 - stfd f31, 136(r1) # save F31 - mffs f0 # load FPSCR - stfd f0, 144(r1) # save FPSCR + stfd f14, 0(r1) ; save F14 + stfd f15, 8(r1) ; save F15 + stfd f16, 16(r1) ; save F16 + stfd f17, 24(r1) ; save F17 + stfd f18, 32(r1) ; save F18 + stfd f19, 40(r1) ; save F19 + stfd f20, 48(r1) ; save F20 + stfd f21, 56(r1) ; save F21 + stfd f22, 64(r1) ; save F22 + stfd f23, 72(r1) ; save F23 + stfd f24, 80(r1) ; save F24 + stfd f25, 88(r1) ; save F25 + stfd f26, 96(r1) ; save F26 + stfd f27, 104(r1) ; save F27 + stfd f28, 112(r1) ; save F28 + stfd f29, 120(r1) ; save F29 + stfd f30, 128(r1) ; save F30 + stfd f31, 136(r1) ; save F31 + mffs f0 ; load FPSCR + stfd f0, 144(r1) ; save FPSCR - stw r13, 152(r1) # save R13 - stw r14, 156(r1) # save R14 - stw r15, 160(r1) # save R15 - stw r16, 164(r1) # save R16 - stw r17, 168(r1) # save R17 - stw r18, 172(r1) # save R18 - stw r19, 176(r1) # save R19 - stw r20, 180(r1) # save R20 - stw r21, 184(r1) # save R21 - stw r22, 188(r1) # save R22 - stw r23, 192(r1) # save R23 - stw r24, 196(r1) # save R24 - stw r25, 200(r1) # save R25 - stw r26, 204(r1) # save R26 - stw r27, 208(r1) # save R27 - stw r28, 212(r1) # save R28 - stw r29, 216(r1) # save R29 - stw r30, 220(r1) # save R30 - stw r31, 224(r1) # save R31 - stw r3, 228(r1) # save hidden + stw r13, 152(r1) ; save R13 + stw r14, 156(r1) ; save R14 + stw r15, 160(r1) ; save R15 + stw r16, 164(r1) ; save R16 + stw r17, 168(r1) ; save R17 + stw r18, 172(r1) ; save R18 + stw r19, 176(r1) ; save R19 + stw r20, 180(r1) ; save R20 + stw r21, 184(r1) ; save R21 + stw r22, 188(r1) ; save R22 + stw r23, 192(r1) ; save R23 + stw r24, 196(r1) ; save R24 + stw r25, 200(r1) ; save R25 + stw r26, 204(r1) ; save R26 + stw r27, 208(r1) ; save R27 + stw r28, 212(r1) ; save R28 + stw r29, 216(r1) ; save R29 + stw r30, 220(r1) ; save R30 + stw r31, 224(r1) ; save R31 + stw r3, 228(r1) ; save hidden - # save CR + ; save CR mfcr r0 stw r0, 232(r1) - # save LR + ; save LR mflr r0 stw r0, 236(r1) - # save LR as PC + ; save LR as PC stw r0, 240(r1) - # store RSP (pointing to context-data) in R6 + ; store RSP (pointing to context-data) in R6 mr r6, r1 - # restore RSP (pointing to context-data) from R4 + ; restore RSP (pointing to context-data) from R4 mr r1, r4 - lfd f14, 0(r1) # restore F14 - lfd f15, 8(r1) # restore F15 - lfd f16, 16(r1) # restore F16 - lfd f17, 24(r1) # restore F17 - lfd f18, 32(r1) # restore F18 - lfd f19, 40(r1) # restore F19 - lfd f20, 48(r1) # restore F20 - lfd f21, 56(r1) # restore F21 - lfd f22, 64(r1) # restore F22 - lfd f23, 72(r1) # restore F23 - lfd f24, 80(r1) # restore F24 - lfd f25, 88(r1) # restore F25 - lfd f26, 96(r1) # restore F26 - lfd f27, 104(r1) # restore F27 - lfd f28, 112(r1) # restore F28 - lfd f29, 120(r1) # restore F29 - lfd f30, 128(r1) # restore F30 - lfd f31, 136(r1) # restore F31 - lfd f0, 144(r1) # load FPSCR - mtfsf 0xff, f0 # restore FPSCR + lfd f14, 0(r1) ; restore F14 + lfd f15, 8(r1) ; restore F15 + lfd f16, 16(r1) ; restore F16 + lfd f17, 24(r1) ; restore F17 + lfd f18, 32(r1) ; restore F18 + lfd f19, 40(r1) ; restore F19 + lfd f20, 48(r1) ; restore F20 + lfd f21, 56(r1) ; restore F21 + lfd f22, 64(r1) ; restore F22 + lfd f23, 72(r1) ; restore F23 + lfd f24, 80(r1) ; restore F24 + lfd f25, 88(r1) ; restore F25 + lfd f26, 96(r1) ; restore F26 + lfd f27, 104(r1) ; restore F27 + lfd f28, 112(r1) ; restore F28 + lfd f29, 120(r1) ; restore F29 + lfd f30, 128(r1) ; restore F30 + lfd f31, 136(r1) ; restore F31 + lfd f0, 144(r1) ; load FPSCR + mtfsf 0xff, f0 ; restore FPSCR - lwz r13, 152(r1) # restore R13 - lwz r14, 156(r1) # restore R14 - lwz r15, 160(r1) # restore R15 - lwz r16, 164(r1) # restore R16 - lwz r17, 168(r1) # restore R17 - lwz r18, 172(r1) # restore R18 - lwz r19, 176(r1) # restore R19 - lwz r20, 180(r1) # restore R20 - lwz r21, 184(r1) # restore R21 - lwz r22, 188(r1) # restore R22 - lwz r23, 192(r1) # restore R23 - lwz r24, 196(r1) # restore R24 - lwz r25, 200(r1) # restore R25 - lwz r26, 204(r1) # restore R26 - lwz r27, 208(r1) # restore R27 - lwz r28, 212(r1) # restore R28 - lwz r29, 216(r1) # restore R29 - lwz r30, 220(r1) # restore R30 - lwz r31, 224(r1) # restore R31 - lwz r3, 228(r1) # restore hidden + lwz r13, 152(r1) ; restore R13 + lwz r14, 156(r1) ; restore R14 + lwz r15, 160(r1) ; restore R15 + lwz r16, 164(r1) ; restore R16 + lwz r17, 168(r1) ; restore R17 + lwz r18, 172(r1) ; restore R18 + lwz r19, 176(r1) ; restore R19 + lwz r20, 180(r1) ; restore R20 + lwz r21, 184(r1) ; restore R21 + lwz r22, 188(r1) ; restore R22 + lwz r23, 192(r1) ; restore R23 + lwz r24, 196(r1) ; restore R24 + lwz r25, 200(r1) ; restore R25 + lwz r26, 204(r1) ; restore R26 + lwz r27, 208(r1) ; restore R27 + lwz r28, 212(r1) ; restore R28 + lwz r29, 216(r1) ; restore R29 + lwz r30, 220(r1) ; restore R30 + lwz r31, 224(r1) ; restore R31 + lwz r3, 228(r1) ; restore hidden - # restore CR + ; restore CR lwz r0, 232(r1) mtcr r0 - # restore LR + ; restore LR lwz r0, 236(r1) mtlr r0 - # load PC + ; load PC lwz r0, 240(r1) - # restore CTR + ; restore CTR mtctr r0 - # adjust stack + ; adjust stack addi r1, r1, 244 - # return transfer_t + ; return transfer_t stw r6, 0(r3) stw r5, 4(r3) - # jump to context + ; jump to context bctr diff --git a/src/asm/jump_ppc64_sysv_macho_gas.S b/src/asm/jump_ppc64_sysv_macho_gas.S index 74fcb2ab..dcc6c645 100644 --- a/src/asm/jump_ppc64_sysv_macho_gas.S +++ b/src/asm/jump_ppc64_sysv_macho_gas.S @@ -12,7 +12,7 @@ * ------------------------------------------------- * * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * * ------------------------------------------------- * - * | TOC | R14 | R15 | R16 | * + * | R13 | R14 | R15 | R16 | * * ------------------------------------------------- * * ------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * @@ -61,7 +61,7 @@ * ------------------------------------------------- * * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * * ------------------------------------------------- * - * | TOC saved | FCTX | DATA | | * + * | FCTX | DATA | | | * * ------------------------------------------------- * * * *******************************************************/ @@ -138,27 +138,27 @@ _jump_fcontext: ; load PC ld r12, 176(r1) - # restore CTR + ; restore CTR mtctr r12 - # adjust stack + ; adjust stack addi r1, r1, 184 - # zero in r3 indicates first jump to context-function + ; zero in r3 indicates first jump to context-function cmpdi r3, 0 beq use_entry_arg - # return transfer_t + ; return transfer_t std r6, 0(r3) std r5, 8(r3) - # jump to context + ; jump to context bctr use_entry_arg: - # copy transfer_t into transfer_fn arg registers + ; copy transfer_t into transfer_fn arg registers mr r3, r6 mr r4, r5 - # jump to context + ; jump to context bctr diff --git a/src/asm/jump_x86_64_sysv_elf_gas.S b/src/asm/jump_x86_64_sysv_elf_gas.S index 49726699..58f0e241 100644 --- a/src/asm/jump_x86_64_sysv_elf_gas.S +++ b/src/asm/jump_x86_64_sysv_elf_gas.S @@ -12,19 +12,29 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * | fc_mxcsr|fc_x87_cw| guard | R12 | R13 | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * * ---------------------------------------------------------------------------------- * - * | R15 | RBX | RBP | RIP | * + * | R14 | R15 | RBX | RBP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | RIP | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ + # if defined __CET__ # include +# define SHSTK_ENABLED (__CET__ & 0x2) +# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL) # else # define _CET_ENDBR # endif @@ -35,19 +45,32 @@ .align 16 jump_fcontext: _CET_ENDBR - leaq -0x38(%rsp), %rsp /* prepare stack */ + leaq -0x40(%rsp), %rsp /* prepare stack */ #if !defined(BOOST_USE_TSX) stmxcsr (%rsp) /* save MMX control- and status-word */ fnstcw 0x4(%rsp) /* save x87 control-word */ #endif - movq %r12, 0x8(%rsp) /* save R12 */ - movq %r13, 0x10(%rsp) /* save R13 */ - movq %r14, 0x18(%rsp) /* save R14 */ - movq %r15, 0x20(%rsp) /* save R15 */ - movq %rbx, 0x28(%rsp) /* save RBX */ - movq %rbp, 0x30(%rsp) /* save RBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movq %fs:0x28, %rcx /* read stack guard from TLS record */ + movq %rcx, 0x8(%rsp) /* save stack guard */ +#endif + + movq %r12, 0x10(%rsp) /* save R12 */ + movq %r13, 0x18(%rsp) /* save R13 */ + movq %r14, 0x20(%rsp) /* save R14 */ + movq %r15, 0x28(%rsp) /* save R15 */ + movq %rbx, 0x30(%rsp) /* save RBX */ + movq %rbp, 0x38(%rsp) /* save RBP */ + +#if BOOST_CONTEXT_SHADOW_STACK + /* grow the stack to reserve space for shadow stack pointer(SSP) */ + leaq -0x8(%rsp), %rsp + /* read the current SSP and store it */ + rdsspq %rcx + movq %rcx, (%rsp) +#endif /* store RSP (pointing to context-data) in RAX */ movq %rsp, %rax @@ -55,21 +78,44 @@ jump_fcontext: /* restore RSP (pointing to context-data) from RDI */ movq %rdi, %rsp - movq 0x38(%rsp), %r8 /* restore return-address */ +#if BOOST_CONTEXT_SHADOW_STACK + /* first 8 bytes are SSP */ + movq (%rsp), %rcx + leaq 0x8(%rsp), %rsp + + /* Restore target(new) shadow stack */ + rstorssp -8(%rcx) + /* restore token for previous shadow stack is pushed */ + /* on previous shadow stack after saveprevssp */ + saveprevssp + + /* when return, jump_fcontext jump to restored return address */ + /* (r8) instead of RET. This miss of RET implies us to unwind */ + /* shadow stack accordingly. Otherwise mismatch occur */ + movq $1, %rcx + incsspq %rcx +#endif + + movq 0x40(%rsp), %r8 /* restore return-address */ #if !defined(BOOST_USE_TSX) ldmxcsr (%rsp) /* restore MMX control- and status-word */ fldcw 0x4(%rsp) /* restore x87 control-word */ #endif - movq 0x8(%rsp), %r12 /* restore R12 */ - movq 0x10(%rsp), %r13 /* restore R13 */ - movq 0x18(%rsp), %r14 /* restore R14 */ - movq 0x20(%rsp), %r15 /* restore R15 */ - movq 0x28(%rsp), %rbx /* restore RBX */ - movq 0x30(%rsp), %rbp /* restore RBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movq 0x8(%rsp), %rdx /* load stack guard */ + movq %rdx, %fs:0x28 /* restore stack guard to TLS record */ +#endif + + movq 0x10(%rsp), %r12 /* restore R12 */ + movq 0x18(%rsp), %r13 /* restore R13 */ + movq 0x20(%rsp), %r14 /* restore R14 */ + movq 0x28(%rsp), %r15 /* restore R15 */ + movq 0x30(%rsp), %rbx /* restore RBX */ + movq 0x38(%rsp), %rbp /* restore RBP */ - leaq 0x40(%rsp), %rsp /* prepare stack */ + leaq 0x48(%rsp), %rsp /* prepare stack */ /* return transfer_t from jump */ #if !defined(_ILP32) diff --git a/src/asm/make_i386_sysv_elf_gas.S b/src/asm/make_i386_sysv_elf_gas.S index b76de260..0b7ab811 100644 --- a/src/asm/make_i386_sysv_elf_gas.S +++ b/src/asm/make_i386_sysv_elf_gas.S @@ -12,14 +12,14 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * | fc_mxcsr|fc_x87_cw| guard | EDI | ESI | EBX | EBP | EIP | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * - * | 0x20 | 0x24 | | * + * | 0x20 | 0x24 | 0x28 | | * * ---------------------------------------------------------------------------------- * - * | to | data | | * + * | hidden | to | data | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ @@ -41,22 +41,28 @@ make_fcontext: andl $-16, %eax /* reserve space for context-data on context-stack */ - leal -0x28(%eax), %eax + leal -0x2c(%eax), %eax /* third arg of make_fcontext() == address of context-function */ /* stored in EBX */ movl 0xc(%esp), %ecx - movl %ecx, 0x10(%eax) + movl %ecx, 0x14(%eax) /* save MMX control- and status-word */ stmxcsr (%eax) /* save x87 control-word */ fnstcw 0x4(%eax) +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + /* save stack guard */ + movl %gs:0x14, %ecx /* read stack guard from TLS record */ + movl %ecx, 0x8(%eax) /* save stack guard */ +#endif + /* return transport_t */ /* FCTX == EDI, DATA == ESI */ - leal 0x8(%eax), %ecx - movl %ecx, 0x1c(%eax) + leal 0xc(%eax), %ecx + movl %ecx, 0x20(%eax) /* compute abs address of label trampoline */ call 1f @@ -66,7 +72,7 @@ make_fcontext: addl $trampoline-1b, %ecx /* save address of trampoline as return address */ /* will be entered after calling jump_fcontext() first time */ - movl %ecx, 0x18(%eax) + movl %ecx, 0x1c(%eax) /* compute abs address of label finish */ call 2f @@ -76,7 +82,7 @@ make_fcontext: addl $finish-2b, %ecx /* save address of finish as return-address for context-function */ /* will be entered after context-function returns */ - movl %ecx, 0x14(%eax) + movl %ecx, 0x18(%eax) ret /* return pointer to context-data */ diff --git a/src/asm/make_ppc32_sysv_macho_gas.S b/src/asm/make_ppc32_sysv_macho_gas.S index 8f35eff9..e5c1b67c 100644 --- a/src/asm/make_ppc32_sysv_macho_gas.S +++ b/src/asm/make_ppc32_sysv_macho_gas.S @@ -77,61 +77,61 @@ .globl _make_fcontext .align 2 _make_fcontext: - # save return address into R6 + ; save return address into R6 mflr r6 - # first arg of make_fcontext() == top address of context-function - # shift address in R3 to lower 16 byte boundary + ; first arg of make_fcontext() == top address of context-function + ; shift address in R3 to lower 16 byte boundary clrrwi r3, r3, 4 - # reserve space for context-data on context-stack - # including 64 byte of linkage + parameter area (R1 16 == 0) + ; reserve space for context-data on context-stack + ; including 64 byte of linkage + parameter area (R1 16 == 0) subi r3, r3, 336 - # third arg of make_fcontext() == address of context-function + ; third arg of make_fcontext() == address of context-function stw r5, 240(r3) - # set back-chain to zero + ; set back-chain to zero li r0, 0 stw r0, 244(r3) - mffs f0 # load FPSCR - stfd f0, 144(r3) # save FPSCR + mffs f0 ; load FPSCR + stfd f0, 144(r3) ; save FPSCR - # compute address of returned transfer_t + ; compute address of returned transfer_t addi r0, r3, 252 mr r4, r0 stw r4, 228(r3) - # load LR + ; load LR mflr r0 - # jump to label 1 + ; jump to label 1 bl 1f 1: - # load LR into R4 + ; load LR into R4 mflr r4 - # compute abs address of label finish + ; compute abs address of label finish addi r4, r4, finish - 1b - # restore LR + ; restore LR mtlr r0 - # save address of finish as return-address for context-function - # will be entered after context-function returns + ; save address of finish as return-address for context-function + ; will be entered after context-function returns stw r4, 236(r3) - # restore return address from R6 + ; restore return address from R6 mtlr r6 - blr # return pointer to context-data + blr ; return pointer to context-data finish: - # save return address into R0 + ; save return address into R0 mflr r0 - # save return address on stack, set up stack frame + ; save return address on stack, set up stack frame stw r0, 4(r1) - # allocate stack space, R1 16 == 0 + ; allocate stack space, R1 16 == 0 stwu r1, -16(r1) - # exit code is zero + ; exit code is zero li r3, 0 - # exit application - bl _exit@plt + ; exit application + bl _exit diff --git a/src/asm/make_ppc64_sysv_macho_gas.S b/src/asm/make_ppc64_sysv_macho_gas.S index 7b947bb6..fb5cada2 100644 --- a/src/asm/make_ppc64_sysv_macho_gas.S +++ b/src/asm/make_ppc64_sysv_macho_gas.S @@ -12,7 +12,7 @@ * ------------------------------------------------- * * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * * ------------------------------------------------- * - * | TOC | R14 | R15 | R16 | * + * | R13 | R14 | R15 | R16 | * * ------------------------------------------------- * * ------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * @@ -61,7 +61,7 @@ * ------------------------------------------------- * * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * * ------------------------------------------------- * - * | TOC saved | FCTX | DATA | | * + * | FCTX | DATA | | | * * ------------------------------------------------- * * * @@ -77,19 +77,19 @@ _make_fcontext: ; reserve space for context-data on context-stack ; including 64 byte of linkage + parameter area (R1 16 == 0) - subi r3, r3, 248 + subi r3, r3, 240 ; third arg of make_fcontext() == address of context-function stw r5, 176(r3) ; set back-chain to zero - li %r0, 0 - std %r0, 184(%r3) + li r0, 0 + std r0, 184(r3) ; compute address of returned transfer_t - addi %r0, %r3, 232 - mr %r4, %r0 - std %r4, 152(%r3) + addi r0, r3, 224 + mr r4, r0 + std r4, 152(r3) ; load LR mflr r0 diff --git a/src/asm/make_x86_64_sysv_elf_gas.S b/src/asm/make_x86_64_sysv_elf_gas.S index 7b760082..4294398a 100644 --- a/src/asm/make_x86_64_sysv_elf_gas.S +++ b/src/asm/make_x86_64_sysv_elf_gas.S @@ -12,19 +12,29 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * | fc_mxcsr|fc_x87_cw| guard | R12 | R13 | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * * ---------------------------------------------------------------------------------- * - * | R15 | RBX | RBP | RIP | * + * | R14 | R15 | RBX | RBP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | RIP | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ + # if defined __CET__ # include +# define SHSTK_ENABLED (__CET__ & 0x2) +# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL) # else # define _CET_ENDBR # endif @@ -35,6 +45,11 @@ .align 16 make_fcontext: _CET_ENDBR +#if BOOST_CONTEXT_SHADOW_STACK + /* the new shadow stack pointer (SSP) */ + movq -0x8(%rdi), %r9 +#endif + /* first arg of make_fcontext() == top of context-stack */ movq %rdi, %rax @@ -43,28 +58,63 @@ make_fcontext: /* reserve space for context-data on context-stack */ /* on context-function entry: (RSP -0x8) % 16 == 0 */ - leaq -0x40(%rax), %rax + leaq -0x48(%rax), %rax /* third arg of make_fcontext() == address of context-function */ /* stored in RBX */ - movq %rdx, 0x28(%rax) + movq %rdx, 0x30(%rax) /* save MMX control- and status-word */ stmxcsr (%rax) /* save x87 control-word */ fnstcw 0x4(%rax) +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + /* save stack guard */ + movq %fs:0x28, %rcx /* read stack guard from TLS record */ + movq %rcx, 0x8(%rsp) /* save stack guard */ +#endif + /* compute abs address of label trampoline */ leaq trampoline(%rip), %rcx /* save address of trampoline as return-address for context-function */ /* will be entered after calling jump_fcontext() first time */ - movq %rcx, 0x38(%rax) + movq %rcx, 0x40(%rax) /* compute abs address of label finish */ leaq finish(%rip), %rcx /* save address of finish as return-address for context-function */ /* will be entered after context-function returns */ - movq %rcx, 0x30(%rax) + movq %rcx, 0x38(%rax) + +#if BOOST_CONTEXT_SHADOW_STACK + /* Populate the shadow stack and normal stack */ + /* get original SSP */ + rdsspq %r8 + /* restore new shadow stack */ + rstorssp -0x8(%r9) + /* save the restore token on the original shadow stack */ + saveprevssp + /* push the address of "jmp trampoline" to the new shadow stack */ + /* as well as the stack */ + call 1f + jmp trampoline +1: + /* save address of "jmp trampoline" as return-address */ + /* for context-function */ + pop 0x38(%rax) + /* Get the new SSP. */ + rdsspq %r9 + /* restore original shadow stack */ + rstorssp -0x8(%r8) + /* save the restore token on the new shadow stack. */ + saveprevssp + + /* reserve space for the new SSP */ + leaq -0x8(%rax), %rax + /* save the new SSP to this fcontext */ + movq %r9, (%rax) +#endif ret /* return pointer to context-data */ @@ -72,7 +122,15 @@ trampoline: _CET_ENDBR /* store return address on stack */ /* fix stack alignment */ +#if BOOST_CONTEXT_SHADOW_STACK + /* save address of "jmp *%rbp" as return-address */ + /* on stack and shadow stack */ + call 2f + jmp *%rbp +2: +#else push %rbp +#endif /* jump to context-function */ jmp *%rbx diff --git a/src/asm/ontop_i386_sysv_elf_gas.S b/src/asm/ontop_i386_sysv_elf_gas.S index 40fe6c2a..0cb6168f 100644 --- a/src/asm/ontop_i386_sysv_elf_gas.S +++ b/src/asm/ontop_i386_sysv_elf_gas.S @@ -12,14 +12,14 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * | fc_mxcsr|fc_x87_cw| guard | EDI | ESI | EBX | EBP | EIP | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * - * | 0x20 | 0x24 | | * + * | 0x20 | 0x24 | 0x28 | | * * ---------------------------------------------------------------------------------- * - * | to | data | | * + * | hidden | to | data | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ @@ -30,41 +30,46 @@ .align 2 .type ontop_fcontext,@function ontop_fcontext: - leal -0x18(%esp), %esp /* prepare stack */ + leal -0x1c(%esp), %esp /* prepare stack */ #if !defined(BOOST_USE_TSX) stmxcsr (%esp) /* save MMX control- and status-word */ fnstcw 0x4(%esp) /* save x87 control-word */ #endif - movl %edi, 0x8(%esp) /* save EDI */ - movl %esi, 0xc(%esp) /* save ESI */ - movl %ebx, 0x10(%esp) /* save EBX */ - movl %ebp, 0x14(%esp) /* save EBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movl %gs:0x14, %ecx /* read stack guard from TLS record */ + movl %ecx, 0x8(%esp) /* save stack guard */ +#endif + + movl %edi, 0xc(%esp) /* save EDI */ + movl %esi, 0x10(%esp) /* save ESI */ + movl %ebx, 0x14(%esp) /* save EBX */ + movl %ebp, 0x18(%esp) /* save EBP */ /* store ESP (pointing to context-data) in ECX */ movl %esp, %ecx /* first arg of ontop_fcontext() == fcontext to jump to */ - movl 0x20(%esp), %eax + movl 0x24(%esp), %eax /* pass parent fcontext_t */ - movl %ecx, 0x20(%eax) + movl %ecx, 0x24(%eax) /* second arg of ontop_fcontext() == data to be transferred */ - movl 0x24(%esp), %ecx + movl 0x28(%esp), %ecx /* pass data */ - movl %ecx, 0x24(%eax) + movl %ecx, 0x28(%eax) /* third arg of ontop_fcontext() == ontop-function */ - movl 0x28(%esp), %ecx + movl 0x2c(%esp), %ecx /* restore ESP (pointing to context-data) from EAX */ movl %eax, %esp /* address of returned transport_t */ - movl 0x1c(%esp), %eax + movl 0x20(%esp), %eax /* return parent fcontext_t */ movl %ecx, (%eax) /* return data */ @@ -75,12 +80,17 @@ ontop_fcontext: fldcw 0x4(%esp) /* restore x87 control-word */ #endif - movl 0x8(%esp), %edi /* restore EDI */ - movl 0xc(%esp), %esi /* restore ESI */ - movl 0x10(%esp), %ebx /* restore EBX */ - movl 0x14(%esp), %ebp /* restore EBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movl 0x8(%esp), %edx /* load stack guard */ + movl %edx, %gs:0x14 /* restore stack guard to TLS record */ +#endif + + movl 0xc(%esp), %edi /* restore EDI */ + movl 0x10(%esp), %esi /* restore ESI */ + movl 0x14(%esp), %ebx /* restore EBX */ + movl 0x18(%esp), %ebp /* restore EBP */ - leal 0x18(%esp), %esp /* prepare stack */ + leal 0x1c(%esp), %esp /* prepare stack */ /* jump to context */ jmp *%ecx diff --git a/src/asm/ontop_ppc32_sysv_macho_gas.S b/src/asm/ontop_ppc32_sysv_macho_gas.S index 1eb5f934..2e701ebd 100644 --- a/src/asm/ontop_ppc32_sysv_macho_gas.S +++ b/src/asm/ontop_ppc32_sysv_macho_gas.S @@ -77,125 +77,125 @@ .globl _ontop_fcontext .align 2 _ontop_fcontext: - # reserve space on stack + ; reserve space on stack subi r1, r1, 244 - stfd f14, 0(r1) # save F14 - stfd f15, 8(r1) # save F15 - stfd f16, 16(r1) # save F16 - stfd f17, 24(r1) # save F17 - stfd f18, 32(r1) # save F18 - stfd f19, 40(r1) # save F19 - stfd f20, 48(r1) # save F20 - stfd f21, 56(r1) # save F21 - stfd f22, 64(r1) # save F22 - stfd f23, 72(r1) # save F23 - stfd f24, 80(r1) # save F24 - stfd f25, 88(r1) # save F25 - stfd f26, 96(r1) # save F26 - stfd f27, 104(r1) # save F27 - stfd f28, 112(r1) # save F28 - stfd f29, 120(r1) # save F29 - stfd f30, 128(r1) # save F30 - stfd f31, 136(r1) # save F31 - mffs f0 # load FPSCR - stfd f0, 144(r1) # save FPSCR + stfd f14, 0(r1) ; save F14 + stfd f15, 8(r1) ; save F15 + stfd f16, 16(r1) ; save F16 + stfd f17, 24(r1) ; save F17 + stfd f18, 32(r1) ; save F18 + stfd f19, 40(r1) ; save F19 + stfd f20, 48(r1) ; save F20 + stfd f21, 56(r1) ; save F21 + stfd f22, 64(r1) ; save F22 + stfd f23, 72(r1) ; save F23 + stfd f24, 80(r1) ; save F24 + stfd f25, 88(r1) ; save F25 + stfd f26, 96(r1) ; save F26 + stfd f27, 104(r1) ; save F27 + stfd f28, 112(r1) ; save F28 + stfd f29, 120(r1) ; save F29 + stfd f30, 128(r1) ; save F30 + stfd f31, 136(r1) ; save F31 + mffs f0 ; load FPSCR + stfd f0, 144(r1) ; save FPSCR - stw r13, 152(r1) # save R13 - stw r14, 156(r1) # save R14 - stw r15, 160(r1) # save R15 - stw r16, 164(r1) # save R16 - stw r17, 168(r1) # save R17 - stw r18, 172(r1) # save R18 - stw r19, 176(r1) # save R19 - stw r20, 180(r1) # save R20 - stw r21, 184(r1) # save R21 - stw r22, 188(r1) # save R22 - stw r23, 192(r1) # save R23 - stw r24, 196(r1) # save R24 - stw r25, 200(r1) # save R25 - stw r26, 204(r1) # save R26 - stw r27, 208(r1) # save R27 - stw r28, 212(r1) # save R28 - stw r29, 216(r1) # save R29 - stw r30, 220(r1) # save R30 - stw r31, 224(r1) # save R31 - stw r3, 228(r1) # save hidden + stw r13, 152(r1) ; save R13 + stw r14, 156(r1) ; save R14 + stw r15, 160(r1) ; save R15 + stw r16, 164(r1) ; save R16 + stw r17, 168(r1) ; save R17 + stw r18, 172(r1) ; save R18 + stw r19, 176(r1) ; save R19 + stw r20, 180(r1) ; save R20 + stw r21, 184(r1) ; save R21 + stw r22, 188(r1) ; save R22 + stw r23, 192(r1) ; save R23 + stw r24, 196(r1) ; save R24 + stw r25, 200(r1) ; save R25 + stw r26, 204(r1) ; save R26 + stw r27, 208(r1) ; save R27 + stw r28, 212(r1) ; save R28 + stw r29, 216(r1) ; save R29 + stw r30, 220(r1) ; save R30 + stw r31, 224(r1) ; save R31 + stw r3, 228(r1) ; save hidden - # save CR + ; save CR mfcr r0 stw r0, 232(r1) - # save LR + ; save LR mflr r0 stw r0, 236(r1) - # save LR as PC + ; save LR as PC stw r0, 240(r1) - # store RSP (pointing to context-data) in R7 + ; store RSP (pointing to context-data) in R7 mr r7, r1 - # restore RSP (pointing to context-data) from R4 + ; restore RSP (pointing to context-data) from R4 mr r1, r4 - lfd f14, 0(r1) # restore F14 - lfd f15, 8(r1) # restore F15 - lfd f16, 16(r1) # restore F16 - lfd f17, 24(r1) # restore F17 - lfd f18, 32(r1) # restore F18 - lfd f19, 40(r1) # restore F19 - lfd f20, 48(r1) # restore F20 - lfd f21, 56(r1) # restore F21 - lfd f22, 64(r1) # restore F22 - lfd f23, 72(r1) # restore F23 - lfd f24, 80(r1) # restore F24 - lfd f25, 88(r1) # restore F25 - lfd f26, 96(r1) # restore F26 - lfd f27, 104(r1) # restore F27 - lfd f28, 112(r1) # restore F28 - lfd f29, 120(r1) # restore F29 - lfd f30, 128(r1) # restore F30 - lfd f31, 136(r1) # restore F31 - lfd f0, 144(r1) # load FPSCR - mtfsf 0xff, f0 # restore FPSCR + lfd f14, 0(r1) ; restore F14 + lfd f15, 8(r1) ; restore F15 + lfd f16, 16(r1) ; restore F16 + lfd f17, 24(r1) ; restore F17 + lfd f18, 32(r1) ; restore F18 + lfd f19, 40(r1) ; restore F19 + lfd f20, 48(r1) ; restore F20 + lfd f21, 56(r1) ; restore F21 + lfd f22, 64(r1) ; restore F22 + lfd f23, 72(r1) ; restore F23 + lfd f24, 80(r1) ; restore F24 + lfd f25, 88(r1) ; restore F25 + lfd f26, 96(r1) ; restore F26 + lfd f27, 104(r1) ; restore F27 + lfd f28, 112(r1) ; restore F28 + lfd f29, 120(r1) ; restore F29 + lfd f30, 128(r1) ; restore F30 + lfd f31, 136(r1) ; restore F31 + lfd f0, 144(r1) ; load FPSCR + mtfsf 0xff, f0 ; restore FPSCR - lwz r13, 152(r1) # restore R13 - lwz r14, 156(r1) # restore R14 - lwz r15, 160(r1) # restore R15 - lwz r16, 164(r1) # restore R16 - lwz r17, 168(r1) # restore R17 - lwz r18, 172(r1) # restore R18 - lwz r19, 176(r1) # restore R19 - lwz r20, 180(r1) # restore R20 - lwz r21, 184(r1) # restore R21 - lwz r22, 188(r1) # restore R22 - lwz r23, 192(r1) # restore R23 - lwz r24, 196(r1) # restore R24 - lwz r25, 200(r1) # restore R25 - lwz r26, 204(r1) # restore R26 - lwz r27, 208(r1) # restore R27 - lwz r28, 212(r1) # restore R28 - lwz r29, 216(r1) # restore R29 - lwz r30, 220(r1) # restore R30 - lwz r31, 224(r1) # restore R31 - lwz r4, 228(r1) # restore hidden + lwz r13, 152(r1) ; restore R13 + lwz r14, 156(r1) ; restore R14 + lwz r15, 160(r1) ; restore R15 + lwz r16, 164(r1) ; restore R16 + lwz r17, 168(r1) ; restore R17 + lwz r18, 172(r1) ; restore R18 + lwz r19, 176(r1) ; restore R19 + lwz r20, 180(r1) ; restore R20 + lwz r21, 184(r1) ; restore R21 + lwz r22, 188(r1) ; restore R22 + lwz r23, 192(r1) ; restore R23 + lwz r24, 196(r1) ; restore R24 + lwz r25, 200(r1) ; restore R25 + lwz r26, 204(r1) ; restore R26 + lwz r27, 208(r1) ; restore R27 + lwz r28, 212(r1) ; restore R28 + lwz r29, 216(r1) ; restore R29 + lwz r30, 220(r1) ; restore R30 + lwz r31, 224(r1) ; restore R31 + lwz r4, 228(r1) ; restore hidden - # restore CR + ; restore CR lwz r0, 232(r1) mtcr r0 - # restore LR + ; restore LR lwz r0, 236(r1) mtlr r0 - # ignore PC + ; ignore PC - # adjust stack + ; adjust stack addi r1, r1, 244 - # return transfer_t + ; return transfer_t stw r7, 0(r4) stw r5, 4(r4) - # restore CTR + ; restore CTR mtctr r6 - # jump to ontop-function + ; jump to ontop-function bctr diff --git a/src/asm/ontop_ppc64_sysv_macho_gas.S b/src/asm/ontop_ppc64_sysv_macho_gas.S index 5de8acd1..a9fe8cf5 100644 --- a/src/asm/ontop_ppc64_sysv_macho_gas.S +++ b/src/asm/ontop_ppc64_sysv_macho_gas.S @@ -12,7 +12,7 @@ * ------------------------------------------------- * * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * * ------------------------------------------------- * - * | TOC | R14 | R15 | R16 | * + * | R13 | R14 | R15 | R16 | * * ------------------------------------------------- * * ------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * @@ -61,7 +61,7 @@ * ------------------------------------------------- * * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * * ------------------------------------------------- * - * | TOC saved | FCTX | DATA | | * + * | FCTX | DATA | | | * * ------------------------------------------------- * * * *******************************************************/ diff --git a/src/asm/ontop_x86_64_sysv_elf_gas.S b/src/asm/ontop_x86_64_sysv_elf_gas.S index 2b764d35..c3892b8b 100644 --- a/src/asm/ontop_x86_64_sysv_elf_gas.S +++ b/src/asm/ontop_x86_64_sysv_elf_gas.S @@ -12,19 +12,28 @@ * ---------------------------------------------------------------------------------- * * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * * ---------------------------------------------------------------------------------- * - * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * | fc_mxcsr|fc_x87_cw| guard | R12 | R13 | * * ---------------------------------------------------------------------------------- * * ---------------------------------------------------------------------------------- * * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * * ---------------------------------------------------------------------------------- * * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * * ---------------------------------------------------------------------------------- * - * | R15 | RBX | RBP | RIP | * + * | R14 | R15 | RBX | RBP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | RIP | | * * ---------------------------------------------------------------------------------- * * * ****************************************************************************************/ # if defined __CET__ # include +# define SHSTK_ENABLED (__CET__ & 0x2) +# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL) # else # define _CET_ENDBR # endif @@ -38,19 +47,32 @@ ontop_fcontext: /* preserve ontop-function in R8 */ movq %rdx, %r8 - leaq -0x38(%rsp), %rsp /* prepare stack */ + leaq -0x40(%rsp), %rsp /* prepare stack */ #if !defined(BOOST_USE_TSX) stmxcsr (%rsp) /* save MMX control- and status-word */ fnstcw 0x4(%rsp) /* save x87 control-word */ #endif - movq %r12, 0x8(%rsp) /* save R12 */ - movq %r13, 0x10(%rsp) /* save R13 */ - movq %r14, 0x18(%rsp) /* save R14 */ - movq %r15, 0x20(%rsp) /* save R15 */ - movq %rbx, 0x28(%rsp) /* save RBX */ - movq %rbp, 0x30(%rsp) /* save RBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movq %fs:0x28, %rcx /* read stack guard from TLS record */ + movq %rcx, 0x8(%rsp) /* save stack guard */ +#endif + + movq %r12, 0x10(%rsp) /* save R12 */ + movq %r13, 0x18(%rsp) /* save R13 */ + movq %r14, 0x20(%rsp) /* save R14 */ + movq %r15, 0x28(%rsp) /* save R15 */ + movq %rbx, 0x30(%rsp) /* save RBX */ + movq %rbp, 0x38(%rsp) /* save RBP */ + +#if BOOST_CONTEXT_SHADOW_STACK + /* grow the stack to reserve space for shadow stack pointer(SSP) */ + leaq -0x8(%rsp), %rsp + /* read the current SSP and store it */ + rdsspq %rcx + movq %rcx, (%rsp) +#endif /* store RSP (pointing to context-data) in RAX */ movq %rsp, %rax @@ -58,19 +80,36 @@ ontop_fcontext: /* restore RSP (pointing to context-data) from RDI */ movq %rdi, %rsp +#if BOOST_CONTEXT_SHADOW_STACK + /* first 8 bytes are SSP */ + movq (%rsp), %rcx + leaq 0x8(%rsp), %rsp + + /* Restore target(new) shadow stack */ + rstorssp -8(%rcx) + /* restore token for previous shadow stack is pushed */ + /* on previous shadow stack after saveprevssp */ + saveprevssp +#endif + #if !defined(BOOST_USE_TSX) ldmxcsr (%rsp) /* restore MMX control- and status-word */ fldcw 0x4(%rsp) /* restore x87 control-word */ #endif - movq 0x8(%rsp), %r12 /* restore R12 */ - movq 0x10(%rsp), %r13 /* restore R13 */ - movq 0x18(%rsp), %r14 /* restore R14 */ - movq 0x20(%rsp), %r15 /* restore R15 */ - movq 0x28(%rsp), %rbx /* restore RBX */ - movq 0x30(%rsp), %rbp /* restore RBP */ +#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) + movq 0x8(%rsp), %rdx /* load stack guard */ + movq %rdx, %fs:0x28 /* restore stack guard to TLS record */ +#endif + + movq 0x10(%rsp), %r12 /* restore R12 */ + movq 0x18(%rsp), %r13 /* restore R13 */ + movq 0x20(%rsp), %r14 /* restore R14 */ + movq 0x28(%rsp), %r15 /* restore R15 */ + movq 0x30(%rsp), %rbx /* restore RBX */ + movq 0x38(%rsp), %rbp /* restore RBP */ - leaq 0x38(%rsp), %rsp /* prepare stack */ + leaq 0x40(%rsp), %rsp /* prepare stack */ /* return transfer_t from jump */ #if !defined(_ILP32)