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

This patch adds SSP - shadow stack pointer to JumpBuffer.
It will be used for the platform that enabled CET/ShadowStack.

We add gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask
to control the global enable/disable.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ray Ni <ray...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yao Jiewen <jiewen....@intel.com>
---
 MdePkg/Include/Library/BaseLib.h          |  2 ++
 MdePkg/Library/BaseLib/BaseLib.inf        |  3 ++-
 MdePkg/Library/BaseLib/Ia32/LongJump.c    | 28 +++++++++++++++++++-
 MdePkg/Library/BaseLib/Ia32/LongJump.nasm | 23 +++++++++++++++-
 MdePkg/Library/BaseLib/Ia32/SetJump.c     | 28 +++++++++++++++++++-
 MdePkg/Library/BaseLib/Ia32/SetJump.nasm  | 21 ++++++++++++++-
 MdePkg/Library/BaseLib/X64/LongJump.nasm  | 25 ++++++++++++++++-
 MdePkg/Library/BaseLib/X64/SetJump.nasm   | 21 ++++++++++++++-
 MdePkg/MdePkg.dec                         |  7 +++++
 9 files changed, 151 insertions(+), 7 deletions(-)

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 9c42f82a7d..616ba2e95b 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -31,6 +31,7 @@ typedef struct {
   UINT32                            Ebp;
   UINT32                            Esp;
   UINT32                            Eip;
+  UINT32                            Ssp;
 } BASE_LIBRARY_JUMP_BUFFER;
 
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4
@@ -54,6 +55,7 @@ typedef struct {
   UINT64                            Rip;
   UINT64                            MxCsr;
   UINT8                             XmmBuffer[160]; ///< XMM6-XMM15.
+  UINT64                            Ssp;
 } BASE_LIBRARY_JUMP_BUFFER;
 
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf 
b/MdePkg/Library/BaseLib/BaseLib.inf
index f25a067a23..a0d6c372f9 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Base Library implementation.
 #
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
 #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 #  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 #
@@ -620,6 +620,7 @@
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength      ## 
SOMETIMES_CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength     ## 
SOMETIMES_CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength   ## 
SOMETIMES_CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask   ## 
SOMETIMES_CONSUMES
 
 [FeaturePcd]
   gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList  ## CONSUMES
