From nobody Thu May 2 18:01:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1528868121943124.3713640667163; Tue, 12 Jun 2018 22:35:21 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D6DF9212E25AD; Tue, 12 Jun 2018 22:35:19 -0700 (PDT) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2A706212C01F7 for ; Tue, 12 Jun 2018 22:35:19 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Jun 2018 22:35:17 -0700 Received: from shwdeopenpsi777.ccr.corp.intel.com ([10.239.158.27]) by fmsmga002.fm.intel.com with ESMTP; 12 Jun 2018 22:35:06 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,217,1526367600"; d="scan'208";a="56794879" From: Jian J Wang To: edk2-devel@lists.01.org Date: Wed, 13 Jun 2018 13:35:00 +0800 Message-Id: <20180613053501.4604-2-jian.j.wang@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20180613053501.4604-1-jian.j.wang@intel.com> References: <20180613053501.4604-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v2 1/2] UefiCpuPkg/CpuDxe: allow accessing (DXE) page table in SMM mode X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ruiyu Ni , Jiewen Yao , Laszlo Ersek , Eric Dong MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" > v2: > a. add more specific explanations in commit message > b. add more comments in code > c. remove redundant logic in IsInSmm() > d. fix a logic hole in GetCurrentPagingContext() > e. replace meanless constant macro with meaning ones The MdePkg/Library/SmmMemoryAllocationLib, used only by DXE_SMM_DRIVER, allows to free memory allocated in DXE (before EndOfDxe). This is done by checking the memory range and calling gBS services to do real operation if the memory to free is out of SMRAM. If some memory related features, like Heap Guard, are enabled, gBS interface will turn to EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes(), provided by DXE driver UefiCpuPkg/CpuDxe, to change memory paging attributes. This means we have part of DXE code running in SMM mode in certain circumstances. Because page table in SMM mode is different from DXE mode and CpuDxe always uses current registers (CR0, CR3, etc.) to get memory paging attributes, it cannot get the correct attributes of DXE memory in SMM mode from SMM page table. This will cause incorrect memory manipulations, like fail the releasing of Guard pages if Heap Guard is enabled. The solution in this patch is to store the DXE page table information (e.g. value of CR0, CR3 registers, etc.) in a global variable of CpuDxe driver. If CpuDxe detects it's in SMM mode, it will use this global variable to access page table instead of current processor registers. This can avoid retrieving wrong DXE memory paging attributes and changing SMM page table attributes unexpectedly. Cc: Eric Dong Cc: Laszlo Ersek Cc: Jiewen Yao Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang Reviewed-by: Eric Dong Reviewed-by: Laszlo Ersek --- UefiCpuPkg/CpuDxe/CpuDxe.inf | 1 + UefiCpuPkg/CpuDxe/CpuPageTable.c | 159 ++++++++++++++++++++++++++++++-----= ---- 2 files changed, 123 insertions(+), 37 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf index 3c938cee53..ce2bd3627c 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.inf +++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf @@ -66,6 +66,7 @@ [Protocols] gEfiCpuArchProtocolGuid ## PRODUCES gEfiMpServiceProtocolGuid ## PRODUCES + gEfiSmmBase2ProtocolGuid ## CONSUMES =20 [Guids] gIdleLoopEventGuid ## CONSUMES ## E= vent diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTa= ble.c index e2595b4d89..b7e75922b6 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.c +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c @@ -23,10 +23,21 @@ #include #include #include +#include +#include +#include =20 #include "CpuDxe.h" #include "CpuPageTable.h" =20 +/// +/// Paging registers +/// +#define CR0_WP BIT16 +#define CR0_PG BIT31 +#define CR4_PSE BIT4 +#define CR4_PAE BIT5 + /// /// Page Table Entry /// @@ -87,7 +98,46 @@ PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] =3D { {Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64}, }; =20 -PAGE_TABLE_POOL *mPageTablePool =3D NULL; +PAGE_TABLE_POOL *mPageTablePool =3D NULL; +PAGE_TABLE_LIB_PAGING_CONTEXT mPagingContext; +EFI_SMM_BASE2_PROTOCOL *mSmmBase2 =3D NULL; + +/** + Check if current execution environment is in SMM mode or not, via + EFI_SMM_BASE2_PROTOCOL. + + This is necessary because of the fact that MdePkg\Library\SmmMemoryAlloca= tionLib + supports to free memory outside SMRAM. The library will call gBS->FreePoo= l() or + gBS->FreePages() and then SetMemorySpaceAttributes interface in turn to c= hange + memory paging attributes during free operation, if some memory related fe= atures + are enabled (like Heap Guard). + + This means that SetMemorySpaceAttributes() has chance to run in SMM mode.= This + will cause incorrect result because SMM mode always loads its own page ta= bles, + which are usually different from DXE. This function can be used to detect= such + situation and help to avoid further misoperations. + + @retval TRUE In SMM mode. + @retval FALSE Not in SMM mode. +**/ +BOOLEAN +IsInSmm ( + VOID + ) +{ + BOOLEAN InSmm; + + InSmm =3D FALSE; + if (mSmmBase2 =3D=3D NULL) { + gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&mSmmBa= se2); + } + + if (mSmmBase2 !=3D NULL) { + mSmmBase2->InSmm (mSmmBase2, &InSmm); + } + + return InSmm; +} =20 /** Return current paging context. @@ -99,45 +149,61 @@ GetCurrentPagingContext ( IN OUT PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext ) { - UINT32 RegEax; - UINT32 RegEdx; + UINT32 RegEax; + CPUID_EXTENDED_CPU_SIG_EDX RegEdx; + MSR_IA32_EFER_REGISTER MsrEfer; =20 - ZeroMem(PagingContext, sizeof(*PagingContext)); - if (sizeof(UINTN) =3D=3D sizeof(UINT64)) { - PagingContext->MachineType =3D IMAGE_FILE_MACHINE_X64; - } else { - PagingContext->MachineType =3D IMAGE_FILE_MACHINE_I386; - } - if ((AsmReadCr0 () & BIT31) !=3D 0) { - PagingContext->ContextData.X64.PageTableBase =3D (AsmReadCr3 () & PAGI= NG_4K_ADDRESS_MASK_64); - } else { - PagingContext->ContextData.X64.PageTableBase =3D 0; - } + // + // Don't retrieve current paging context from processor if in SMM mode. + // + if (!IsInSmm ()) { + ZeroMem (&mPagingContext, sizeof(mPagingContext)); =20 - if ((AsmReadCr4 () & BIT4) !=3D 0) { - PagingContext->ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGING_= CONTEXT_IA32_X64_ATTRIBUTES_PSE; - } - if ((AsmReadCr4 () & BIT5) !=3D 0) { - PagingContext->ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGING_= CONTEXT_IA32_X64_ATTRIBUTES_PAE; - } - if ((AsmReadCr0 () & BIT16) !=3D 0) { - PagingContext->ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGING_= CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE; - } + if (sizeof(UINTN) =3D=3D sizeof(UINT64)) { + mPagingContext.MachineType =3D IMAGE_FILE_MACHINE_X64; + } else { + mPagingContext.MachineType =3D IMAGE_FILE_MACHINE_I386; + } + if ((AsmReadCr0 () & CR0_PG) !=3D 0) { + mPagingContext.ContextData.X64.PageTableBase =3D (AsmReadCr3 () & PA= GING_4K_ADDRESS_MASK_64); + } else { + mPagingContext.ContextData.X64.PageTableBase =3D 0; + } =20 - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax > 0x80000000) { - AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT20) !=3D 0) { - // XD supported - if ((AsmReadMsr64 (0xC0000080) & BIT11) !=3D 0) { - // XD activated - PagingContext->ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAG= ING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED; - } + if ((AsmReadCr4 () & CR4_PSE) !=3D 0) { + mPagingContext.ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGIN= G_CONTEXT_IA32_X64_ATTRIBUTES_PSE; + } + if ((AsmReadCr4 () & CR4_PAE) !=3D 0) { + mPagingContext.ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGIN= G_CONTEXT_IA32_X64_ATTRIBUTES_PAE; + } + if ((AsmReadCr0 () & CR0_WP) !=3D 0) { + mPagingContext.ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGIN= G_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE; } - if ((RegEdx & BIT26) !=3D 0) { - PagingContext->ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAGIN= G_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT; + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >=3D CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, (UINT32 *)&RegEd= x); + + if (RegEdx.Bits.NX !=3D 0) { + // XD supported + MsrEfer.Uint64 =3D AsmReadMsr64(MSR_CORE_IA32_EFER); + if (MsrEfer.Bits.NXE !=3D 0) { + // XD activated + mPagingContext.ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_P= AGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED; + } + } + + if (RegEdx.Bits.Page1GB !=3D 0) { + mPagingContext.ContextData.Ia32.Attributes |=3D PAGE_TABLE_LIB_PAG= ING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT; + } } } + + // + // This can avoid getting SMM paging context if in SMM mode. We cannot a= ssume + // SMM mode shares the same paging context as DXE. + // + CopyMem (PagingContext, &mPagingContext, sizeof (mPagingContext)); } =20 /** @@ -507,7 +573,14 @@ IsReadOnlyPageWriteProtected ( VOID ) { - return ((AsmReadCr0 () & BIT16) !=3D 0); + // + // To avoid unforseen consequences, don't touch paging settings in SMM m= ode + // in this driver. + // + if (!IsInSmm ()) { + return ((AsmReadCr0 () & CR0_WP) !=3D 0); + } + return FALSE; } =20 /** @@ -518,7 +591,13 @@ DisableReadOnlyPageWriteProtect ( VOID ) { - AsmWriteCr0 (AsmReadCr0() & ~BIT16); + // + // To avoid unforseen consequences, don't touch paging settings in SMM m= ode + // in this driver. + // + if (!IsInSmm ()) { + AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP); + } } =20 /** @@ -529,7 +608,13 @@ EnableReadOnlyPageWriteProtect ( VOID ) { - AsmWriteCr0 (AsmReadCr0() | BIT16); + // + // To avoid unforseen consequences, don't touch paging settings in SMM m= ode + // in this driver. + // + if (!IsInSmm ()) { + AsmWriteCr0 (AsmReadCr0 () | CR0_WP); + } } =20 /** --=20 2.16.2.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Thu May 2 18:01:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1528868124705184.4972329404751; Tue, 12 Jun 2018 22:35:24 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0D710212DA5F5; Tue, 12 Jun 2018 22:35:21 -0700 (PDT) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 47F5E212CFEC9 for ; Tue, 12 Jun 2018 22:35:19 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Jun 2018 22:35:18 -0700 Received: from shwdeopenpsi777.ccr.corp.intel.com ([10.239.158.27]) by fmsmga002.fm.intel.com with ESMTP; 12 Jun 2018 22:35:08 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,217,1526367600"; d="scan'208";a="56794882" From: Jian J Wang To: edk2-devel@lists.01.org Date: Wed, 13 Jun 2018 13:35:01 +0800 Message-Id: <20180613053501.4604-3-jian.j.wang@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20180613053501.4604-1-jian.j.wang@intel.com> References: <20180613053501.4604-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v2 2/2] MdeModulePkg/Core: remove SMM check for Heap Guard feature detection X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ruiyu Ni , Jiewen Yao , Eric Dong , Star Zeng MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" CpuDxe driver is updated to be able to access DXE page table in SMM mode, which means Heap Guard can get correct memory paging attributes in what environment. It's not necessary to exclude SMM from detecting Heap Guard feature support. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang Reviewed-by: Star Zeng --- MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/= Mem/HeapGuard.c index 9d765c98f6..447c56bb11 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -667,21 +667,11 @@ IsMemoryTypeToGuard ( { UINT64 TestBit; UINT64 ConfigBit; - BOOLEAN InSmm; =20 if (AllocateType =3D=3D AllocateAddress) { return FALSE; } =20 - InSmm =3D FALSE; - if (gSmmBase2 !=3D NULL) { - gSmmBase2->InSmm (gSmmBase2, &InSmm); - } - - if (InSmm) { - return FALSE; - } - if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) =3D=3D 0) { return FALSE; } --=20 2.16.2.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel