From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 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 6299B20945BC8 for ; Mon, 25 Sep 2017 17:51:25 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga105.fm.intel.com with ESMTP; 25 Sep 2017 17:54:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,438,1500966000"; d="scan'208";a="139375215" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga002.jf.intel.com with ESMTP; 25 Sep 2017 17:54:35 -0700 Received: from FMSMSX109.amr.corp.intel.com (10.18.116.9) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 25 Sep 2017 17:54:36 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by fmsmsx109.amr.corp.intel.com (10.18.116.9) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 25 Sep 2017 17:54:35 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.213]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.159]) with mapi id 14.03.0319.002; Tue, 26 Sep 2017 08:54:33 +0800 From: "Wang, Jian J" To: "Yao, Jiewen" , "edk2-devel@lists.01.org" CC: "Zeng, Star" , "Dong, Eric" , Laszlo Ersek , "Kinney, Michael D" , "Justen, Jordan L" , "Wolman, Ayellet" Thread-Topic: [PATCH v2 2/6] MdeModulePkg/DxeIpl: Implement NULL pointer detection Thread-Index: AQHTMpljxyaF1eQT702ZquneuJ//aKLFUReQgAENnBA= Date: Tue, 26 Sep 2017 00:54:33 +0000 Message-ID: References: <20170921052032.13652-1-jian.j.wang@intel.com> <20170921052032.13652-3-jian.j.wang@intel.com> <74D8A39837DF1E4DA445A8C0B3885C503A9C1BCE@shsmsx102.ccr.corp.intel.com> In-Reply-To: <74D8A39837DF1E4DA445A8C0B3885C503A9C1BCE@shsmsx102.ccr.corp.intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v2 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: , X-List-Received-Date: Tue, 26 Sep 2017 00:51:25 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Good catch. Thanks for the feedback. > -----Original Message----- > From: Yao, Jiewen > Sent: Monday, September 25, 2017 4:51 PM > To: Wang, Jian J ; edk2-devel@lists.01.org > Cc: Zeng, Star ; Dong, Eric ; L= aszlo > Ersek ; Kinney, Michael D = ; > Justen, Jordan L ; Wolman, Ayellet > > Subject: RE: [PATCH v2 2/6] MdeModulePkg/DxeIpl: Implement NULL pointer > detection >=20 > Hi > I do not think NULL pointer is related to NX. > As long as NullPointer PCD is true and IA32PAE is supported, we can build= page > table. >=20 > + BuildPageTablesIa32Pae =3D (BOOLEAN) (IsIa32PaeSupport () > + && IsExecuteDisableBitAvailable = () > + && (PcdGetBool (PcdSetNxForStack= ) > + || IsNullDetectionEnabled ()= )); >=20 >=20 >=20 >=20 > > -----Original Message----- > > From: Wang, Jian J > > Sent: Thursday, September 21, 2017 1:20 PM > > To: edk2-devel@lists.01.org > > Cc: Zeng, Star ; Dong, Eric ; > Laszlo > > Ersek ; Yao, Jiewen ; Kinney, > > Michael D ; Justen, Jordan L > > ; Wolman, Ayellet > > Subject: [PATCH v2 2/6] MdeModulePkg/DxeIpl: Implement NULL pointer > > detection > > > > 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 b= e > > 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 acces= s > > and re-enable it afterwards; or disalbe this feature at all. > > > > Cc: Star Zeng > > Cc: Eric Dong > > Cc: Laszlo Ersek > > Cc: Jiewen Yao > > Cc: Michael Kinney > > Cc: Jordan Justen > > 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 | 65 > > ++++++++++++++++++++++++ > > MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 11 +++- > > MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 2 + > > MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 31 ++++++++--- > > 6 files changed, 126 insertions(+), 9 deletions(-) > > > > diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h > > b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h > > index 72d2532f50..1654bcd2dc 100644 > > --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h > > +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h > > @@ -240,4 +240,29 @@ Decompress ( > > OUT UINTN *OutputSize > > ); > > > > +/** > > + 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 > > +ClearLegacyMemory ( > > + 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/DxeIplPeim/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 > > > > [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] > > gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## > > SOMETIMES_CONSUMES > > diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > > b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > > index 50b5440d15..0a71b1f3de 100644 > > --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > > +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > > @@ -825,3 +825,68 @@ UpdateStackHob ( > > Hob.Raw =3D GET_NEXT_HOB (Hob); > > } > > } > > + > > +/** > > + 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 > > +ClearLegacyMemory ( > > + 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) ? > > + TRUE : FALSE); > > +} > > + > > diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c > > b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c > > index 1957326caf..503cf88382 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; > > > > for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; > > IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += =3D > > SIZE_2MB) { > > - if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddre= ss + > > 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,8 @@ HandOffToDxeCore ( > > EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; > > BOOLEAN BuildPageTablesIa32Pae; > > > > + ClearLegacyMemory (HobList.Raw); > > + > > Status =3D PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_T= O_PAGES > > (STACK_SIZE), &BaseOfStack); > > ASSERT_EFI_ERROR (Status); > > > > @@ -379,7 +383,10 @@ HandOffToDxeCore ( > > TopOfStack =3D (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER > > (TopOfStack, CPU_STACK_ALIGNMENT); > > > > PageTables =3D 0; > > - BuildPageTablesIa32Pae =3D (BOOLEAN) (PcdGetBool (PcdSetNxForStack= ) && > > IsIa32PaeSupport () && IsExecuteDisableBitAvailable ()); > > + BuildPageTablesIa32Pae =3D (BOOLEAN) (IsIa32PaeSupport () > > + && IsExecuteDisableBitAvailabl= e > > () > > + && (PcdGetBool > > (PcdSetNxForStack) > > + || IsNullDetectionEnabled > > ())); > > if (BuildPageTablesIa32Pae) { > > PageTables =3D Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZ= E); > > EnableExecuteDisableBit (); > > diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c > > b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c > > index 6488880eab..d93a9c5a2d 100644 > > --- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c > > +++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c > > @@ -42,6 +42,8 @@ HandOffToDxeCore ( > > EFI_VECTOR_HANDOFF_INFO *VectorInfo; > > EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; > > > > + ClearLegacyMemory (HobList.Raw); > > + > > // > > // Get Vector Hand-off Info PPI and build Guided HOB > > // > > diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c > > b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c > > index 48150be4e1..80c1821eca 100644 > > --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c > > +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c > > @@ -90,8 +90,16 @@ Split2MPageTo4K ( > > // > > PageTableEntry->Uint64 =3D (UINT64) PhysicalAddress4K | AddressEnc= Mask; > > PageTableEntry->Bits.ReadWrite =3D 1; > > - PageTableEntry->Bits.Present =3D 1; > > - if ((PhysicalAddress4K >=3D StackBase) && (PhysicalAddress4K < Sta= ckBase + > > 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 +145,12 @@ Split1GPageTo2M ( > > > > PhysicalAddress2M =3D PhysicalAddress; > > for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries = < 512; > > IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M = +=3D > > SIZE_2MB) { > > - if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddre= ss2M + > > 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 *) PageDirectoryEntr= y, > > StackBase, StackSize); > > } else { > > @@ -279,7 +290,10 @@ CreateIdentityMappingPageTables ( > > PageDirectory1GEntry =3D (VOID *) PageDirectoryPointerEntry; > > > > for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntr= ies < 512; > > IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress +=3D > > SIZE_1GB) { > > - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase = + > > StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) { > > + if ((IsNullDetectionEnabled () && PageAddress =3D=3D 0) > > + || (PcdGetBool (PcdSetNxForStack) > > + && (PageAddress < StackBase + StackSize) > > + && ((PageAddress + SIZE_1GB) > StackBase))) { > > Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntr= y, > > StackBase, StackSize); > > } else { > > // > > @@ -308,9 +322,12 @@ CreateIdentityMappingPageTables ( > > PageDirectoryPointerEntry->Bits.Present =3D 1; > > > > for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEn= tries < > > 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += =3D > > SIZE_2MB) { > > - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBas= e + > > 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 ra= nge. > > // > > Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntr= y, > > StackBase, StackSize); > > } else { > > -- > > 2.14.1.windows.1