public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Sheng Wei" <w.sheng@intel.com>
To: devel@edk2.groups.io
Cc: Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Rahul Kumar <rahul1.kumar@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Qihua Zhuang <qihua.zhuang@intel.com>,
	Daquan Dong <daquan.dong@intel.com>,
	Justin Tong <justin.tong@intel.com>, Tom Xu <tom.xu@intel.com>
Subject: [PATCH] UefiCpuPkg/ExceptionLib: Conditionally clear shadow stack token busy bit
Date: Fri,  2 Jul 2021 13:28:40 +0800	[thread overview]
Message-ID: <20210702052840.15860-1-w.sheng@intel.com> (raw)

When enter SMM exception, there will be a stack switch only if the IST
field of the interrupt gate is set. When CET shadow stack feature is
enabled, if there is a stack switch between SMM exception and SMM, the
shadow stack token busy bit needs to be cleared when return from SMM
exception to SMM. In UEFI BIOS, only page fault exception does the stack
swith when SMM shack guard feature is enabled. The condition of clear
shadow stack token busy bit should be SMM stack guard enabled, CET shadows
stack feature enabled and page fault exception.
The shadow stack token should be initialized by UINT64.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3462

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Qihua Zhuang <qihua.zhuang@intel.com>
Cc: Daquan Dong <daquan.dong@intel.com>
Cc: Justin Tong <justin.tong@intel.com>
Cc: Tom Xu <tom.xu@intel.com>
---
 .../X64/Xcode5ExceptionHandlerAsm.nasm             | 83 +++++++++++-----------
 UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c       |  2 +-
 2 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
index ebe0eec874..4881a02848 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
@@ -20,6 +20,7 @@
 ;
 
 %define VC_EXCEPTION 29
+%define PF_EXCEPTION 14
 
 extern ASM_PFX(mErrorCodeFlag)    ; Error code flags for exceptions
 extern ASM_PFX(mDoFarReturnFlag)  ; Do far return flag
@@ -279,6 +280,46 @@ DrFinish:
     call    ASM_PFX(CommonExceptionHandler)
     add     rsp, 4 * 8 + 8
 
+    ; The follow algorithm is used for clear shadow stack token busy bit.
+    ; The comment is based on the sample shadow stack.
+    ; The sample shadow stack layout :
+    ; Address | Context
+    ;         +-------------------------+
+    ;  0xFD0  |   FREE                  | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.
+    ;         +-------------------------+
+    ;  0xFD8  |  Prev SSP               |
+    ;         +-------------------------+
+    ;  0xFE0  |   RIP                   |
+    ;         +-------------------------+
+    ;  0xFE8  |   CS                    |
+    ;         +-------------------------+
+    ;  0xFF0  |  0xFF0 | BUSY           | BUSY flag cleared after CLRSSBSY
+    ;         +-------------------------+
+    ;  0xFF8  | 0xFD8|0x02|(LMA & CS.L) |
+    ;         +-------------------------+
+    ; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.
+    cmp     qword [ASM_PFX(mDoFarReturnFlag)], 0
+    jz      CetDone
+    cmp     qword [rbp + 8], PF_EXCEPTION   ; check if it is a Page Fault
+    jnz     CetDone
+    cmp     byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
+    jz      CetDone
+    mov     rax, cr4
+    and     rax, 0x800000       ; check if CET is enabled
+    jz      CetDone
+                                ; SSP should be 0xFD8 at this point
+    mov     rax, 0x04           ; advance past cs:lip:prevssp;supervisor shadow stack token
+    INCSSP_RAX                  ; After this SSP should be 0xFF8
+    SAVEPREVSSP                 ; now the shadow stack restore token will be created at 0xFD0
+    READSSP_RAX                 ; Read new SSP, SSP should be 0x1000
+    sub     rax, 0x10
+    CLRSSBSY_RAX                ; Clear token at 0xFF0, SSP should be 0 after this
+    sub     rax, 0x20
+    RSTORSSP_RAX                ; Restore to token at 0xFD0, new SSP will be 0xFD0
+    mov     rax, 0x01           ; Pop off the new save token created
+    INCSSP_RAX                  ; SSP should be 0xFD8 now
+CetDone:
+
     cli
 ;; UINT64  ExceptionData;
     add     rsp, 8
@@ -373,47 +414,7 @@ DoReturn:
     push    qword [rax + 0x18]       ; save EFLAGS in new location
     mov     rax, [rax]        ; restore rax
     popfq                     ; restore EFLAGS
-
-    ; The follow algorithm is used for clear shadow stack token busy bit.
-    ; The comment is based on the sample shadow stack.
-    ; The sample shadow stack layout :
-    ; Address | Context
-    ;         +-------------------------+
-    ;  0xFD0  |   FREE                  | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.
-    ;         +-------------------------+
-    ;  0xFD8  |  Prev SSP               |
-    ;         +-------------------------+
-    ;  0xFE0  |   RIP                   |
-    ;         +-------------------------+
-    ;  0xFE8  |   CS                    |
-    ;         +-------------------------+
-    ;  0xFF0  |  0xFF0 | BUSY           | BUSY flag cleared after CLRSSBSY
-    ;         +-------------------------+
-    ;  0xFF8  | 0xFD8|0x02|(LMA & CS.L) |
-    ;         +-------------------------+
-    ; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.
-    push     rax                ; SSP should be 0xFD8 at this point
-    cmp      byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
-    jz       CetDone
-    mov      rax, cr4
-    and      rax, 0x800000      ; check if CET is enabled
-    jz       CetDone
-    mov      rax, 0x04          ; advance past cs:lip:prevssp;supervisor shadow stack token
-    INCSSP_RAX                  ; After this SSP should be 0xFF8
-    SAVEPREVSSP                 ; now the shadow stack restore token will be created at 0xFD0
-    READSSP_RAX                 ; Read new SSP, SSP should be 0x1000
-    push     rax
-    sub      rax, 0x10
-    CLRSSBSY_RAX                ; Clear token at 0xFF0, SSP should be 0 after this
-    sub      rax, 0x20
-    RSTORSSP_RAX                ; Restore to token at 0xFD0, new SSP will be 0xFD0
-    pop      rax
-    mov      rax, 0x01          ; Pop off the new save token created
-    INCSSP_RAX                  ; SSP should be 0xFD8 now
-CetDone:
-    pop      rax                ; restore rax
-
-    DB       0x48               ; prefix to composite "retq" with next "retf"
+    DB      0x48                ; prefix to composite "retq" with next "retf"
     retf                        ; far return
 DoIret:
     iretq
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
index 661c1ba294..ca3f5ff91a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
@@ -202,7 +202,7 @@ InitShadowStack (
       // Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 for the full stack frame at runtime.
       //
       InterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64));
-      *(UINT32 *)(UINTN)InterruptSsp = (InterruptSsp - sizeof(UINT64) * 4) | 0x2;
+      *(UINT64 *)(UINTN)InterruptSsp = (InterruptSsp - sizeof(UINT64) * 4) | 0x2;
       mCetInterruptSsp = InterruptSsp - sizeof(UINT64);
 
       mCetInterruptSspTable = (UINT32)(UINTN)(mSmmInterruptSspTables + sizeof(UINT64) * 8 * CpuIndex);
-- 
2.16.2.windows.1


             reply	other threads:[~2021-07-02  5:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-02  5:28 Sheng Wei [this message]
2021-07-06  2:53 ` [PATCH] UefiCpuPkg/ExceptionLib: Conditionally clear shadow stack token busy bit Dong, Eric
2021-07-06  2:59   ` Sheng Wei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210702052840.15860-1-w.sheng@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox