From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com []) by mx.groups.io with SMTP id smtpd.web10.360.1593666932487247443 for ; Wed, 01 Jul 2020 22:15:36 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: guomin.jiang@intel.com) IronPort-SDR: a4F0kTU3kQ7V9bRsXmdrBK1Hkra399tgw9/R65lvG/1welMLjsGDY01HjIEZbcC7zbLf0pFsGq R+WfJANK4Rwg== X-IronPort-AV: E=McAfee;i="6000,8403,9669"; a="208319024" X-IronPort-AV: E=Sophos;i="5.75,302,1589266800"; d="scan'208";a="208319024" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jul 2020 22:15:36 -0700 IronPort-SDR: 4b+RuCQGaqwfRwxJwEDCf9/cb9W5w0ExlZ5xynTaJ2QhycNvu98TJweA4RZARK+2qtEp5+8XZP enV6WrS+F7Pw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,302,1589266800"; d="scan'208";a="455384873" Received: from guominji-mobl.ccr.corp.intel.com ([10.238.4.95]) by orsmga005.jf.intel.com with ESMTP; 01 Jul 2020 22:15:34 -0700 From: "Guomin Jiang" To: devel@edk2.groups.io Cc: Michael Kubacki , Eric Dong , Ray Ni , Laszlo Ersek , Rahul Kumar Subject: [PATCH v2 2/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098) Date: Thu, 2 Jul 2020 13:15:18 +0800 Message-Id: <20200702051525.1102-3-guomin.jiang@intel.com> X-Mailer: git-send-email 2.25.1.windows.1 In-Reply-To: <20200702051525.1102-1-guomin.jiang@intel.com> References: <20200702051525.1102-1-guomin.jiang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Michael Kubacki REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614 Moves the GDT and IDT to permanent memory in a memory discovered callback. This is done to ensure the GDT and IDT authenticated in pre-memory is not fetched from outside a verified location after the permanent memory transition. Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Signed-off-by: Michael Kubacki --- UefiCpuPkg/CpuMpPei/CpuMpPei.c | 40 ++++++++++++++++++- UefiCpuPkg/CpuMpPei/CpuMpPei.h | 13 ++++++ UefiCpuPkg/CpuMpPei/CpuPaging.c | 14 +++++-- .../Ia32/ArchExceptionHandler.c | 4 +- .../SecPeiCpuException.c | 2 +- 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index 07ccbe7c6a91..2d6f1bc98851 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -429,6 +429,44 @@ 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 +EFIAPI +MigrateGdt ( + VOID + ) +{ + EFI_STATUS Status; + UINTN GdtBufferSize; + IA32_DESCRIPTOR Gdtr; + UINT8 *GdtBuffer; + + AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr); + GdtBufferSize = sizeof (IA32_TSS_DESCRIPTOR) + Gdtr.Limit + 1; + + Status = PeiServicesAllocatePool ( + GdtBufferSize, + (VOID **) &GdtBuffer + ); + ASSERT (GdtBuffer != NULL); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_TSS_DESCRIPTOR)); + CopyMem ((VOID *) (UINTN) GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1); + Gdtr.Base = (UINT32)(UINTN) GdtBuffer; + AsmWriteGdtr (&Gdtr); + + return EFI_SUCCESS; +} + /** Initializes CPU exceptions handlers for the sake of stack switch requirement. @@ -644,7 +682,7 @@ InitializeCpuMpWorker ( &gEfiVectorHandoffInfoPpiGuid, 0, NULL, - (VOID **)&VectorHandoffInfoPpi + (VOID **) &VectorHandoffInfoPpi ); if (Status == EFI_SUCCESS) { VectorInfo = VectorHandoffInfoPpi->Info; diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index 7d5c527d6006..5dc956409594 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -397,6 +397,19 @@ 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 +EFIAPI +MigrateGdt ( + VOID + ); + /** Initializes MP and exceptions handlers. diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c index a462e7ee1e38..d0cbebf70bbf 100644 --- a/UefiCpuPkg/CpuMpPei/CpuPaging.c +++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c @@ -152,7 +152,7 @@ GetPhysicalAddressWidth ( Get the type of top level page table. @retval Page512G PML4 paging. - @retval Page1G PAE paing. + @retval Page1G PAE paging. **/ PAGE_ATTRIBUTE @@ -582,7 +582,7 @@ SetupStackGuardPage ( } /** - Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE. + Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE. Doing this in the memory-discovered callback is to make sure the Stack Guard feature to cover as most PEI code as possible. @@ -602,8 +602,14 @@ MemoryDiscoveredPpiNotifyCallback ( IN VOID *Ppi ) { - EFI_STATUS Status; - BOOLEAN InitStackGuard; + EFI_STATUS Status; + BOOLEAN InitStackGuard; + BOOLEAN InterruptState; + + InterruptState = SaveAndDisableInterrupts (); + Status = MigrateGdt (); + ASSERT_EFI_ERROR (Status); + SetInterruptState (InterruptState); // // Paging must be setup first. Otherwise the exception TSS setup during MP diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index 1aafb7dac139..903449e0daa9 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -18,8 +18,8 @@ **/ VOID ArchUpdateIdtEntry ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, - IN UINTN InterruptHandler + OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry, + IN UINTN InterruptHandler ) { IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c index 20148db74cf8..d4ae153c5742 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c @@ -87,7 +87,7 @@ InitializeCpuExceptionHandlers ( IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); if (IdtEntryCount > CPU_EXCEPTION_NUM) { // - // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most + // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most // IdtEntryCount = CPU_EXCEPTION_NUM; } -- 2.25.1.windows.1