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: 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>
This commit is contained in:
Yao, Jiewen 2019-02-22 21:30:34 +08:00 committed by Liming Gao
parent 68edd7dbad
commit 0aac2f777a
9 changed files with 159 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
@ -19,8 +19,12 @@
;
;------------------------------------------------------------------------------
%include "Nasm.inc"
SECTION .text
extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
;------------------------------------------------------------------------------
; VOID
; EFIAPI
@ -31,6 +35,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
READSSP_EAX
sub edx, eax ; edx = delta
mov eax, edx ; eax = delta
shr eax, 2 ; eax = delta/sizeof(UINT32)
INCSSP_EAX
CetDone:
pop eax ; skip return address
pop edx ; edx <- JumpBuffer
pop eax ; eax <- Value

View File

@ -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

View File

@ -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
@ -19,9 +19,12 @@
;
;------------------------------------------------------------------------------
%include "Nasm.inc"
SECTION .text
extern ASM_PFX(InternalAssertJumpBuffer)
extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
;------------------------------------------------------------------------------
; UINTN
@ -37,6 +40,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
INCSSP_EAX ; to read original SSP
READSSP_EAX
mov [edx + 0x24], eax ; save SSP
CetDone:
mov [edx], ebx
mov [edx + 4], esi
mov [edx + 8], edi

View File

@ -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
@ -19,9 +19,13 @@
;
;------------------------------------------------------------------------------
%include "Nasm.inc"
DEFAULT REL
SECTION .text
extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
;------------------------------------------------------------------------------
; VOID
; EFIAPI
@ -32,6 +36,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
READSSP_RAX
sub rdx, rax ; rdx = delta
mov rax, rdx ; rax = delta
shr rax, 3 ; rax = delta/sizeof(UINT64)
INCSSP_RAX
pop rdx ; restore rdx
CetDone:
mov rbx, [rcx]
mov rsp, [rcx + 8]
mov rbp, [rcx + 0x10]

View File

@ -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
@ -19,10 +19,13 @@
;
;------------------------------------------------------------------------------
%include "Nasm.inc"
DEFAULT REL
SECTION .text
extern ASM_PFX(InternalAssertJumpBuffer)
extern ASM_PFX(PcdGet32 (PcdControlFlowEnforcementPropertyMask))
;------------------------------------------------------------------------------
; UINTN
@ -39,6 +42,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
INCSSP_RAX ; to read original SSP
READSSP_RAX
mov [rcx + 0xF8], rax ; save SSP
CetDone:
mov [rcx], rbx
mov [rcx + 8], rsp
mov [rcx + 0x10], rbp

View File

@ -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>