From nobody Wed Dec 25 14:01:42 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 1507558654633448.20138518683336; Mon, 9 Oct 2017 07:17:34 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2603821E87989; Mon, 9 Oct 2017 07:14:05 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 35F4221E78206 for ; Mon, 9 Oct 2017 07:14:04 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:29 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:28 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228750992" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:17 +0800 Message-Id: <20171009141722.992-2-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 1/6] MdeModulePkg/MdeModulePkg.dec, .uni: Add NULL pointer detection PCD 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 , Jiewen Yao , Ayellet Wolman , Michael Kinney , 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" From: "Wang, Jian J" PCD PcdNullPointerDetectionPropertyMask is a bitmask used to control the NULL address detection functionality in code for different phases. If enabled, accessing NULL address in UEFI or SMM code can be caught as a page fault exception. BIT0 - Enable NULL pointer detection for UEFI. BIT1 - Enable NULL pointer detection for SMM. BIT2..6 - Reserved for future uses. BIT7 - Disable NULL pointer detection just after EndOfDxe. This is a workaround for those unsolvable NULL access issues in OptionROM, boot loader, etc. It can also help to avoid unnecessary exception caused by legacy memory (0-4095) access after EndOfDxe, such as Windows 7 boot on Qemu. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- MdeModulePkg/MdeModulePkg.dec | 13 +++++++++++++ MdeModulePkg/MdeModulePkg.uni | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index a3c0633ee1..9248d10da8 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -867,6 +867,19 @@ # @ValidList 0x80000006 | 0x03058002 gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32= |0x30001040 =20 + ## Mask to control the NULL address detection in code for different phas= es. + # If enabled, accessing NULL address in UEFI or SMM code can be caught.=

