summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2019-02-22 21:30:36 +0800
committerLiming Gao <liming.gao@intel.com>2019-02-28 09:39:54 +0800
commit3eb69b081c683f9d825930d0c511e43c0485e5d2 (patch)
tree9d89e793207e6e82c98d09b20c12a8b7a728f1b4 /UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
parent0d25074cbcc272532d6ca5a47974ac5b31f4b6ec (diff)
downloadedk2-3eb69b081c683f9d825930d0c511e43c0485e5d2.tar.gz
edk2-3eb69b081c683f9d825930d0c511e43c0485e5d2.tar.bz2
edk2-3eb69b081c683f9d825930d0c511e43c0485e5d2.zip
UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1521 We scan the SMM code with ROPgadget. http://shell-storm.org/project/ROPgadget/ https://github.com/JonathanSalwan/ROPgadget/tree/master This tool reports the gadget in SMM driver. This patch enabled CET ShadowStack for X86 SMM. If CET is supported, SMM will enable CET ShadowStack. SMM CET will save the OS CET context at SmmEntry and restore OS CET context at SmmExit. Test: 1) test Intel internal platform (x64 only, CET enabled/disabled) Boot test: CET supported or not supported CPU on CET supported platform CET enabled/disabled PcdCpuSmmCetEnable enabled/disabled Single core/Multiple core PcdCpuSmmStackGuard enabled/disabled PcdCpuSmmProfileEnable enabled/disabled PcdCpuSmmStaticPageTable enabled/disabled CET exception test: #CF generated with PcdCpuSmmStackGuard enabled/disabled. Other exception test: #PF for normal stack overflow #PF for NX protection #PF for RO protection CET env test: Launch SMM in CET enabled/disabled environment (DXE) - no impact to DXE The test case can be found at https://github.com/jyao1/SecurityEx/tree/master/ControlFlowPkg 2) test ovmf (both IA32 and X64 SMM, CET disabled only) test OvmfIa32/Ovmf3264, with -D SMM_REQUIRE. qemu-system-x86_64.exe -machine q35,smm=on -smp 4 -serial file:serial.log -drive if=pflash,format=raw,unit=0,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=OVMF_VARS.fd QEMU emulator version 3.1.0 (v3.1.0-11736-g7a30e7adb0-dirty) 3) not tested IA32 CET enabled platform 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>
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm99
1 files changed, 94 insertions, 5 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
index 3791cfa144..101215b389 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
@@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
-; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2016 - 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,6 +19,20 @@
;-------------------------------------------------------------------------------
%include "StuffRsbNasm.inc"
+%include "Nasm.inc"
+
+%define MSR_IA32_S_CET 0x6A2
+%define MSR_IA32_CET_SH_STK_EN 0x1
+%define MSR_IA32_CET_WR_SHSTK_EN 0x2
+%define MSR_IA32_CET_ENDBR_EN 0x4
+%define MSR_IA32_CET_LEG_IW_EN 0x8
+%define MSR_IA32_CET_NO_TRACK_EN 0x10
+%define MSR_IA32_CET_SUPPRESS_DIS 0x20
+%define MSR_IA32_CET_SUPPRESS 0x400
+%define MSR_IA32_CET_TRACKER 0x800
+%define MSR_IA32_PL0_SSP 0x6A4
+
+%define CR4_CET 0x800000
%define MSR_IA32_MISC_ENABLE 0x1A0
%define MSR_EFER 0xc0000080
@@ -53,6 +67,11 @@ extern ASM_PFX(mXdSupported)
global ASM_PFX(gPatchXdSupported)
extern ASM_PFX(gSmiHandlerIdtr)
+extern ASM_PFX(mCetSupported)
+global ASM_PFX(mPatchCetSupported)
+global ASM_PFX(mPatchCetPl0Ssp)
+global ASM_PFX(mPatchCetInterruptSsp)
+
SECTION .text
BITS 16
@@ -173,11 +192,61 @@ ASM_PFX(gPatchXdSupported):
mov ax, [ebx + DSC_SS]
mov ss, eax
-; jmp _SmiHandler ; instruction is not needed
+ mov ebx, [esp + 4] ; ebx <- CpuIndex
+
+; enable CET if supported
+ mov al, strict byte 1 ; source operand may be patched
+ASM_PFX(mPatchCetSupported):
+ cmp al, 0
+ jz CetDone
+
+ mov ecx, MSR_IA32_S_CET
+ rdmsr
+ push edx
+ push eax
+
+ mov ecx, MSR_IA32_PL0_SSP
+ rdmsr
+ push edx
+ push eax
+
+ mov ecx, MSR_IA32_S_CET
+ mov eax, MSR_IA32_CET_SH_STK_EN
+ xor edx, edx
+ wrmsr
+
+ mov ecx, MSR_IA32_PL0_SSP
+ mov eax, strict dword 0 ; source operand will be patched
+ASM_PFX(mPatchCetPl0Ssp):
+ xor edx, edx
+ wrmsr
+ mov ecx, cr0
+ btr ecx, 16 ; clear WP
+ mov cr0, ecx
+ mov [eax], eax ; reload SSP, and clear busyflag.
+ xor ecx, ecx
+ mov [eax + 4], ecx
+
+ mov eax, strict dword 0 ; source operand will be patched
+ASM_PFX(mPatchCetInterruptSsp):
+ cmp eax, 0
+ jz CetInterruptDone
+ mov [eax], eax ; reload SSP, and clear busyflag.
+ xor ecx, ecx
+ mov [eax + 4], ecx
+CetInterruptDone:
+
+ mov ecx, cr0
+ bts ecx, 16 ; set WP
+ mov cr0, ecx
+
+ mov eax, 0x668 | CR4_CET
+ mov cr4, eax
+
+ SETSSBSY
+
+CetDone:
-global ASM_PFX(SmiHandler)
-ASM_PFX(SmiHandler):
- mov ebx, [esp + 4] ; CPU Index
push ebx
mov eax, ASM_PFX(CpuSmmDebugEntry)
call eax
@@ -193,6 +262,25 @@ ASM_PFX(SmiHandler):
call eax
add esp, 4
+ mov eax, ASM_PFX(mCetSupported)
+ mov al, [eax]
+ cmp al, 0
+ jz CetDone2
+
+ mov eax, 0x668
+ mov cr4, eax ; disable CET
+
+ mov ecx, MSR_IA32_PL0_SSP
+ pop eax
+ pop edx
+ wrmsr
+
+ mov ecx, MSR_IA32_S_CET
+ pop eax
+ pop edx
+ wrmsr
+CetDone2:
+
mov eax, ASM_PFX(mXdSupported)
mov al, [eax]
cmp al, 0
@@ -206,6 +294,7 @@ ASM_PFX(SmiHandler):
wrmsr
.7:
+
StuffRsb32
rsm