From nobody Sat Jul 12 10:24:29 2025 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 1509459963251249.21016362102182; Tue, 31 Oct 2017 07:26:03 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7ECE12035D111; Tue, 31 Oct 2017 07:22:07 -0700 (PDT) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (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 BFDAE2035D103 for ; Tue, 31 Oct 2017 07:22:05 -0700 (PDT) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Oct 2017 07:25:57 -0700 Received: from jwang36-mobl2.ccr.corp.intel.com ([10.254.212.126]) by fmsmga006.fm.intel.com with ESMTP; 31 Oct 2017 07:25:56 -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=192.55.52.115; helo=mga14.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.44,324,1505804400"; d="scan'208";a="170043589" From: Jian J Wang To: edk2-devel@lists.01.org Date: Tue, 31 Oct 2017 22:24:11 +0800 Message-Id: <20171031142412.21680-3-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171031142412.21680-1-jian.j.wang@intel.com> References: <20171031142412.21680-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH 2/3] 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: 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 Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 35 ++++++++++++++-- MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 1 + MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 51 ++++++++++++++++++--= ---- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/Dx= eIplPeim/DxeIpl.inf index 9d0e76a293..bc857629f8 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -116,6 +116,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ##= SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ##= CONSUMES =20 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIM= ES_CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg= /Core/DxeIplPeim/Ia32/DxeLoadFunc.c index 96f5718444..92f2247bd4 100644 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c @@ -211,6 +211,36 @@ IsExecuteDisableBitAvailable ( return Available; } =20 +/** + The function will check if page table should be setup or not. + + @retval TRUE Page table should be created. + @retval FALSE Page table should not be created. +**/ +BOOLEAN +ToBuildPageTable ( + VOID + ) +{ + if (!IsIa32PaeSupport ()) { + return FALSE; + } + + if (IsNullDetectionEnabled ()) { + return TRUE; + } + + if (PcdGetBool (PcdCpuStackGuard)) { + return TRUE; + } + + if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) { + return TRUE; + } + + return FALSE; +} + /** Transfers control to DxeCore. =20 @@ -385,10 +415,7 @@ HandOffToDxeCore ( TopOfStack =3D (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStac= k, CPU_STACK_ALIGNMENT); =20 PageTables =3D 0; - BuildPageTablesIa32Pae =3D (BOOLEAN) (IsIa32PaeSupport () && - (IsNullDetectionEnabled () || - (PcdGetBool (PcdSetNxForStack) && - IsExecuteDisableBitAvailable ())= )); + BuildPageTablesIa32Pae =3D ToBuildPageTable(); if (BuildPageTablesIa32Pae) { PageTables =3D Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE); if (IsExecuteDisableBitAvailable ()) { 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