summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/PiSmmCpuDxeSmm/X64/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/X64/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/X64/SmiEntry.nasm')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm120
1 files changed, 117 insertions, 3 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm
index 807b309b27..73febcea63 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/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,11 +19,26 @@
;-------------------------------------------------------------------------------
%include "StuffRsbNasm.inc"
+%include "Nasm.inc"
;
; Variables referrenced by C code
;
+%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 MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
+
+%define CR4_CET 0x800000
+
%define MSR_IA32_MISC_ENABLE 0x1A0
%define MSR_EFER 0xc0000080
%define MSR_EFER_XD 0x800
@@ -63,6 +78,12 @@ global ASM_PFX(gPatchSmiCr3)
global ASM_PFX(gcSmiHandlerTemplate)
global ASM_PFX(gcSmiHandlerSize)
+extern ASM_PFX(mCetSupported)
+global ASM_PFX(mPatchCetSupported)
+global ASM_PFX(mPatchCetPl0Ssp)
+global ASM_PFX(mPatchCetInterruptSsp)
+global ASM_PFX(mPatchCetInterruptSspTable)
+
DEFAULT REL
SECTION .text
@@ -174,8 +195,71 @@ SmiHandlerIdtrAbsAddr:
mov ax, [rbx + DSC_SS]
mov ss, eax
-_SmiHandler:
- mov rbx, [rsp + 0x8] ; rcx <- CpuIndex
+ mov rbx, [rsp + 0x8] ; rbx <- 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 rdx
+ push rax
+
+ mov ecx, MSR_IA32_PL0_SSP
+ rdmsr
+ push rdx
+ push rax
+
+ mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
+ rdmsr
+ push rdx
+ push rax
+
+ 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 rcx, cr0
+ btr ecx, 16 ; clear WP
+ mov cr0, rcx
+ mov [eax], eax ; reload SSP, and clear busyflag.
+ xor ecx, ecx
+ mov [eax + 4], ecx
+
+ mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
+ mov eax, strict dword 0 ; source operand will be patched
+ASM_PFX(mPatchCetInterruptSspTable):
+ xor edx, edx
+ wrmsr
+
+ 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 rcx, cr0
+ bts ecx, 16 ; set WP
+ mov cr0, rcx
+
+ mov eax, 0x668 | CR4_CET
+ mov cr4, rax
+
+ SETSSBSY
+
+CetDone:
;
; Save FP registers
@@ -209,6 +293,31 @@ CpuSmmDebugExitAbsAddr:
add rsp, 0x200
+ mov rax, strict qword 0 ; mov rax, ASM_PFX(mCetSupported)
+mCetSupportedAbsAddr:
+ mov al, [rax]
+ cmp al, 0
+ jz CetDone2
+
+ mov eax, 0x668
+ mov cr4, rax ; disable CET
+
+ mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
+ pop rax
+ pop rdx
+ wrmsr
+
+ mov ecx, MSR_IA32_PL0_SSP
+ pop rax
+ pop rdx
+ wrmsr
+
+ mov ecx, MSR_IA32_S_CET
+ pop rax
+ pop rdx
+ wrmsr
+CetDone2:
+
mov rax, strict qword 0 ; lea rax, [ASM_PFX(mXdSupported)]
mXdSupportedAbsAddr:
mov al, [rax]
@@ -223,6 +332,7 @@ mXdSupportedAbsAddr:
wrmsr
.1:
+
StuffRsb64
rsm
@@ -257,4 +367,8 @@ ASM_PFX(PiSmmCpuSmiEntryFixupAddress):
lea rax, [ASM_PFX(mXdSupported)]
lea rcx, [mXdSupportedAbsAddr]
mov qword [rcx - 8], rax
+
+ lea rax, [ASM_PFX(mCetSupported)]
+ lea rcx, [mCetSupportedAbsAddr]
+ mov qword [rcx - 8], rax
ret