From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com []) by mx.groups.io with SMTP id smtpd.web10.2987.1595584489166956048 for ; Fri, 24 Jul 2020 02:54:54 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: guomin.jiang@intel.com) IronPort-SDR: JuUQiDRDlCL/J1in5QlGLKFIXdg0+iuIs/OpOJJ7TYAyqJk/qQ/FgNAlxQZZd4GJPS7pEMQzE+ iFa41k1gkHMg== X-IronPort-AV: E=McAfee;i="6000,8403,9691"; a="151973937" X-IronPort-AV: E=Sophos;i="5.75,390,1589266800"; d="scan'208";a="151973937" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jul 2020 02:54:54 -0700 IronPort-SDR: auvgyEPKiiA8PB0ge25oqNfqlU/YtpDn/ihig47a7t0e3EImerFklwsm2BjJ4aOO8cSqcbSl+2 0vUrEAX/amaA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,390,1589266800"; d="scan'208";a="319266256" Received: from guominji-mobl.ccr.corp.intel.com ([10.238.13.140]) by orsmga008.jf.intel.com with ESMTP; 24 Jul 2020 02:54:52 -0700 From: "Guomin Jiang" To: devel@edk2.groups.io Cc: Michael Kubacki , Eric Dong , Ray Ni , Laszlo Ersek , Rahul Kumar , Jian J Wang Subject: [PATCH v8 3/9] UefiCpuPkg/CpuMpPei: Add GDT migration support (CVE-2019-11098) Date: Fri, 24 Jul 2020 17:54:40 +0800 Message-Id: <20200724095446.598-4-guomin.jiang@intel.com> X-Mailer: git-send-email 2.25.1.windows.1 In-Reply-To: <20200724095446.598-1-guomin.jiang@intel.com> References: <20200724095446.598-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 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 Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Signed-off-by: Michael Kubacki Reviewed-by: Laszlo Ersek Reviewed-by: Jian J Wang --- UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 + UefiCpuPkg/CpuMpPei/CpuMpPei.h | 12 +++++++++++ UefiCpuPkg/CpuMpPei/CpuMpPei.c | 37 ++++++++++++++++++++++++++++++++ UefiCpuPkg/CpuMpPei/CpuPaging.c | 12 +++++++++-- 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf index caead3ce34d4..f4d11b861f77 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf @@ -63,6 +63,7 @@ [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES [Depex] TRUE diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index 7d5c527d6006..309478cbe14c 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.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index 07ccbe7c6a91..d07540cf7471 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/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c index a462e7ee1e38..3bf0574b34c6 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.25.1.windows.1