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.2988.1594176375248160105 for ; Tue, 07 Jul 2020 19:46:25 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: guomin.jiang@intel.com) IronPort-SDR: lsRsM6D0bVK9rFtgOWjzqQHasaxYnUZDKT0I+j1QNF8oBcFPeehtriQ8Q2ZPrUDO/fXfiHYezL sZVIskAYyn7Q== X-IronPort-AV: E=McAfee;i="6000,8403,9675"; a="149242200" X-IronPort-AV: E=Sophos;i="5.75,326,1589266800"; d="scan'208";a="149242200" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jul 2020 19:46:25 -0700 IronPort-SDR: M1keqo4gltpPO+YNoSkkIoU55eJ6KwHdjgfxiEf7vzCigBYyNgxJrKNpb+0JAul/3l+ETfHXbq +tRmWA+h8rwA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,326,1589266800"; d="scan'208";a="483271595" Received: from guominji-mobl.ccr.corp.intel.com ([10.238.4.95]) by fmsmga006.fm.intel.com with ESMTP; 07 Jul 2020 19:46:22 -0700 From: "Guomin Jiang" To: devel@edk2.groups.io Cc: Michael Kubacki , Eric Dong , Ray Ni , Laszlo Ersek , Rahul Kumar Subject: [PATCH v3 06/11] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098) Date: Wed, 8 Jul 2020 10:46:03 +0800 Message-Id: <20200708024608.915-7-guomin.jiang@intel.com> X-Mailer: git-send-email 2.25.1.windows.1 In-Reply-To: <20200708024608.915-1-guomin.jiang@intel.com> References: <20200708024608.915-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.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