Skip to content

Commit cb0f2df

Browse files
committed
Reconcile shadow stack with SP changes in RhpCallCatchFunclet
1 parent 39f2cd4 commit cb0f2df

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/coreclr/nativeaot/Runtime/amd64/AsmOffsetsCpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ PLAT_ASM_OFFSET(0f0, PAL_LIMITED_CONTEXT, Xmm15)
5858

5959
PLAT_ASM_SIZEOF(130, REGDISPLAY)
6060
PLAT_ASM_OFFSET(78, REGDISPLAY, SP)
61+
PLAT_ASM_OFFSET(80, REGDISPLAY, IP)
6162

6263
PLAT_ASM_OFFSET(18, REGDISPLAY, pRbx)
6364
PLAT_ASM_OFFSET(20, REGDISPLAY, pRbp)

src/coreclr/nativeaot/Runtime/amd64/ExceptionHandling.asm

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,9 @@ endif
490490
INLINE_THREAD_UNHIJACK rdx, rcx, r9 ;; Thread in rdx, trashes rcx and r9
491491

492492
mov rcx, [rsp + rsp_offsetof_arguments + 18h] ;; rcx <- current ExInfo *
493+
mov r10, [r8 + OFFSETOF__REGDISPLAY__IP] ;; r10 <- original IP value
493494
mov r8, [r8 + OFFSETOF__REGDISPLAY__SP] ;; r8 <- resume SP value
494-
xor r9d, r9d ;; r9 <- 0
495+
xor r9, r9 ;; r9 <- 0
495496

496497
@@: mov rcx, [rcx + OFFSETOF__ExInfo__m_pPrevExInfo] ;; rcx <- next ExInfo
497498
cmp rcx, r9
@@ -501,6 +502,20 @@ endif
501502

502503
@@: mov [rdx + OFFSETOF__Thread__m_pExInfoStackHead], rcx ;; store the new head on the Thread
503504

505+
;; Sanity check: if we have shadow stack, it should agree with what we have in rsp
506+
LOCAL_STACK_USE equ 118h
507+
ifdef _DEBUG
508+
rdsspq r9
509+
test r9, r9
510+
jz @f
511+
mov r9, [r9]
512+
cmp [rsp + LOCAL_STACK_USE], r9
513+
je @f
514+
int 3
515+
@@:
516+
xor r9, r9 ;; r9 <- 0
517+
endif
518+
504519
test [RhpTrapThreads], TrapThreadsFlags_AbortInProgress
505520
jz @f
506521

@@ -511,12 +526,28 @@ endif
511526
;; It was the ThreadAbortException, so rethrow it
512527
mov rcx, STATUS_REDHAWK_THREAD_ABORT
513528
mov rdx, rax ;; rdx <- continuation address as exception RIP
514-
mov rsp, r8 ;; reset the SP to resume SP value
515-
jmp RhpThrowHwEx ;; Throw the ThreadAbortException as a special kind of hardware exception
529+
mov rax, RhpThrowHwEx ;; Throw the ThreadAbortException as a special kind of hardware exception
516530

517-
;; reset RSP and jump to the continuation address
531+
;; reset RSP and jump to RAX
518532
@@: mov rsp, r8 ;; reset the SP to resume SP value
519-
jmp rax
533+
534+
;; if have shadow stack, then we need to reconcile it with the rsp change we have just made
535+
rdsspq r9
536+
test r9, r9
537+
jz NoSSP
538+
539+
;; Find the shadow stack pointer for the frame we are going to restore to.
540+
;; The SSP we search is pointing to the return address of the frame represented
541+
;; by the passed in context. So we search for the instruction pointer from
542+
;; the context and return one slot up from there.
543+
;; (Same logic as in GetSSPForFrameOnCurrentStack)
544+
xor r11, r11
545+
@@: inc r11
546+
cmp [r9 + r11 * 8 - 8], r10
547+
jne @b
548+
549+
incsspq r11
550+
NoSSP: jmp rax
520551

521552

522553
NESTED_END RhpCallCatchFunclet, _TEXT

0 commit comments

Comments
 (0)