]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/CpuMpPei: Add GDT migration support (CVE-2019-11098)
authorMichael Kubacki <michael.a.kubacki@intel.com>
Sun, 14 Apr 2019 03:48:07 +0000 (11:48 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 28 Jul 2020 01:43:16 +0000 (01:43 +0000)
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
UefiCpuPkg/CpuMpPei/CpuMpPei.h
UefiCpuPkg/CpuMpPei/CpuMpPei.inf
UefiCpuPkg/CpuMpPei/CpuPaging.c

index 07ccbe7c6a91febda2ce9169eac46db57d9c8f73..d07540cf747126b6ae32e32a15021135ac1146c0 100644 (file)
@@ -429,6 +429,43 @@ GetGdtr (
   AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);\r
 }\r
 \r
+/**\r
+  Migrates the Global Descriptor Table (GDT) to permanent memory.\r
+\r
+  @retval   EFI_SUCCESS           The GDT was migrated successfully.\r
+  @retval   EFI_OUT_OF_RESOURCES  The GDT could not be migrated due to lack of available memory.\r
+\r
+**/\r
+EFI_STATUS\r
+MigrateGdt (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  UINTN               GdtBufferSize;\r
+  IA32_DESCRIPTOR     Gdtr;\r
+  VOID                *GdtBuffer;\r
+\r
+  AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);\r
+  GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;\r
+\r
+  Status =  PeiServicesAllocatePool (\r
+              GdtBufferSize,\r
+              &GdtBuffer\r
+              );\r
+  ASSERT (GdtBuffer != NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));\r
+  CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);\r
+  Gdtr.Base = (UINTN) GdtBuffer;\r
+  AsmWriteGdtr (&Gdtr);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Initializes CPU exceptions handlers for the sake of stack switch requirement.\r
 \r
index 7d5c527d6006824a33b3aa2967c93c3a080d7ae4..309478cbe14c1dc36d4c4d2408b359b5cad54dcd 100644 (file)
@@ -397,6 +397,18 @@ SecPlatformInformation2 (
      OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2\r
   );\r
 \r
+/**\r
+  Migrates the Global Descriptor Table (GDT) to permanent memory.\r
+\r
+  @retval   EFI_SUCCESS           The GDT was migrated successfully.\r
+  @retval   EFI_OUT_OF_RESOURCES  The GDT could not be migrated due to lack of available memory.\r
+\r
+**/\r
+EFI_STATUS\r
+MigrateGdt (\r
+  VOID\r
+  );\r
+\r
 /**\r
   Initializes MP and exceptions handlers.\r
 \r
index caead3ce34d46da4bcc782a0c9677f4e899aae22..f4d11b861f77c1ff51fcb0788f710b10696595ad 100644 (file)
@@ -63,6 +63,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## SOMETIMES_CONSUMES\r
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## SOMETIMES_CONSUMES\r
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize                           ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes  ## CONSUMES\r
 \r
 [Depex]\r
   TRUE\r
index a462e7ee1e386b60cbd4074b671f007eee65a97e..3bf0574b34c6cbe342573d633977a7d39403f265 100644 (file)
@@ -602,8 +602,16 @@ MemoryDiscoveredPpiNotifyCallback (
   IN VOID                       *Ppi\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
-  BOOLEAN         InitStackGuard;\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     InitStackGuard;\r
+  BOOLEAN     InterruptState;\r
+\r
+  if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
+    InterruptState = SaveAndDisableInterrupts ();\r
+    Status = MigrateGdt ();\r
+    ASSERT_EFI_ERROR (Status);\r
+    SetInterruptState (InterruptState);\r
+  }\r
 \r
   //\r
   // Paging must be setup first. Otherwise the exception TSS setup during MP\r