;\r
\r
%define VC_EXCEPTION 29\r
+%define PF_EXCEPTION 14\r
\r
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions\r
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag\r
call ASM_PFX(CommonExceptionHandler)\r
add rsp, 4 * 8 + 8\r
\r
+ ; The follow algorithm is used for clear shadow stack token busy bit.\r
+ ; The comment is based on the sample shadow stack.\r
+ ; The sample shadow stack layout :\r
+ ; Address | Context\r
+ ; +-------------------------+\r
+ ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.\r
+ ; +-------------------------+\r
+ ; 0xFD8 | Prev SSP |\r
+ ; +-------------------------+\r
+ ; 0xFE0 | RIP |\r
+ ; +-------------------------+\r
+ ; 0xFE8 | CS |\r
+ ; +-------------------------+\r
+ ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY\r
+ ; +-------------------------+\r
+ ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) |\r
+ ; +-------------------------+\r
+ ; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.\r
+ cmp qword [ASM_PFX(mDoFarReturnFlag)], 0\r
+ jz CetDone\r
+ cmp qword [rbp + 8], PF_EXCEPTION ; check if it is a Page Fault\r
+ jnz CetDone\r
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
+ jz CetDone\r
+ mov rax, cr4\r
+ and rax, 0x800000 ; check if CET is enabled\r
+ jz CetDone\r
+ ; SSP should be 0xFD8 at this point\r
+ mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor shadow stack token\r
+ INCSSP_RAX ; After this SSP should be 0xFF8\r
+ SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFD0\r
+ READSSP_RAX ; Read new SSP, SSP should be 0x1000\r
+ sub rax, 0x10\r
+ CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this\r
+ sub rax, 0x20\r
+ RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0\r
+ mov rax, 0x01 ; Pop off the new save token created\r
+ INCSSP_RAX ; SSP should be 0xFD8 now\r
+CetDone:\r
+\r
cli\r
;; UINT64 ExceptionData;\r
add rsp, 8\r
push qword [rax + 0x18] ; save EFLAGS in new location\r
mov rax, [rax] ; restore rax\r
popfq ; restore EFLAGS\r
-\r
- ; The follow algorithm is used for clear shadow stack token busy bit.\r
- ; The comment is based on the sample shadow stack.\r
- ; The sample shadow stack layout :\r
- ; Address | Context\r
- ; +-------------------------+\r
- ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.\r
- ; +-------------------------+\r
- ; 0xFD8 | Prev SSP |\r
- ; +-------------------------+\r
- ; 0xFE0 | RIP |\r
- ; +-------------------------+\r
- ; 0xFE8 | CS |\r
- ; +-------------------------+\r
- ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY\r
- ; +-------------------------+\r
- ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) |\r
- ; +-------------------------+\r
- ; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.\r
- push rax ; SSP should be 0xFD8 at this point\r
- cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
- jz CetDone\r
- mov rax, cr4\r
- and rax, 0x800000 ; check if CET is enabled\r
- jz CetDone\r
- mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor shadow stack token\r
- INCSSP_RAX ; After this SSP should be 0xFF8\r
- SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFD0\r
- READSSP_RAX ; Read new SSP, SSP should be 0x1000\r
- push rax\r
- sub rax, 0x10\r
- CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this\r
- sub rax, 0x20\r
- RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0\r
- pop rax\r
- mov rax, 0x01 ; Pop off the new save token created\r
- INCSSP_RAX ; SSP should be 0xFD8 now\r
-CetDone:\r
- pop rax ; restore rax\r
-\r
- DB 0x48 ; prefix to composite "retq" with next "retf"\r
+ DB 0x48 ; prefix to composite "retq" with next "retf"\r
retf ; far return\r
DoIret:\r
iretq\r