Reviewed-by: Ray Ni <ray...@intel.com>

> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, February 22, 2019 7:00 PM
> To: edk2-devel@lists.01.org
> Cc: Dong, Eric <eric.d...@intel.com>; Ni, Ray <ray...@intel.com>; Laszlo Ersek
> <ler...@redhat.com>; Yao, Jiewen <jiewen....@intel.com>
> Subject: [PATCH V2 1/3] MdePkg/BaseLib: Add Shadow Stack Support for X86.
> 
> 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|UI
> N
> + T32|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