138 lines
4.5 KiB
Diff
138 lines
4.5 KiB
Diff
From 60b12e69fb1c8c7180fdda92f008248b9ec83db1 Mon Sep 17 00:00:00 2001
|
|
From: Michael Kubacki <michael.a.kubacki@intel.com>
|
|
Date: Sun, 14 Apr 2019 11:48:07 +0800
|
|
Subject: [PATCH] UefiCpuPkg/CpuMpPei: Add GDT migration support
|
|
(CVE-2019-11098)
|
|
|
|
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
|
|
|
|
Moves the GDT to permanent memory in a memory discovered
|
|
callback. This is done to ensure the GDT authenticated in
|
|
pre-memory is not fetched from outside a verified location
|
|
after the permanent memory transition.
|
|
|
|
Cc: Eric Dong <eric.dong@intel.com>
|
|
Cc: Ray Ni <ray.ni@intel.com>
|
|
Cc: Laszlo Ersek <lersek@redhat.com>
|
|
Cc: Rahul Kumar <rahul1.kumar@intel.com>
|
|
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
|
|
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
|
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
|
|
Reviewed-by: Liming Gao <liming.gao@intel.com>
|
|
---
|
|
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 37 ++++++++++++++++++++++++++++++++
|
|
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 12 +++++++++++
|
|
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 +
|
|
UefiCpuPkg/CpuMpPei/CpuPaging.c | 12 +++++++++--
|
|
4 files changed, 60 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
|
|
index 07ccbe7c6a..d07540cf74 100644
|
|
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
|
|
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
|
|
@@ -429,6 +429,43 @@ GetGdtr (
|
|
AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);
|
|
}
|
|
|
|
+/**
|
|
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
|
|
+
|
|
+ @retval EFI_SUCCESS The GDT was migrated successfully.
|
|
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
|
|
+
|
|
+**/
|
|
+EFI_STATUS
|
|
+MigrateGdt (
|
|
+ VOID
|
|
+ )
|
|
+{
|
|
+ EFI_STATUS Status;
|
|
+ UINTN GdtBufferSize;
|
|
+ IA32_DESCRIPTOR Gdtr;
|
|
+ VOID *GdtBuffer;
|
|
+
|
|
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);
|
|
+ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
|
|
+
|
|
+ Status = PeiServicesAllocatePool (
|
|
+ GdtBufferSize,
|
|
+ &GdtBuffer
|
|
+ );
|
|
+ ASSERT (GdtBuffer != NULL);
|
|
+ if (EFI_ERROR (Status)) {
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
+ }
|
|
+
|
|
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
|
|
+ CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
|
|
+ Gdtr.Base = (UINTN) GdtBuffer;
|
|
+ AsmWriteGdtr (&Gdtr);
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
/**
|
|
Initializes CPU exceptions handlers for the sake of stack switch requirement.
|
|
|
|
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
|
|
index 7d5c527d60..309478cbe1 100644
|
|
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
|
|
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
|
|
@@ -397,6 +397,18 @@ SecPlatformInformation2 (
|
|
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
|
|
);
|
|
|
|
+/**
|
|
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
|
|
+
|
|
+ @retval EFI_SUCCESS The GDT was migrated successfully.
|
|
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
|
|
+
|
|
+**/
|
|
+EFI_STATUS
|
|
+MigrateGdt (
|
|
+ VOID
|
|
+ );
|
|
+
|
|
/**
|
|
Initializes MP and exceptions handlers.
|
|
|
|
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
|
|
index caead3ce34..f4d11b861f 100644
|
|
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
|
|
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
|
|
@@ -63,6 +63,7 @@
|
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES
|
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES
|
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES
|
|
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
|
|
|
|
[Depex]
|
|
TRUE
|
|
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
|
|
index a462e7ee1e..3bf0574b34 100644
|
|
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
|
|
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
|
|
@@ -602,8 +602,16 @@ MemoryDiscoveredPpiNotifyCallback (
|
|
IN VOID *Ppi
|
|
)
|
|
{
|
|
- EFI_STATUS Status;
|
|
- BOOLEAN InitStackGuard;
|
|
+ EFI_STATUS Status;
|
|
+ BOOLEAN InitStackGuard;
|
|
+ BOOLEAN InterruptState;
|
|
+
|
|
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
|
|
+ InterruptState = SaveAndDisableInterrupts ();
|
|
+ Status = MigrateGdt ();
|
|
+ ASSERT_EFI_ERROR (Status);
|
|
+ SetInterruptState (InterruptState);
|
|
+ }
|
|
|
|
//
|
|
// Paging must be setup first. Otherwise the exception TSS setup during MP
|
|
--
|
|
2.27.0
|
|
|