summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
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/PiSmmCpuDxeSmm.h
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/PiSmmCpuDxeSmm.h')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h103
1 files changed, 99 insertions, 4 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index 61d4bd3085..84efb22981 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -1,7 +1,7 @@
/** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
This program and the accompanying materials
@@ -65,6 +65,51 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "SmmProfile.h"
//
+// CET definition
+//
+#define CPUID_CET_SS BIT7
+#define CPUID_CET_IBT BIT20
+
+#define CR4_CET_ENABLE BIT23
+
+#define MSR_IA32_S_CET 0x6A2
+#define MSR_IA32_PL0_SSP 0x6A4
+#define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
+
+typedef union {
+ struct {
+ // enable shadow stacks
+ UINT32 SH_STK_ENP:1;
+ // enable the WRSS{D,Q}W instructions.
+ UINT32 WR_SHSTK_EN:1;
+ // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.
+ UINT32 ENDBR_EN:1;
+ // enable legacy compatibility treatment for indirect call/jmp tracking.
+ UINT32 LEG_IW_EN:1;
+ // enable use of no-track prefix on indirect call/jmp.
+ UINT32 NO_TRACK_EN:1;
+ // disable suppression of CET indirect branch tracking on legacy compatibility.
+ UINT32 SUPPRESS_DIS:1;
+ UINT32 RSVD:4;
+ // indirect branch tracking is suppressed.
+ // This bit can be written to 1 only if TRACKER is written as IDLE.
+ UINT32 SUPPRESS:1;
+ // Value of the endbranch state machine
+ // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).
+ UINT32 TRACKER:1;
+ // linear address of a bitmap in memory indicating valid
+ // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled
+ // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on
+ // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are
+ // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address
+ // (this automatically aligns the address on a 4-Kbyte boundary).
+ UINT32 EB_LEG_BITMAP_BASE_low:12;
+ UINT32 EB_LEG_BITMAP_BASE_high:32;
+ } Bits;
+ UINT64 Uint64;
+} MSR_IA32_CET;
+
+//
// MSRs required for configuration of SMM Code Access Check
//
#define EFI_MSR_SMM_MCA_CAP 0x17D
@@ -127,9 +172,11 @@ typedef struct {
// Size of Task-State Segment defined in IA32 Manual
//
#define TSS_SIZE 104
+#define EXCEPTION_TSS_SIZE (TSS_SIZE + 4) // Add 4 bytes SSP
#define TSS_X64_IST1_OFFSET 36
#define TSS_IA32_CR3_OFFSET 28
#define TSS_IA32_ESP_OFFSET 56
+#define TSS_IA32_SSP_OFFSET 104
#define CR0_WP BIT16
@@ -305,6 +352,8 @@ X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3;
extern UINT32 mSmmCr4;
X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4;
X86_ASSEMBLY_PATCH_LABEL gPatchSmmInitStack;
+X86_ASSEMBLY_PATCH_LABEL mPatchCetSupported;
+extern BOOLEAN mCetSupported;
/**
Semaphore operation for all processor relocate SMMBase.
@@ -418,14 +467,16 @@ Gen4GPageTable (
/**
Initialize global data for MP synchronization.
- @param Stacks Base address of SMI stack buffer for all processors.
- @param StackSize Stack size for each processor in SMM.
+ @param Stacks Base address of SMI stack buffer for all processors.
+ @param StackSize Stack size for each processor in SMM.
+ @param ShadowStackSize Shadow Stack size for each processor in SMM.
**/
UINT32
InitializeMpServiceData (
IN VOID *Stacks,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN UINTN ShadowStackSize
);
/**
@@ -1037,6 +1088,50 @@ TransferApToSafeState (
);
/**
+ Set ShadowStack memory.
+
+ @param[in] Cr3 The page table base address.
+ @param[in] BaseAddress The physical address that is the start address of a memory region.
+ @param[in] Length The size in bytes of the memory region.
+
+ @retval EFI_SUCCESS The shadow stack memory is set.
+**/
+EFI_STATUS
+SetShadowStack (
+ IN UINTN Cr3,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Set not present memory.
+
+ @param[in] Cr3 The page table base address.
+ @param[in] BaseAddress The physical address that is the start address of a memory region.
+ @param[in] Length The size in bytes of the memory region.
+
+ @retval EFI_SUCCESS The not present memory is set.
+**/
+EFI_STATUS
+SetNotPresentPage (
+ IN UINTN Cr3,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Initialize the shadow stack related data structure.
+
+ @param CpuIndex The index of CPU.
+ @param ShadowStack The bottom of the shadow stack for this CPU.
+**/
+VOID
+InitShadowStack (
+ IN UINTN CpuIndex,
+ IN VOID *ShadowStack
+ );
+
+/**
This function set given attributes of the memory region specified by
BaseAddress and Length.