diff --git a/MdePkg/Library/BaseLib/Ia32/LongJump.c 
b/MdePkg/Library/BaseLib/Ia32/LongJump.c
index 73973a9cce..2c1feb8373 100644
--- a/MdePkg/Library/BaseLib/Ia32/LongJump.c
+++ b/MdePkg/Library/BaseLib/Ia32/LongJump.c
@@ -1,7 +1,7 @@
 /** @file
   Implementation of _LongJump() on IA-32.
 
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD 
License
   which accompanies this distribution.  The full text of the license may be 
found at
@@ -36,6 +36,32 @@ InternalLongJump (
   )
 {
   _asm {
+    mov     eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]
+    test    eax, eax
+    jz      CetDone
+    _emit      0x0F
+    _emit      0x20
+    _emit      0xE0                ; mov     eax, cr4
+    bt      eax, 23                ; check if CET is enabled
+    jnc     CetDone
+
+    mov     edx, [esp + 4]         ; edx = JumpBuffer
+    mov     edx, [edx + 24]        ; edx = target SSP
+    _emit      0xF3
+    _emit      0x0F
+    _emit      0x1E
+    _emit      0xC8                ; READSSP EAX
+    sub     edx, eax               ; edx = delta
+    mov     eax, edx               ; eax = delta
+
+    shr     eax, 2                 ; eax = delta/sizeof(UINT32)
+    _emit      0xF3
+    _emit      0x0F
+    _emit      0xAE
+    _emit      0xE8                ; INCSSP EAX
+
+CetDone:
+
     pop     eax                         ; skip return address
     pop     edx                         ; edx <- JumpBuffer
     pop     eax                         ; eax <- Value
diff --git a/MdePkg/Library/BaseLib/Ia32/LongJump.nasm 
b/MdePkg/Library/BaseLib/Ia32/LongJump.nasm
index 7ef03462ee..1e806fb635 100644
--- a/MdePkg/Library/BaseLib/Ia32/LongJump.nasm
+++ b/MdePkg/Library/BaseLib/Ia32/LongJump.nasm
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------
 ;
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 ; This program and the accompanying materials
 ; are licensed and made available under the terms and conditions of the BSD 
License
 ; which accompanies this distribution.  The full text of the license may be 
found at
@@ -21,6 +21,8 @@
 
     SECTION .text
 
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
+
 ;------------------------------------------------------------------------------
 ; VOID
 ; EFIAPI
@@ -31,6 +33,25 @@
 ;------------------------------------------------------------------------------
 global ASM_PFX(InternalLongJump)
 ASM_PFX(InternalLongJump):
+
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]
+    test    eax, eax
+    jz      CetDone
+    mov     eax, cr4
+    bt      eax, 23                ; check if CET is enabled
+    jnc     CetDone
+
+    mov     edx, [esp + 4]         ; edx = JumpBuffer
+    mov     edx, [edx + 24]        ; edx = target SSP
+    DB      0xF3, 0x0F, 0x1E, 0xC8 ; READSSP EAX
+    sub     edx, eax               ; edx = delta
+    mov     eax, edx               ; eax = delta
+
+    shr     eax, 2                 ; eax = delta/sizeof(UINT32)
+    DB      0xF3, 0x0F, 0xAE, 0xE8 ; INCSSP EAX
+
+CetDone:
+
     pop     eax                         ; skip return address
     pop     edx                         ; edx <- JumpBuffer
     pop     eax                         ; eax <- Value
diff --git a/MdePkg/Library/BaseLib/Ia32/SetJump.c 
b/MdePkg/Library/BaseLib/Ia32/SetJump.c
index 652d45d53b..d608fd9ccb 100644
--- a/MdePkg/Library/BaseLib/Ia32/SetJump.c
+++ b/MdePkg/Library/BaseLib/Ia32/SetJump.c
@@ -1,7 +1,7 @@
 /** @file
   Implementation of SetJump() on IA-32.
 
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD 
License
   which accompanies this distribution.  The full text of the license may be 
found at
@@ -62,6 +62,32 @@ SetJump (
     pop     ecx
     pop     ecx
     mov     edx, [esp]
+
+    xor     eax, eax
+    mov     [edx + 24], eax        ; save 0 to SSP
+
+    mov     eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]
+    test    eax, eax
+    jz      CetDone
+    _emit      0x0F
+    _emit      0x20
+    _emit      0xE0                ; mov     eax, cr4
+    bt      eax, 23                ; check if CET is enabled
+    jnc     CetDone
+
+    mov     eax, 1
+    _emit      0xF3
+    _emit      0x0F
+    _emit      0xAE
+    _emit      0xE8                ; INCSSP EAX to read original SSP
+    _emit      0xF3
+    _emit      0x0F
+    _emit      0x1E
+    _emit      0xC8                ; READSSP EAX
+    mov     [edx + 0x24], eax      ; save SSP
+
+CetDone:
+
     mov     [edx], ebx
     mov     [edx + 4], esi
     mov     [edx + 8], edi
diff --git a/MdePkg/Library/BaseLib/Ia32/SetJump.nasm 
b/MdePkg/Library/BaseLib/Ia32/SetJump.nasm
index 6d3a5a25bb..95d7247050 100644
--- a/MdePkg/Library/BaseLib/Ia32/SetJump.nasm
+++ b/MdePkg/Library/BaseLib/Ia32/SetJump.nasm
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------
 ;
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 ; This program and the accompanying materials
 ; are licensed and made available under the terms and conditions of the BSD 
License
 ; which accompanies this distribution.  The full text of the license may be 
found at
@@ -22,6 +22,7 @@
     SECTION .text
 
 extern ASM_PFX(InternalAssertJumpBuffer)
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
 
 ;------------------------------------------------------------------------------
 ; UINTN
@@ -37,6 +38,24 @@ ASM_PFX(SetJump):
     pop     ecx
     pop     ecx                         ; ecx <- return address
     mov     edx, [esp]
+
+    xor     eax, eax
+    mov     [edx + 24], eax        ; save 0 to SSP
+
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]
+    test    eax, eax
+    jz      CetDone
+    mov     eax, cr4
+    bt      eax, 23                ; check if CET is enabled
+    jnc     CetDone
+
+    mov     eax, 1
+    DB      0xF3, 0x0F, 0xAE, 0xE8 ; INCSSP EAX to read original SSP
+    DB      0xF3, 0x0F, 0x1E, 0xC8 ; READSSP EAX
+    mov     [edx + 0x24], eax      ; save SSP
+
+CetDone:
+
     mov     [edx], ebx
     mov     [edx + 4], esi
     mov     [edx + 8], edi
diff --git a/MdePkg/Library/BaseLib/X64/LongJump.nasm 
b/MdePkg/Library/BaseLib/X64/LongJump.nasm
index 3bac27469e..87a54a59f7 100644
--- a/MdePkg/Library/BaseLib/X64/LongJump.nasm
+++ b/MdePkg/Library/BaseLib/X64/LongJump.nasm
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------
 ;
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 ; This program and the accompanying materials
 ; are licensed and made available under the terms and conditions of the BSD 
License
 ; which accompanies this distribution.  The full text of the license may be 
found at
@@ -22,6 +22,8 @@
     DEFAULT REL
     SECTION .text
 
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
+
 ;------------------------------------------------------------------------------
 ; VOID
 ; EFIAPI
@@ -32,6 +34,27 @@
 ;------------------------------------------------------------------------------
 global ASM_PFX(InternalLongJump)
 ASM_PFX(InternalLongJump):
+
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]
+    test    eax, eax
+    jz      CetDone
+    mov     rax, cr4
+    bt      eax, 23                      ; check if CET is enabled
+    jnc     CetDone
+
+    push    rdx                          ; save rdx
+
+    mov     rdx, [rcx + 0xF8]            ; rdx = target SSP
+    DB      0xF3, 0x48, 0x0F, 0x1E, 0xC8 ; READSSP RAX
+    sub     rdx, rax                     ; rdx = delta
+    mov     rax, rdx                     ; rax = delta
+
+    shr     rax, 3                       ; rax = delta/sizeof(UINT64)
+    DB      0xF3, 0x48, 0x0F, 0xAE, 0xE8 ; INCSSP RAX
+
+    pop     rdx                          ; restore rdx
+CetDone:
+
     mov     rbx, [rcx]
     mov     rsp, [rcx + 8]
     mov     rbp, [rcx + 0x10]
diff --git a/MdePkg/Library/BaseLib/X64/SetJump.nasm 
b/MdePkg/Library/BaseLib/X64/SetJump.nasm
index b1d0ff7121..b478327b95 100644
--- a/MdePkg/Library/BaseLib/X64/SetJump.nasm
+++ b/MdePkg/Library/BaseLib/X64/SetJump.nasm
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------
 ;
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 ; This program and the accompanying materials
 ; are licensed and made available under the terms and conditions of the BSD 
License
 ; which accompanies this distribution.  The full text of the license may be 
found at
@@ -23,6 +23,7 @@
     SECTION .text
 
 extern ASM_PFX(InternalAssertJumpBuffer)
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
 
 ;------------------------------------------------------------------------------
 ; UINTN
@@ -39,6 +40,24 @@ ASM_PFX(SetJump):
     add     rsp, 0x20
     pop     rcx
     pop     rdx
+
+    xor     rax, rax
+    mov     [rcx + 0xF8], rax            ; save 0 to SSP
+
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]
+    test    eax, eax
+    jz      CetDone
+    mov     rax, cr4
+    bt      eax, 23                      ; check if CET is enabled
+    jnc     CetDone
+
+    mov     rax, 1
+    DB      0xF3, 0x48, 0x0F, 0xAE, 0xE8 ; INCSSP RAX to read original SSP
+    DB      0xF3, 0x48, 0x0F, 0x1E, 0xC8 ; READSSP RAX
+    mov     [rcx + 0xF8], rax            ; save SSP
+
+CetDone:
+
     mov     [rcx], rbx
     mov     [rcx + 8], rsp
     mov     [rcx + 0x10], rbp
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index c859b4a511..69a9575a04 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -2087,6 +2087,13 @@
   # @Prompt Fixed Debug Message Print Level.
   
gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0xFFFFFFFF|UINT32|0x30001016
 
+  ## Indicates the control flow enforcement enabling state.
+  #  If enabled, it uses control flow enforcement technology to prevent ROP or 
JOP.<BR><BR>
+  #   BIT0 - SMM CET Shadow Stack is enabled.<BR>
+  #   Other - reserved
+  # @Prompt Enable control flow enforcement.
+  
gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x0|UINT32|0x30001017
+
 [PcdsFixedAtBuild,PcdsPatchableInModule]
   ## Indicates the maximum length of unicode string used in the following
   #  BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), 
StrnCpy()<BR><BR>
-- 
2.19.2.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to