]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/BaseLib: Add Shadow Stack Support for X86.
authorYao, Jiewen <jiewen.yao@intel.com>
Fri, 22 Feb 2019 13:30:34 +0000 (21:30 +0800)
committerLiming Gao <liming.gao@intel.com>
Thu, 28 Feb 2019 01:39:47 +0000 (09:39 +0800)
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: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yao Jiewen <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
MdePkg/Include/Library/BaseLib.h
MdePkg/Library/BaseLib/BaseLib.inf
MdePkg/Library/BaseLib/Ia32/LongJump.c
MdePkg/Library/BaseLib/Ia32/LongJump.nasm
MdePkg/Library/BaseLib/Ia32/SetJump.c
MdePkg/Library/BaseLib/Ia32/SetJump.nasm
MdePkg/Library/BaseLib/X64/LongJump.nasm
MdePkg/Library/BaseLib/X64/SetJump.nasm
MdePkg/MdePkg.dec

index 9c42f82a7d91366304eda8fb2c8a567bb824980a..616ba2e95b622c7ca311338d97d9d19bcd14fa5b 100644 (file)
@@ -31,6 +31,7 @@ typedef struct {
   UINT32                            Ebp;\r
   UINT32                            Esp;\r
   UINT32                            Eip;\r
+  UINT32                            Ssp;\r
 } BASE_LIBRARY_JUMP_BUFFER;\r
 \r
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4\r
@@ -54,6 +55,7 @@ typedef struct {
   UINT64                            Rip;\r
   UINT64                            MxCsr;\r
   UINT8                             XmmBuffer[160]; ///< XMM6-XMM15.\r
+  UINT64                            Ssp;\r
 } BASE_LIBRARY_JUMP_BUFFER;\r
 \r
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8\r
index f25a067a233586c444796a24bdc901822dda6f35..a0d6c372f997768a08522f816a153acee58a48a9 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Base Library implementation.\r
 #\r
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
 #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 #  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
 #\r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength      ## SOMETIMES_CONSUMES\r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength     ## SOMETIMES_CONSUMES\r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength   ## SOMETIMES_CONSUMES\r
+  gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask   ## SOMETIMES_CONSUMES\r
 \r
 [FeaturePcd]\r
   gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList  ## CONSUMES\r
index 73973a9cceae00092cd0e94bc2ff51dce020b530..2c1feb83735081da4129ccaae8decd4442125e72 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of _LongJump() on IA-32.\r
 \r
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -36,6 +36,32 @@ InternalLongJump (
   )\r
 {\r
   _asm {\r
+    mov     eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    _emit      0x0F\r
+    _emit      0x20\r
+    _emit      0xE0                ; mov     eax, cr4\r
+    bt      eax, 23                ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    mov     edx, [esp + 4]         ; edx = JumpBuffer\r
+    mov     edx, [edx + 24]        ; edx = target SSP\r
+    _emit      0xF3\r
+    _emit      0x0F\r
+    _emit      0x1E\r
+    _emit      0xC8                ; READSSP EAX\r
+    sub     edx, eax               ; edx = delta\r
+    mov     eax, edx               ; eax = delta\r
+\r
+    shr     eax, 2                 ; eax = delta/sizeof(UINT32)\r
+    _emit      0xF3\r
+    _emit      0x0F\r
+    _emit      0xAE\r
+    _emit      0xE8                ; INCSSP EAX\r
+\r
+CetDone:\r
+\r
     pop     eax                         ; skip return address\r
     pop     edx                         ; edx <- JumpBuffer\r
     pop     eax                         ; eax <- Value\r
index 7ef03462eed35401a5341e93b34678db4b59528c..57305d4981f40c201624d43d6e06acb62b11eaf2 100644 (file)
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------\r
 ;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
 ;\r
 ;------------------------------------------------------------------------------\r
 \r
+%include "Nasm.inc"\r
+\r
     SECTION .text\r
 \r
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))\r
+\r
 ;------------------------------------------------------------------------------\r
 ; VOID\r
 ; EFIAPI\r
 ;------------------------------------------------------------------------------\r
 global ASM_PFX(InternalLongJump)\r
 ASM_PFX(InternalLongJump):\r
+\r
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    mov     eax, cr4\r
+    bt      eax, 23                ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    mov     edx, [esp + 4]         ; edx = JumpBuffer\r
+    mov     edx, [edx + 24]        ; edx = target SSP\r
+    READSSP_EAX\r
+    sub     edx, eax               ; edx = delta\r
+    mov     eax, edx               ; eax = delta\r
+\r
+    shr     eax, 2                 ; eax = delta/sizeof(UINT32)\r
+    INCSSP_EAX\r
+\r
+CetDone:\r
+\r
     pop     eax                         ; skip return address\r
     pop     edx                         ; edx <- JumpBuffer\r
     pop     eax                         ; eax <- Value\r
