From nobody Wed Dec 25 02:22:17 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 Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1512095882540438.1075473961291; Thu, 30 Nov 2017 18:38:02 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 71F4E221660E6; Thu, 30 Nov 2017 18:33:21 -0800 (PST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (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 03AEA220F3C5A for ; Thu, 30 Nov 2017 18:33:17 -0800 (PST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Nov 2017 18:37:43 -0800 Received: from jwang36-mobl2.ccr.corp.intel.com ([10.239.192.33]) by fmsmga004.fm.intel.com with ESMTP; 30 Nov 2017 18:37:43 -0800 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=192.55.52.43; helo=mga05.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,343,1508828400"; d="scan'208";a="8199555" From: Jian J Wang To: edk2-devel@lists.01.org Date: Fri, 1 Dec 2017 10:37:28 +0800 Message-Id: <20171201023728.4680-12-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171201023728.4680-1-jian.j.wang@intel.com> References: <20171201023728.4680-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v3 11/11] MdeModulePkg/DxeIpl: Enable paging for Stack Guard X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: 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" Stack guard feature makes use of paging mechanism to monitor if there's a stack overflow occurred during boot. This patch will check setting of PCD PcdCpuStackGuard. If it's TRUE, DxeIpl will setup page table and set the page at which the stack base locates to be NOT PRESENT. If stack is used up and memory access cross into the last page of it, #PF exception will be triggered. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 5 ++- MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 ++ MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 1 + MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 51 ++++++++++++++++++--= ---- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/Dx= eIplPeim/DxeIpl.inf index a1b8748432..ba1d9c6b05 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -49,7 +49,7 @@ [Sources.X64] X64/VirtualMemory.h X64/VirtualMemory.c - X64/DxeLoadFunc.c =20 + X64/DxeLoadFunc.c =20 [Sources.IPF] Ipf/DxeLoadFunc.c @@ -117,6 +117,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ##= CONSUMES =20 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIM= ES_CONSUMES @@ -132,7 +133,7 @@ # # [Hob] # MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # MEMORY_ALLOCAT= ION_MODULE for DxeCore -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # New Stack HoB = =20 +# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # New Stack HoB # MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # Old Stack HOB # # [Hob.IPF] diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg= /Core/DxeIplPeim/Ia32/DxeLoadFunc.c index 5649265367..441096ad0f 100644 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c @@ -235,6 +235,10 @@ ToBuildPageTable ( return TRUE; } =20 + if (PcdGetBool (PcdCpuStackGuard)) { + return TRUE; + } + if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) { return TRUE; } diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/= Core/DxeIplPeim/X64/DxeLoadFunc.c index f613221b81..b75a4489bf 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c @@ -95,6 +95,7 @@ HandOffToDxeCore ( // for the DxeIpl and the DxeCore are both X64. // ASSERT (PcdGetBool (PcdSetNxForStack) =3D=3D FALSE); + ASSERT (PcdGetBool (PcdCpuStackGuard) =3D=3D FALSE); } =20 // diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePk= g/Core/DxeIplPeim/X64/VirtualMemory.c index 29b6205e88..a2466b7766 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -117,6 +117,39 @@ EnableExecuteDisableBit ( AsmWriteMsr64 (0xC0000080, MsrRegisters); } =20 +/** + The function will check if page table entry should be splitted to smaller + granularity. + + @retval TRUE Page table should be created. + @retval FALSE Page table should not be created. +**/ +BOOLEAN +ToSplitPageTable ( + IN EFI_PHYSICAL_ADDRESS Address, + IN UINTN Size, + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize + ) +{ + if (IsNullDetectionEnabled () && Address =3D=3D 0) { + return TRUE; + } + + if (PcdGetBool (PcdCpuStackGuard)) { + if (StackBase >=3D Address && StackBase < (Address + Size)) { + return TRUE; + } + } + + if (PcdGetBool (PcdSetNxForStack)) { + if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase= )) { + return TRUE; + } + } + + return FALSE; +} /** Split 2M page to 4K. =20 @@ -160,7 +193,8 @@ Split2MPageTo4K ( PageTableEntry->Uint64 =3D (UINT64) PhysicalAddress4K | AddressEncMask; PageTableEntry->Bits.ReadWrite =3D 1; =20 - if (IsNullDetectionEnabled () && PhysicalAddress4K =3D=3D 0) { + if ((IsNullDetectionEnabled () && PhysicalAddress4K =3D=3D 0) || + (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K =3D=3D StackBa= se)) { PageTableEntry->Bits.Present =3D 0; } else { PageTableEntry->Bits.Present =3D 1; @@ -214,10 +248,7 @@ Split1GPageTo2M ( =20 PhysicalAddress2M =3D PhysicalAddress; for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries < 51= 2; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += =3D SIZE_2MB) { - if ((IsNullDetectionEnabled () && PhysicalAddress2M =3D=3D 0) - || (PcdGetBool (PcdSetNxForStack) - && (PhysicalAddress2M < StackBase + StackSize) - && ((PhysicalAddress2M + SIZE_2MB) > StackBase))) { + if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSiz= e)) { // // Need to split this 2M page that covers NULL or stack range. // @@ -359,10 +390,7 @@ CreateIdentityMappingPageTables ( PageDirectory1GEntry =3D (VOID *) PageDirectoryPointerEntry; =20 for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries = < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += =3D SIZE_1GB) { - if ((IsNullDetectionEnabled () && PageAddress =3D=3D 0) - || (PcdGetBool (PcdSetNxForStack) - && (PageAddress < StackBase + StackSize) - && ((PageAddress + SIZE_1GB) > StackBase))) { + if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)= ) { Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, S= tackBase, StackSize); } else { // @@ -391,10 +419,7 @@ CreateIdentityMappingPageTables ( PageDirectoryPointerEntry->Bits.Present =3D 1; =20 for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += =3D SIZE_2MB) { - if ((IsNullDetectionEnabled () && PageAddress =3D=3D 0) - || (PcdGetBool (PcdSetNxForStack) - && (PageAddress < StackBase + StackSize) - && ((PageAddress + SIZE_2MB) > StackBase))) { + if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSiz= e)) { // // Need to split this 2M page that covers NULL or stack range. // --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel