summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
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/PageTbl.c
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/PageTbl.c')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
index a32b736089..b734a1ea8c 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -1,7 +1,7 @@
/** @file
Page table manipulation functions for IA-32 processors
-Copyright (c) 2009 - 2017, 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
@@ -17,6 +17,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "PiSmmCpuDxeSmm.h"
/**
+ Disable CET.
+**/
+VOID
+EFIAPI
+DisableCet (
+ VOID
+ );
+
+/**
+ Enable CET.
+**/
+VOID
+EFIAPI
+EnableCet (
+ VOID
+ );
+
+/**
Create PageTable for SMM use.
@return PageTable Address
@@ -138,6 +156,7 @@ SmiPFHandler (
}
}
CpuDeadLoop ();
+ goto Exit;
}
//
@@ -152,6 +171,7 @@ SmiPFHandler (
DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);
);
CpuDeadLoop ();
+ goto Exit;
}
//
@@ -171,6 +191,7 @@ SmiPFHandler (
}
CpuDeadLoop ();
+ goto Exit;
}
if (IsSmmCommBufferForbiddenAddress (PFAddress)) {
@@ -180,6 +201,7 @@ SmiPFHandler (
DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
);
CpuDeadLoop ();
+ goto Exit;
}
}
@@ -212,6 +234,7 @@ SetPageTableAttributes (
UINT64 *L3PageTable;
BOOLEAN IsSplitted;
BOOLEAN PageTableSplitted;
+ BOOLEAN CetEnabled;
//
// Don't mark page table to read-only if heap guard is enabled.
@@ -238,6 +261,13 @@ SetPageTableAttributes (
// Disable write protection, because we need mark page table to be write protected.
// We need *write* page table memory, to mark itself to be *read only*.
//
+ CetEnabled = ((AsmReadCr4() & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
+ if (CetEnabled) {
+ //
+ // CET must be disabled if WP is disabled.
+ //
+ DisableCet();
+ }
AsmWriteCr0 (AsmReadCr0() & ~CR0_WP);
do {
@@ -277,6 +307,12 @@ SetPageTableAttributes (
// Enable write protection, after page table updated.
//
AsmWriteCr0 (AsmReadCr0() | CR0_WP);
+ if (CetEnabled) {
+ //
+ // re-enable CET.
+ //
+ EnableCet();
+ }
return ;
}