index 652d45d53ba749d4319c6c0394a4cc9c6220e443..d608fd9ccb1fb4d354f3d8542acc18f3c1f6f52c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of SetJump() on IA-32.\r
 \r
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -62,6 +62,32 @@ SetJump (
     pop     ecx\r
     pop     ecx\r
     mov     edx, [esp]\r
+\r
+    xor     eax, eax\r
+    mov     [edx + 24], eax        ; save 0 to SSP\r
+\r
+    mov     eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    _emit      0x0F\r
+    _emit      0x20\r
+    _emit      0xE0                ; mov     eax, cr4\r
+    bt      eax, 23                ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    mov     eax, 1\r
+    _emit      0xF3\r
+    _emit      0x0F\r
+    _emit      0xAE\r
+    _emit      0xE8                ; INCSSP EAX to read original SSP\r
+    _emit      0xF3\r
+    _emit      0x0F\r
+    _emit      0x1E\r
+    _emit      0xC8                ; READSSP EAX\r
+    mov     [edx + 0x24], eax      ; save SSP\r
+\r
+CetDone:\r
+\r
     mov     [edx], ebx\r
     mov     [edx + 4], esi\r
     mov     [edx + 8], edi\r
index 6d3a5a25bb708556756f9ecf2285912d2f48a81d..840fed61c74d10dda4b39d2c5b6c03b2286269eb 100644 (file)
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------\r
 ;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
 ;\r
 ;------------------------------------------------------------------------------\r
 \r
+%include "Nasm.inc"\r
+\r
     SECTION .text\r
 \r
 extern ASM_PFX(InternalAssertJumpBuffer)\r
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))\r
 \r
 ;------------------------------------------------------------------------------\r
 ; UINTN\r
@@ -37,6 +40,24 @@ ASM_PFX(SetJump):
     pop     ecx\r
     pop     ecx                         ; ecx <- return address\r
     mov     edx, [esp]\r
+\r
+    xor     eax, eax\r
+    mov     [edx + 24], eax        ; save 0 to SSP\r
+\r
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    mov     eax, cr4\r
+    bt      eax, 23                ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    mov     eax, 1\r
+    INCSSP_EAX                     ; to read original SSP\r
+    READSSP_EAX\r
+    mov     [edx + 0x24], eax      ; save SSP\r
+\r
+CetDone:\r
+\r
     mov     [edx], ebx\r
     mov     [edx + 4], esi\r
     mov     [edx + 8], edi\r
index 3bac27469e3a8f1108c218807e1ef986318e604e..2b38ef0b25e39051b14d00b05a15bb0cf1001d04 100644 (file)
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------\r
 ;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
 ;\r
 ;------------------------------------------------------------------------------\r
 \r
+%include "Nasm.inc"\r
+\r
     DEFAULT REL\r
     SECTION .text\r
 \r
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))\r
+\r
 ;------------------------------------------------------------------------------\r
 ; VOID\r
 ; EFIAPI\r
 ;------------------------------------------------------------------------------\r
 global ASM_PFX(InternalLongJump)\r
 ASM_PFX(InternalLongJump):\r
+\r
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    mov     rax, cr4\r
+    bt      eax, 23                      ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    push    rdx                          ; save rdx\r
+\r
+    mov     rdx, [rcx + 0xF8]            ; rdx = target SSP\r
+    READSSP_RAX\r
+    sub     rdx, rax                     ; rdx = delta\r
+    mov     rax, rdx                     ; rax = delta\r
+\r
+    shr     rax, 3                       ; rax = delta/sizeof(UINT64)\r
+    INCSSP_RAX\r
+\r
+    pop     rdx                          ; restore rdx\r
+CetDone:\r
+\r
     mov     rbx, [rcx]\r
     mov     rsp, [rcx + 8]\r
     mov     rbp, [rcx + 0x10]\r
index b1d0ff712135408b71b3750fd21a5079e41aaee6..b491df896d9ccf41d87308a8e2ed917eaf95318c 100644 (file)
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------\r
 ;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
 ;\r
 ;------------------------------------------------------------------------------\r
 \r
+%include "Nasm.inc"\r
+\r
     DEFAULT REL\r
     SECTION .text\r
 \r
 extern ASM_PFX(InternalAssertJumpBuffer)\r
+extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))\r
 \r
 ;------------------------------------------------------------------------------\r
 ; UINTN\r
@@ -39,6 +42,24 @@ ASM_PFX(SetJump):
     add     rsp, 0x20\r
     pop     rcx\r
     pop     rdx\r
+\r
+    xor     rax, rax\r
+    mov     [rcx + 0xF8], rax            ; save 0 to SSP\r
+\r
+    mov     eax, [ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))]\r
+    test    eax, eax\r
+    jz      CetDone\r
+    mov     rax, cr4\r
+    bt      eax, 23                      ; check if CET is enabled\r
+    jnc     CetDone\r
+\r
+    mov     rax, 1\r
+    INCSSP_RAX                           ; to read original SSP\r
+    READSSP_RAX\r
+    mov     [rcx + 0xF8], rax            ; save SSP\r
+\r
+CetDone:\r
+\r
     mov     [rcx], rbx\r
     mov     [rcx + 8], rsp\r
     mov     [rcx + 0x10], rbp\r
index c859b4a511695de0df4d87c4c4263e0df1a321e2..69a9575a04d105166a271b984e4ca91ca07ad068 100644 (file)
   # @Prompt Fixed Debug Message Print Level.\r
   gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0xFFFFFFFF|UINT32|0x30001016\r
 \r
+  ## Indicates the control flow enforcement enabling state.\r
+  #  If enabled, it uses control flow enforcement technology to prevent ROP or JOP.<BR><BR>\r
+  #   BIT0 - SMM CET Shadow Stack is enabled.<BR>\r
+  #   Other - reserved\r
+  # @Prompt Enable control flow enforcement.\r
+  gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x0|UINT32|0x30001017\r
+\r
 [PcdsFixedAtBuild,PcdsPatchableInModule]\r
   ## Indicates the maximum length of unicode string used in the following\r
   #  BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()<BR><BR>\r