+ # BIT0 - Enable NULL pointer detection for UEFI.
+ # BIT1 - Enable NULL pointer detection for SMM.
+ # BIT2..6 - Reserved for future uses.
+ # BIT7 - Disable NULL pointer detection just after EndOfDxe.
+ # This is a workaround for those unsolvable NULL access iss= ues in + # OptionROM, boot loader, etc. It can also help to avoid un= necessary + # exception caused by legacy memory (0-4095) access after E= ndOfDxe, + # such as Windows 7 boot on Qemu.
+ # @Prompt Enable NULL address detection. + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask|0x0|U= INT8|0x30001050 + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Dynamic type PCD can be registered callback function for Pcd setting = action. # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of= callback function diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni index d6015de75f..f8b31694ba 100644 --- a/MdeModulePkg/MdeModulePkg.uni +++ b/MdeModulePkg/MdeModulePkg.uni @@ -1127,3 +1127,16 @@ = "enabled on AMD processors supporting the Secure= Encrypted Virtualization (SEV) feature.\n" = "This mask should be applied when creating 1:1 v= irtual to physical mapping tables." =20 +#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdNullPointerDetectionProperty= Mask_PROMPT #language en-US "Enable NULL pointer detection" + +#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdNullPointerDetectionProperty= Mask_HELP #language en-US "Mask to control the NULL address detection in= code for different phases.\n" + = " If enabled, accessing NULL address in UEFI o= r SMM code can be caught.\n\n" + = " BIT0 - Enable NULL pointer detection fo= r UEFI.\n" + = " BIT1 - Enable NULL pointer detection fo= r SMM.\n" + = " BIT2..6 - Reserved for future uses.\n" + = " BIT7 - Disable NULL pointer detection j= ust after EndOfDxe." + = " This is a workaround for those unsolvable NU= LL access issues in" + = " OptionROM, boot loader, etc. It can also hel= p to avoid unnecessary" + = " exception caused by legacy memory (0-4095) a= ccess after EndOfDxe," + = " such as Windows 7 boot on Qemu.\n" + --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Wed Dec 25 14:01:42 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 1507558657621431.94949842437245; Mon, 9 Oct 2017 07:17:37 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6474E21EA15A5; Mon, 9 Oct 2017 07:14:05 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 6D04421CF58B4 for ; Mon, 9 Oct 2017 07:14:04 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:31 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:30 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228751007" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:18 +0800 Message-Id: <20171009141722.992-3-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 2/6] MdeModulePkg/DxeIpl: Implement NULL pointer detection 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: Michael Kinney , Ayellet Wolman , 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" > According to Start's feedback > a. Change function ClearLegacyMemory to ClearFirst4KPage > b. Call ClearFirst4KPage only when NULL detection is enabled > c. Move ClearFirst4KPage to X64/Ia32 related files NULL pointer detection is done by making use of paging mechanism of CPU. During page table setup, if enabled, the first 4-K page (0-4095) will be marked as NOT PRESENT. Any code which unintentionally access memory between 0-4095 will trigger a Page Fault exception which warns users that there's potential illegal code in BIOS. This also means that legacy code which has to access memory between 0-4095 should be cautious to temporarily disable this feature before the access and re-enable it afterwards; or disalbe this feature at all. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.h | 25 +++++++ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 1 + MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 17 ++++- MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 4 + MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 93 ++++++++++++++++++++= ++-- 6 files changed, 131 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeI= plPeim/DxeIpl.h index 72d2532f50..ecf186667a 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h @@ -240,4 +240,29 @@ Decompress ( OUT UINTN *OutputSize ); =20 +/** + Clear legacy memory located at the first 4K-page. + + This function traverses the whole HOB list to check if memory from 0 to= 4095 + exists and has not been allocated, and then clear it if so. + + @param HoStart The start of HobList passed to DxeCore. + +**/ +VOID +ClearFirst4KPage ( + IN VOID *HobStart + ); + +/** + Return configure status of NULL pointer detection feature + + @return TRUE NULL pointer detection feature is enabled + @return FALSE NULL pointer detection feature is disabled +**/ +BOOLEAN +IsNullDetectionEnabled ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/Dx= eIplPeim/DxeIpl.inf index c54afe4aa6..9d0e76a293 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -115,6 +115,7 @@ [Pcd.IA32,Pcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ##= SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES =20 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIM= ES_CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/Dxe= IplPeim/DxeLoad.c index 50b5440d15..1f626a9e86 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -825,3 +825,4 @@ UpdateStackHob ( Hob.Raw =3D GET_NEXT_HOB (Hob); } } + diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg= /Core/DxeIplPeim/Ia32/DxeLoadFunc.c index 1957326caf..96f5718444 100644 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c @@ -123,7 +123,9 @@ Create4GPageTablesIa32Pae ( PageDirectoryPointerEntry->Bits.Present =3D 1; =20 for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries < = 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += =3D SIZE_2MB) { - if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress += SIZE_2MB) > StackBase)) { + if ((IsNullDetectionEnabled () && PhysicalAddress =3D=3D 0) + || ((PhysicalAddress < StackBase + StackSize) + && ((PhysicalAddress + SIZE_2MB) > StackBase))) { // // Need to split this 2M page that covers stack range. // @@ -240,6 +242,10 @@ HandOffToDxeCore ( EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; BOOLEAN BuildPageTablesIa32Pae; =20 + if (IsNullDetectionEnabled ()) { + ClearFirst4KPage (HobList.Raw); + } + Status =3D PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PA= GES (STACK_SIZE), &BaseOfStack); ASSERT_EFI_ERROR (Status); =20 @@ -379,10 +385,15 @@ HandOffToDxeCore ( TopOfStack =3D (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStac= k, CPU_STACK_ALIGNMENT); =20 PageTables =3D 0; - BuildPageTablesIa32Pae =3D (BOOLEAN) (PcdGetBool (PcdSetNxForStack) &&= IsIa32PaeSupport () && IsExecuteDisableBitAvailable ()); + BuildPageTablesIa32Pae =3D (BOOLEAN) (IsIa32PaeSupport () && + (IsNullDetectionEnabled () || + (PcdGetBool (PcdSetNxForStack) && + IsExecuteDisableBitAvailable ())= )); if (BuildPageTablesIa32Pae) { PageTables =3D Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE); - EnableExecuteDisableBit (); + if (IsExecuteDisableBitAvailable ()) { + EnableExecuteDisableBit(); + } } =20 // diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/= Core/DxeIplPeim/X64/DxeLoadFunc.c index 6488880eab..f613221b81 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c @@ -42,6 +42,10 @@ HandOffToDxeCore ( EFI_VECTOR_HANDOFF_INFO *VectorInfo; EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; =20 + if (IsNullDetectionEnabled ()) { + ClearFirst4KPage (HobList.Raw); + } + // // Get Vector Hand-off Info PPI and build Guided HOB // diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePk= g/Core/DxeIplPeim/X64/VirtualMemory.c index 48150be4e1..a10dea25fd 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -31,6 +31,68 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHE= R EXPRESS OR IMPLIED. #include "DxeIpl.h" #include "VirtualMemory.h" =20 +/** + Clear legacy memory located at the first 4K-page, if available. + + This function traverses the whole HOB list to check if memory from 0 to= 4095 + exists and has not been allocated, and then clear it if so. + + @param HoStart The start of HobList passed to DxeCore. + +**/ +VOID +ClearFirst4KPage ( + IN VOID *HobStart + ) +{ + EFI_PEI_HOB_POINTERS RscHob; + EFI_PEI_HOB_POINTERS MemHob; + BOOLEAN DoClear; + + RscHob.Raw =3D HobStart; + MemHob.Raw =3D HobStart; + DoClear =3D FALSE; + + // + // Check if page 0 exists and free + // + while ((RscHob.Raw =3D GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, + RscHob.Raw)) !=3D NULL) { + if (RscHob.ResourceDescriptor->ResourceType =3D=3D EFI_RESOURCE_SYSTEM= _MEMORY && + RscHob.ResourceDescriptor->PhysicalStart =3D=3D 0) { + DoClear =3D TRUE; + // + // Make sure memory at 0-4095 has not been allocated. + // + while ((MemHob.Raw =3D GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, + MemHob.Raw)) !=3D NULL) { + if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + < EFI_PAGE_SIZE) { + DoClear =3D FALSE; + break; + } + MemHob.Raw =3D GET_NEXT_HOB (MemHob); + } + break; + } + RscHob.Raw =3D GET_NEXT_HOB (RscHob); + } + + if (DoClear) { + DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n")); + SetMem (NULL, EFI_PAGE_SIZE, 0); + } + + return; +} + +BOOLEAN +IsNullDetectionEnabled ( + VOID + ) +{ + return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) !=3D 0); +} =20 /** Enable Execute Disable Bit. @@ -90,8 +152,16 @@ Split2MPageTo4K ( // PageTableEntry->Uint64 =3D (UINT64) PhysicalAddress4K | AddressEncMask; PageTableEntry->Bits.ReadWrite =3D 1; - PageTableEntry->Bits.Present =3D 1; - if ((PhysicalAddress4K >=3D StackBase) && (PhysicalAddress4K < StackBa= se + StackSize)) { + + if (IsNullDetectionEnabled () && PhysicalAddress4K =3D=3D 0) { + PageTableEntry->Bits.Present =3D 0; + } else { + PageTableEntry->Bits.Present =3D 1; + } + + if (PcdGetBool (PcdSetNxForStack) + && (PhysicalAddress4K >=3D StackBase) + && (PhysicalAddress4K < StackBase + StackSize)) { // // Set Nx bit for stack. // @@ -137,9 +207,12 @@ Split1GPageTo2M ( =20 PhysicalAddress2M =3D PhysicalAddress; for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries < 51= 2; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += =3D SIZE_2MB) { - if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M= + SIZE_2MB) > StackBase)) { + if ((IsNullDetectionEnabled () && PhysicalAddress2M =3D=3D 0) + || (PcdGetBool (PcdSetNxForStack) + && (PhysicalAddress2M < StackBase + StackSize) + && ((PhysicalAddress2M + SIZE_2MB) > StackBase))) { // - // Need to split this 2M page that covers stack range. + // Need to split this 2M page that covers NULL or stack range. // Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, S= tackBase, StackSize); } else { @@ -279,7 +352,10 @@ CreateIdentityMappingPageTables ( PageDirectory1GEntry =3D (VOID *) PageDirectoryPointerEntry; =20 for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries = < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += =3D SIZE_1GB) { - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + St= ackSize) && ((PageAddress + SIZE_1GB) > StackBase)) { + if ((IsNullDetectionEnabled () && PageAddress =3D=3D 0) + || (PcdGetBool (PcdSetNxForStack) + && (PageAddress < StackBase + StackSize) + && ((PageAddress + SIZE_1GB) > StackBase))) { Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, S= tackBase, StackSize); } else { // @@ -308,9 +384,12 @@ CreateIdentityMappingPageTables ( PageDirectoryPointerEntry->Bits.Present =3D 1; =20 for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += =3D SIZE_2MB) { - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + = StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) { + if ((IsNullDetectionEnabled () && PageAddress =3D=3D 0) + || (PcdGetBool (PcdSetNxForStack) + && (PageAddress < StackBase + StackSize) + && ((PageAddress + SIZE_2MB) > StackBase))) { // - // Need to split this 2M page that covers stack range. + // Need to split this 2M page that covers NULL or stack range. // Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, S= tackBase, StackSize); } else { --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Wed Dec 25 14:01:42 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 150755866106873.41853381299609; Mon, 9 Oct 2017 07:17:41 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A0D3821EA15B1; Mon, 9 Oct 2017 07:14:07 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 E2DDC21E78215 for ; Mon, 9 Oct 2017 07:14:05 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:33 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:31 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228751022" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:19 +0800 Message-Id: <20171009141722.992-4-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 3/6] MdeModulePkg/Core/Dxe: Add EndOfDxe workaround for NULL pointer detection 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: Michael Kinney , Ayellet Wolman , 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" > According to Star's feedback, use GCD service instead of CPU arch > protocol to change page attributes One of issue caused by enabling NULL pointer detection is that some PCI device OptionROM, binary drivers and binary OS boot loaders may have NULL pointer access bugs, which will prevent BIOS from booting and is almost impossible to fix. BIT7 of PCD PcdNullPointerDetectionPropertyMask is used as a workaround to indicate BIOS to disable NULL pointer detection right after event gEfiEndOfDxeEventGroupGuid, and then let boot continue. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/Mem/Page.c | 4 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 65 +++++++++++++++++++++++= ++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeM= ain.inf index 30d5984f7c..0a161ffd71 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -192,6 +192,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable = ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy = ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy = ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask = ## CONSUMES =20 # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/P= age.c index a142c79ee2..0468df3171 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -188,7 +188,9 @@ CoreAddRange ( // used for other purposes. // =20 if (Type =3D=3D EfiConventionalMemory && Start =3D=3D 0 && (End >=3D EFI= _PAGE_SIZE - 1)) { - SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0); + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0) { + SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0); + } } =20 // diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/C= ore/Dxe/Misc/MemoryProtection.c index a73c4ccd64..0fa89e4437 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -995,6 +995,53 @@ MemoryProtectionExitBootServicesCallback ( } } =20 +/** + Disable NULL pointer detection after EndOfDxe. This is a workaround reso= rt in + order to skip unfixable NULL pointer access issues detected in OptionROM= or + boot loaders. + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +DisableNullDetectionAtTheEndOfDxe ( + EFI_EVENT Event, + VOID *Context + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; + + DEBUG ((DEBUG_INFO, "DisableNullDetectionAtTheEndOfDxe(): start\r\n")); + // + // Disable NULL pointer detection by enabling first 4K page + // + Status =3D CoreGetMemorySpaceDescriptor (0, &Desc); + ASSERT_EFI_ERROR (Status); + + if ((Desc.Capabilities & EFI_MEMORY_RP) =3D=3D 0) { + Status =3D CoreSetMemorySpaceCapabilities ( + 0, + EFI_PAGE_SIZE, + Desc.Capabilities | EFI_MEMORY_RP + ); + ASSERT_EFI_ERROR (Status); + } + + Status =3D CoreSetMemorySpaceAttributes ( + 0, + EFI_PAGE_SIZE, + Desc.Attributes & ~EFI_MEMORY_RP + ); + ASSERT_EFI_ERROR (Status); + + CoreCloseEvent (Event); + DEBUG ((DEBUG_INFO, "DisableNullDetectionAtTheEndOfDxe(): end\r\n")); + + return; +} + /** Initialize Memory Protection support. **/ @@ -1006,6 +1053,7 @@ CoreInitializeMemoryProtection ( { EFI_STATUS Status; EFI_EVENT Event; + EFI_EVENT EndOfDxeEvent; VOID *Registration; =20 mImageProtectionPolicy =3D PcdGet32(PcdImageProtectionPolicy); @@ -1044,6 +1092,23 @@ CoreInitializeMemoryProtection ( ); ASSERT_EFI_ERROR(Status); } + + // + // Register a callback to disable NULL pointer detection at EndOfDxe + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) + =3D=3D (BIT0|BIT7)) { + Status =3D CoreCreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + DisableNullDetectionAtTheEndOfDxe, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + ASSERT_EFI_ERROR (Status); + } + return ; } =20 --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Wed Dec 25 14:01:42 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 1507558664757666.1303101643572; Mon, 9 Oct 2017 07:17:44 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id DB27921E78215; Mon, 9 Oct 2017 07:14:08 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 7B4B821CF58B4 for ; Mon, 9 Oct 2017 07:14:07 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:34 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:33 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228751035" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:20 +0800 Message-Id: <20171009141722.992-5-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 4/6] UefiCpuPkg/PiSmmCpuDxeSmm: Implement NULL pointer detection for SMM code 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: Michael Kinney , Ayellet Wolman , 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" The mechanism behind is the same as NULL pointer detection enabled in EDK-II core. SMM has its own page table and we have to disable page 0 again in SMM mode. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 12 ++++++++++++ UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 25 ++++++++++++++++++++++++- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 12 ++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpu= DxeSmm/Ia32/PageTbl.c index f295c2ebf2..641a1d69a2 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -155,6 +155,18 @@ SmiPFHandler ( } } =20 + // + // If NULL pointer was just accessed + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) !=3D 0 && + (PFAddress < EFI_PAGE_SIZE)) { + DEBUG ((DEBUG_ERROR, "!!! NULL pointer access !!!\n")); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip); + ); + CpuDeadLoop (); + } + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { SmmProfilePFHandler ( SystemContext.SystemContextIa32->Eip, diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxe= Smm/MpService.c index f086b97c30..0d3223d714 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -855,10 +855,10 @@ Gen4GPageTable ( Pte[Index] =3D (Index << 21) | mAddressEncMask | IA32_PG_PS | PAGE_ATT= RIBUTE_BITS; } =20 + Pdpte =3D (UINT64*)PageTable; if (FeaturePcdGet (PcdCpuSmmStackGuard)) { Pages =3D (UINTN)PageTable + EFI_PAGES_TO_SIZE (5); GuardPage =3D mSmmStackArrayBase + EFI_PAGE_SIZE; - Pdpte =3D (UINT64*)PageTable; for (PageIndex =3D Low2MBoundary; PageIndex <=3D High2MBoundary; PageI= ndex +=3D SIZE_2MB) { Pte =3D (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30= , 31)] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1)); Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] =3D (UINT64)Pages | = mAddressEncMask | PAGE_ATTRIBUTE_BITS; @@ -886,6 +886,29 @@ Gen4GPageTable ( } } =20 + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) !=3D 0) { + Pte =3D (UINT64*)(UINTN)(Pdpte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE= - 1)); + if ((Pte[0] & IA32_PG_PS) =3D=3D 0) { + // 4K-page entries are already mapped. Just hide the first one anywa= y. + Pte =3D (UINT64*)(UINTN)(Pte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE= - 1)); + Pte[0] &=3D ~IA32_PG_P; // Hide page 0 + } else { + // Create 4K-page entries + Pages =3D (UINTN)AllocatePageTableMemory (1); + ASSERT (Pages !=3D 0); + + Pte[0] =3D (UINT64)(Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS); + + Pte =3D (UINT64*)Pages; + PageAddress =3D 0; + Pte[0] =3D PageAddress | mAddressEncMask; // Hide page 0 but present= left + for (Index =3D 1; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) { + PageAddress +=3D EFI_PAGE_SIZE; + Pte[Index] =3D PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + } + } + return (UINT32)(UINTN)PageTable; } =20 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSm= mCpuDxeSmm/PiSmmCpuDxeSmm.inf index 099792e6ce..31cb215342 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -159,6 +159,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## CONS= UMES gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONS= UMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES =20 [Depex] gEfiMpServiceProtocolGuid diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuD= xeSmm/X64/PageTbl.c index 3dde80f9ba..f3791ce897 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -872,6 +872,18 @@ SmiPFHandler ( } } =20 + // + // If NULL pointer was just accessed + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) !=3D 0 && + (PFAddress < EFI_PAGE_SIZE)) { + DEBUG ((DEBUG_ERROR, "!!! NULL pointer access !!!\n")); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip); + ); + CpuDeadLoop (); + } + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { SmmProfilePFHandler ( SystemContext.SystemContextX64->Rip, --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Wed Dec 25 14:01:42 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 1507558669049191.99871989724477; Mon, 9 Oct 2017 07:17:49 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1FBF321E78211; Mon, 9 Oct 2017 07:14:11 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 4F3B621E78211 for ; Mon, 9 Oct 2017 07:14:09 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:36 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:34 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228751043" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:21 +0800 Message-Id: <20171009141722.992-6-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 5/6] IntelFrameworkModulePkg/Csm: Add code to bypass NULL pointer detection 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: Michael Kinney , Ayellet Wolman , 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" Legacy has to access interrupt vector, BDA, etc. located in memory between 0-4095. To allow as much code as possible to be monitored by NULL pointer detection, we add code to temporarily disable this feature right before those memory access and enable it again afterwards. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c | 101 ++++++++++++++ .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h | 2 + .../Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf | 2 + .../Csm/LegacyBiosDxe/LegacyBda.c | 4 + .../Csm/LegacyBiosDxe/LegacyBios.c | 152 +++++++++++++++++= ++++ .../Csm/LegacyBiosDxe/LegacyBiosDxe.inf | 2 + .../Csm/LegacyBiosDxe/LegacyBiosInterface.h | 18 +++ .../Csm/LegacyBiosDxe/LegacyBootSupport.c | 23 +++- .../Csm/LegacyBiosDxe/LegacyPci.c | 17 ++- IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c | 27 +++- 10 files changed, 338 insertions(+), 10 deletions(-) diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard= .c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c index 7308523ad8..d2224a20aa 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c @@ -1732,6 +1732,98 @@ CheckKeyboardConnect ( } } =20 +/** + Disable NULL pointer detection +*/ +VOID +DisableNullDetection ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; + + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0) { + return; + } + + // + // Check current capabilities and attributes + // + Status =3D gDS->GetMemorySpaceDescriptor (0, &Desc); + ASSERT_EFI_ERROR (Status); + + // + // Try to add EFI_MEMORY_RP support if necessary + // + if ((Desc.Capabilities & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Capabilities |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceCapabilities (0, EFI_PAGES_TO_SIZE(1), + Desc.Capabilities); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + } + + // + // Don't bother if EFI_MEMORY_RP is already cleared. + // + if ((Desc.Attributes & EFI_MEMORY_RP) !=3D 0) { + Desc.Attributes &=3D ~EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE(1), + Desc.Attributes); + ASSERT_EFI_ERROR (Status); + } else { + DEBUG ((DEBUG_WARN, "!!! Page 0 is supposed to be disabled !!!\r\n")); + } +} + +/** + Enable NULL pointer detection +*/ +VOID +EnableNullDetection ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; + + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0) { + return; + } + + // + // Check current capabilities and attributes + // + Status =3D gDS->GetMemorySpaceDescriptor (0, &Desc); + ASSERT_EFI_ERROR (Status); + + // + // Try to add EFI_MEMORY_RP support if necessary + // + if ((Desc.Capabilities & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Capabilities |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceCapabilities (0, EFI_PAGES_TO_SIZE(1), + Desc.Capabilities); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + } + + // + // Don't bother if EFI_MEMORY_RP is already set. + // + if ((Desc.Attributes & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Attributes |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE(1), + Desc.Attributes); + ASSERT_EFI_ERROR (Status); + } +} + /** Timer event handler: read a series of key stroke from 8042 and put them into memory key buffer.=20 @@ -1839,6 +1931,11 @@ BiosKeyboardTimerHandler ( // 0 Right Shift pressed =20 =20 + // + // Disable NULL pointer detection temporarily + // + DisableNullDetection (); + // // Clear the CTRL and ALT BDA flag // @@ -1916,6 +2013,10 @@ BiosKeyboardTimerHandler ( KbFlag1 &=3D ~0x0C; =20 *((UINT8 *) (UINTN) 0x417) =3D KbFlag1;=20 =20 + // + // Restore NULL pointer detection + // + EnableNullDetection (); =20 // // Output EFI input key and shift/toggle state diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard= .h b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h index 0bf28ea140..c64ec0095e 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h @@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER= EXPRESS OR IMPLIED. =20 =20 #include +#include =20 #include #include @@ -33,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER= EXPRESS OR IMPLIED. #include #include #include +#include #include #include #include diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.= inf b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf index 4d4536466c..596f4ced44 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf @@ -60,6 +60,7 @@ DebugLib BaseLib PcdLib + DxeServicesTableLib =20 [Protocols] gEfiIsaIoProtocolGuid ## TO_START @@ -73,6 +74,7 @@ =20 [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection ## S= OMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## C= ONSUMES =20 [UserExtensions.TianoCore."ExtraFiles"] KeyboardDxeExtra.uni diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBda.c b/IntelF= rameworkModulePkg/Csm/LegacyBiosDxe/LegacyBda.c index c45d5d4c3e..c6670febee 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBda.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBda.c @@ -34,6 +34,8 @@ LegacyBiosInitBda ( BDA_STRUC *Bda; UINT8 *Ebda; =20 + DisableNullDetection (); + Bda =3D (BDA_STRUC *) ((UINTN) 0x400); Ebda =3D (UINT8 *) ((UINTN) 0x9fc00); =20 @@ -62,5 +64,7 @@ LegacyBiosInitBda ( =20 *Ebda =3D 0x01; =20 + EnableNullDetection (); + return EFI_SUCCESS; } diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c b/Intel= FrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c index 3ead2d9828..3176a989f6 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c @@ -40,6 +40,7 @@ VOID *mRuntimeSmbiosEntryPoint =3D NULL; EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint =3D 0; EFI_PHYSICAL_ADDRESS mStructureTableAddress =3D 0; UINTN mStructureTablePages =3D 0; +BOOLEAN mEndOfDxe =3D FALSE; =20 /** Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode @@ -765,6 +766,135 @@ InstallSmbiosEventCallback ( } } =20 +/** + Callback function to toggle EndOfDxe status. NULL pointer detection needs + this status to decide if it's necessary to change attributes of page 0. + + @param Event Event whose notification function is being invo= ked. + @param Context The pointer to the notification function's cont= ext, + which is implementation-dependent. + +**/ +VOID +EFIAPI +ToggleEndOfDxeStatus ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + mEndOfDxe =3D TRUE; + return; +} + +// +// Legacy BIOS needs to access memory between 0-4095, which will cause page +// fault exception if NULL pointer detection mechanism is enabled. Followi= ng +// functions can be used to disable/enable NULL pointer detection before/a= fter +// accessing those memory. +// + +/** + Enable NULL pointer detection +*/ +VOID +EnableNullDetection ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; + + if (((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0) + || + ((mEndOfDxe =3D=3D TRUE) && + ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT7|BIT0)) + =3D=3D (BIT7|BIT0))) + ) { + return; + } + + // + // Check current capabilities and attributes + // + Status =3D gDS->GetMemorySpaceDescriptor (0, &Desc); + ASSERT_EFI_ERROR (Status); + + // + // Try to add EFI_MEMORY_RP support if necessary + // + if ((Desc.Capabilities & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Capabilities |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceCapabilities (0, EFI_PAGES_TO_SIZE(1), + Desc.Capabilities); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + } + + // + // Don't bother if EFI_MEMORY_RP is already set. + // + if ((Desc.Attributes & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Attributes |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE(1), + Desc.Attributes); + ASSERT_EFI_ERROR (Status); + } +} + +/** + Disable NULL pointer detection +*/ +VOID +DisableNullDetection ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; + + if (((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0) + || + ((mEndOfDxe =3D=3D TRUE) && + ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT7|BIT0)) + =3D=3D (BIT7|BIT0))) + ) { + return; + } + + // + // Check current capabilities and attributes + // + Status =3D gDS->GetMemorySpaceDescriptor (0, &Desc); + ASSERT_EFI_ERROR (Status); + + // + // Try to add EFI_MEMORY_RP support if necessary + // + if ((Desc.Capabilities & EFI_MEMORY_RP) =3D=3D 0) { + Desc.Capabilities |=3D EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceCapabilities (0, EFI_PAGES_TO_SIZE(1), + Desc.Capabilities); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + } + + // + // Don't bother if EFI_MEMORY_RP is already cleared. + // + if ((Desc.Attributes & EFI_MEMORY_RP) !=3D 0) { + Desc.Attributes &=3D ~EFI_MEMORY_RP; + Status =3D gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE(1), + Desc.Attributes); + ASSERT_EFI_ERROR (Status); + } else { + DEBUG ((DEBUG_WARN, "!!! Page 0 is supposed to be disabled !!!\r\n")); + } +} + /** Install Driver to produce Legacy BIOS protocol. =20 @@ -802,6 +932,7 @@ LegacyBiosInstall ( UINT64 Length; UINT8 *SecureBoot; EFI_EVENT InstallSmbiosEvent; + EFI_EVENT EndOfDxeEvent; =20 // // Load this driver's image to memory @@ -964,8 +1095,10 @@ LegacyBiosInstall ( // Initialize region from 0x0000 to 4k. This initializes interrupt vector // range. // + DisableNullDetection (); gBS->SetMem ((VOID *) ClearPtr, 0x400, INITIAL_VALUE_BELOW_1K); ZeroMem ((VOID *) ((UINTN)ClearPtr + 0x400), 0xC00); + EnableNullDetection (); =20 // // Allocate pages for OPROM usage @@ -1104,12 +1237,17 @@ LegacyBiosInstall ( // // Save Unexpected interrupt vector so can restore it just prior to boot // + DisableNullDetection (); + BaseVectorMaster =3D (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_V= ECTOR_MASTER); Private->BiosUnexpectedInt =3D BaseVectorMaster[0]; IntRedirCode =3D (UINT32) (UINTN) Private->IntThunk->InterruptRedirectio= nCode; for (Index =3D 0; Index < 8; Index++) { BaseVectorMaster[Index] =3D (EFI_SEGMENT (IntRedirCode + Index * 4) <<= 16) | EFI_OFFSET (IntRedirCode + Index * 4); } + + EnableNullDetection (); + // // Save EFI value // @@ -1133,6 +1271,20 @@ LegacyBiosInstall ( ); ASSERT_EFI_ERROR (Status); =20 =20 + // + // Create callback to update status of EndOfDxe, which is needed by NULL + // pointer detection + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + ToggleEndOfDxeStatus, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + ASSERT_EFI_ERROR (Status); + // // Make a new handle and install the protocol // diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf b/= IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf index 48473a0713..6efc7f36ae 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf @@ -108,6 +108,7 @@ gEfiDiskInfoIdeInterfaceGuid ## SOMETIMES_CONSUMES ##GU= ID #Used in LegacyBiosBuildIdeData() to assure device is a disk gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ##Sy= stemTable gEfiLegacyBiosGuid ## SOMETIMES_CONSUMES ##GU= ID #Used in LegacyBiosInstallVgaRom() to locate handle buffer + gEfiEndOfDxeEventGroupGuid ## CONSUMES =20 [Guids.IA32] gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ##Sy= stemTable @@ -147,6 +148,7 @@ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize = ## CONSUMES gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase = ## CONSUMES gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize = ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask = ## CONSUMES =20 [Depex] gEfiLegacyRegion2ProtocolGuid AND gEfiLegacyInterruptProtocolGuid AND gE= fiLegacyBiosPlatformProtocolGuid AND gEfiLegacy8259ProtocolGuid AND gEfiGen= ericMemTestProtocolGuid AND gEfiCpuArchProtocolGuid AND gEfiTimerArchProtoc= olGuid AND gEfiVariableWriteArchProtocolGuid diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.= h b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h index fe9dd7463a..20dfef3fec 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h @@ -509,6 +509,8 @@ extern BBS_TABLE *mBbsTable; =20 extern EFI_GENERIC_MEMORY_TEST_PROTOCOL *gGenMemoryTest; =20 +extern BOOLEAN mEndOfDxe; + #define PORT_70 0x70 #define PORT_71 0x71 =20 @@ -1542,4 +1544,20 @@ LegacyBiosInstallVgaRom ( IN LEGACY_BIOS_INSTANCE *Private ); =20 +/** + Enable NULL pointer detection +*/ +VOID +EnableNullDetection ( + VOID + ); + +/** + Disable NULL pointer detection +*/ +VOID +DisableNullDetection ( + VOID + ); + #endif diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c = b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c index 1e098b3726..c2ac69ce69 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c @@ -1073,8 +1073,10 @@ GenericLegacyBoot ( // Use 182/10 to avoid floating point math. // LocalTime =3D (LocalTime * 182) / 10; + DisableNullDetection (); BdaPtr =3D (UINT32 *) (UINTN)0x46C; *BdaPtr =3D LocalTime; + EnableNullDetection (); =20 // // Shadow PCI ROMs. We must do this near the end since this will kick @@ -1320,6 +1322,7 @@ GenericLegacyBoot ( // set of TIANO vectors) or takes it over. // // + DisableNullDetection (); BaseVectorMaster =3D (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE= _VECTOR_MASTER); for (Index =3D 0; Index < 8; Index++) { Private->ThunkSavedInt[Index] =3D BaseVectorMaster[Index]; @@ -1327,6 +1330,7 @@ GenericLegacyBoot ( BaseVectorMaster[Index] =3D (UINT32) (Private->BiosUnexpectedInt); } } + EnableNullDetection (); =20 ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); Regs.X.AX =3D Legacy16Boot; @@ -1340,10 +1344,12 @@ GenericLegacyBoot ( 0 ); =20 + DisableNullDetection (); BaseVectorMaster =3D (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE= _VECTOR_MASTER); for (Index =3D 0; Index < 8; Index++) { BaseVectorMaster[Index] =3D Private->ThunkSavedInt[Index]; } + EnableNullDetection (); } Private->LegacyBootEntered =3D TRUE; if ((mBootMode =3D=3D BOOT_LEGACY_OS) || (mBootMode =3D=3D BOOT_UNCONVEN= TIONAL_DEVICE)) { @@ -1731,9 +1737,11 @@ LegacyBiosBuildE820 ( // // First entry is 0 to (640k - EBDA) // + DisableNullDetection (); E820Table[0].BaseAddr =3D 0; E820Table[0].Length =3D (UINT64) ((*(UINT16 *) (UINTN)0x40E) << 4); E820Table[0].Type =3D EfiAcpiAddressRangeMemory; + EnableNullDetection (); =20 // // Second entry is (640k - EBDA) to 640k @@ -1967,6 +1975,8 @@ LegacyBiosCompleteBdaBeforeBoot ( UINT16 MachineConfig; DEVICE_PRODUCER_DATA_HEADER *SioPtr; =20 + DisableNullDetection (); + Bda =3D (BDA_STRUC *) ((UINTN) 0x400); MachineConfig =3D 0; =20 @@ -2025,6 +2035,8 @@ LegacyBiosCompleteBdaBeforeBoot ( MachineConfig =3D (UINT16) (MachineConfig + 0x00 + 0x02 + (SioPtr-= >MousePresent * 0x04)); Bda->MachineConfig =3D MachineConfig; =20 + EnableNullDetection (); + return EFI_SUCCESS; } =20 @@ -2049,15 +2061,20 @@ LegacyBiosUpdateKeyboardLedStatus ( UINT8 LocalLeds; EFI_IA32_REGISTER_SET Regs; =20 - Bda =3D (BDA_STRUC *) ((UINTN) 0x400); - Private =3D LEGACY_BIOS_INSTANCE_FROM_THIS (This); + + DisableNullDetection (); + + Bda =3D (BDA_STRUC *) ((UINTN) 0x400); LocalLeds =3D Leds; Bda->LedStatus =3D (UINT8) ((Bda->LedStatus &~0x07) | LocalLeds); LocalLeds =3D (UINT8) (LocalLeds << 4); Bda->ShiftStatus =3D (UINT8) ((Bda->ShiftStatus &~0x70) | LocalLeds); LocalLeds =3D (UINT8) (Leds & 0x20); Bda->KeyboardStatus =3D (UINT8) ((Bda->KeyboardStatus &~0x20) | LocalLed= s); + + EnableNullDetection (); + // // Call into Legacy16 code to allow it to do any processing // @@ -2102,7 +2119,9 @@ LegacyBiosCompleteStandardCmosBeforeBoot ( // to large capacity drives // CMOS 14 =3D BDA 40:10 plus bit 3(display enabled) // + DisableNullDetection (); Bda =3D (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3); + EnableNullDetection (); =20 // // Force display enabled diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c b/IntelF= rameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c index 8ffdf0c1ff..d38cef3e33 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c @@ -2279,6 +2279,7 @@ LegacyBiosInstallRom ( UINTN Function; EFI_IA32_REGISTER_SET Regs; UINT8 VideoMode; + UINT8 OldVideoMode; EFI_TIME BootTime; UINT32 *BdaPtr; UINT32 LocalTime; @@ -2299,6 +2300,7 @@ LegacyBiosInstallRom ( Device =3D 0; Function =3D 0; VideoMode =3D 0; + OldVideoMode =3D 0; PhysicalAddress =3D 0; MaxRomAddr =3D PcdGet32 (PcdEndOpromShadowAddress); =20 @@ -2401,6 +2403,8 @@ LegacyBiosInstallRom ( // 2. BBS compliants drives will not change 40:75 until boot time. // 3. Onboard IDE controllers will change 40:75 // + DisableNullDetection (); + LocalDiskStart =3D (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80); if ((Private->Disk4075 + 0x80) < LocalDiskStart) { // @@ -2426,6 +2430,9 @@ LegacyBiosInstallRom ( // VideoMode =3D *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE)); } + + EnableNullDetection (); + // // Notify the platform that we are about to scan the ROM // @@ -2466,9 +2473,11 @@ LegacyBiosInstallRom ( // Multiply result by 18.2 for number of ticks since midnight. // Use 182/10 to avoid floating point math. // + DisableNullDetection (); LocalTime =3D (LocalTime * 182) / 10; BdaPtr =3D (UINT32 *) ((UINTN) 0x46C); *BdaPtr =3D LocalTime; + EnableNullDetection (); =20 // // Pass in handoff data @@ -2564,7 +2573,11 @@ LegacyBiosInstallRom ( // // Set mode settings since PrepareToScanRom may change mode // - if (VideoMode !=3D *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE))) { + DisableNullDetection (); + OldVideoMode =3D *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE)); + EnableNullDetection (); + + if (VideoMode !=3D OldVideoMode) { // // The active video mode is changed, restore it to original mode. // @@ -2604,7 +2617,9 @@ LegacyBiosInstallRom ( } } =20 + DisableNullDetection (); LocalDiskEnd =3D (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80); + EnableNullDetection (); =20 // // Allow platform to perform any required actions after the diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c b/IntelFrame= workModulePkg/Csm/LegacyBiosDxe/Thunk.c index 3d9a8b9649..f42c13cd89 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c @@ -57,7 +57,11 @@ LegacyBiosInt86 ( IN EFI_IA32_REGISTER_SET *Regs ) { - UINT32 *VectorBase; + UINT16 Segment; + UINT16 Offset; + LEGACY_BIOS_INSTANCE *Private; + + Private =3D LEGACY_BIOS_INSTANCE_FROM_THIS (This); =20 Regs->X.Flags.Reserved1 =3D 1; Regs->X.Flags.Reserved2 =3D 0; @@ -72,12 +76,15 @@ LegacyBiosInt86 ( // The base address of legacy interrupt vector table is 0. // We use this base address to get the legacy interrupt handler. // - VectorBase =3D 0; + DisableNullDetection (); + Segment =3D (UINT16)(((UINT32 *)0)[BiosInt] >> 16); + Offset =3D (UINT16)((UINT32 *)0)[BiosInt]; + EnableNullDetection (); =20 return InternalLegacyBiosFarCall ( This, - (UINT16) ((VectorBase)[BiosInt] >> 16), - (UINT16) (VectorBase)[BiosInt], + Segment, + Offset, Regs, &Regs->X.Flags, sizeof (Regs->X.Flags) @@ -293,9 +300,15 @@ InternalLegacyBiosFarCall ( UINTN EbdaBaseAddress; UINTN ReservedEbdaBaseAddress; =20 - EbdaBaseAddress =3D (*(UINT16 *) (UINTN) 0x40E) << 4; - ReservedEbdaBaseAddress =3D CONVENTIONAL_MEMORY_TOP - PcdGet32 (PcdE= bdaReservedMemorySize); - ASSERT (ReservedEbdaBaseAddress <=3D EbdaBaseAddress); + // + // Skip this part of debug code if NULL pointer detection is enabled + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) =3D=3D 0)= { + EbdaBaseAddress =3D (*(UINT16 *) (UINTN) 0x40E) << 4; + ReservedEbdaBaseAddress =3D CONVENTIONAL_MEMORY_TOP + - PcdGet32 (PcdEbdaReservedMemorySize); + ASSERT (ReservedEbdaBaseAddress <=3D EbdaBaseAddress); + } } ); =20 --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Wed Dec 25 14:01:42 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 1507558674023765.1607618633266; Mon, 9 Oct 2017 07:17:54 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5ABAC21EA15BA; Mon, 9 Oct 2017 07:14:12 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 CABC921E78211 for ; Mon, 9 Oct 2017 07:14:10 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2017 07:17:37 -0700 Received: from sunyanwa-mobl1.ccr.corp.intel.com (HELO jwang36-MOBL2.ccr.corp.intel.com) ([10.255.25.15]) by fmsmga002.fm.intel.com with ESMTP; 09 Oct 2017 07:17:36 -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.93; helo=mga11.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.42,500,1500966000"; d="scan'208";a="1228751051" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 9 Oct 2017 22:17:22 +0800 Message-Id: <20171009141722.992-7-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171009141722.992-1-jian.j.wang@intel.com> References: <20171009141722.992-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v4 6/6] OvmfPkg/QemuVideoDxe: Bypass NULL pointer detection during VBE SHIM installing 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: Michael Kinney , Ayellet Wolman , 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" QemuVideoDxe driver will link VBE SHIM into page 0. If NULL pointer detection is enabled, this driver will fail to load. NULL pointer detection bypassing code is added to prevent such problem during boot. Please note that Windows 7 will try to access VBE SHIM during boot if it's installed, and then cause boot failure. This can be fixed by setting BIT7 of PcdNullPointerDetectionPropertyMask to disable NULL pointer detection after EndOfDxe. As far as we know, there's no other OSs has such issue. Cc: Star Zeng Cc: Eric Dong Cc: Jiewen Yao Cc: Michael Kinney Cc: Ayellet Wolman Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 1 + OvmfPkg/QemuVideoDxe/VbeShim.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/Q= emuVideoDxe.inf index 577e07b0a8..ff68c99e96 100644 --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -77,3 +77,4 @@ [Pcd] gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c index e45a08e887..8ba5522cde 100644 --- a/OvmfPkg/QemuVideoDxe/VbeShim.c +++ b/OvmfPkg/QemuVideoDxe/VbeShim.c @@ -75,6 +75,20 @@ InstallVbeShim ( UINTN Printed; VBE_MODE_INFO *VbeModeInfo; =20 + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) =3D=3D= BIT0) { + DEBUG (( + DEBUG_WARN, + "%a: page 0 protected, not installing VBE shim\n", + __FUNCTION__ + )); + DEBUG (( + DEBUG_WARN, + "%a: page 0 protection prevents Windows 7 from booting anyway\n", + __FUNCTION__ + )); + return; + } + Segment0 =3D 0x00000; SegmentC =3D 0xC0000; SegmentF =3D 0xF0000; --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel