From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (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 6DF2C81F40 for ; Sun, 26 Feb 2017 22:46:12 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Feb 2017 22:46:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,213,1484035200"; d="scan'208";a="1135317571" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by fmsmga002.fm.intel.com with ESMTP; 26 Feb 2017 22:46:12 -0800 Received: from fmsmsx156.amr.corp.intel.com (10.18.116.74) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.248.2; Sun, 26 Feb 2017 22:46:11 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx156.amr.corp.intel.com (10.18.116.74) with Microsoft SMTP Server (TLS) id 14.3.248.2; Sun, 26 Feb 2017 22:46:11 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.88]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.132]) with mapi id 14.03.0248.002; Mon, 27 Feb 2017 14:46:09 +0800 From: "Gao, Liming" To: Ard Biesheuvel , "edk2-devel@lists.01.org" , "Yao, Jiewen" , "leif.lindholm@linaro.org" CC: "afish@apple.com" , "Kinney, Michael D" , "lersek@redhat.com" , "Tian, Feng" , "Zeng, Star" Thread-Topic: [PATCH v3 6/6] MdeModulePkg/DxeCore: implement memory protection policy Thread-Index: AQHSkF53TrHLHLoaO0uo6UOldNT5f6F8aUgA Date: Mon, 27 Feb 2017 06:46:09 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14D6E4EDC@shsmsx102.ccr.corp.intel.com> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> <1488133805-4773-7-git-send-email-ard.biesheuvel@linaro.org> In-Reply-To: <1488133805-4773-7-git-send-email-ard.biesheuvel@linaro.org> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v3 6/6] MdeModulePkg/DxeCore: implement memory protection policy X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Feb 2017 06:46:12 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ard: I have minor comment. GetPermissionAttributeForMemoryType() function head= er comment doesn't match its definition, and IsInSmm() has no function head= er.=20 Thanks Liming >-----Original Message----- >From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] >Sent: Monday, February 27, 2017 2:30 AM >To: edk2-devel@lists.01.org; Yao, Jiewen ; >leif.lindholm@linaro.org >Cc: afish@apple.com; Kinney, Michael D ; Gao, >Liming ; lersek@redhat.com; Tian, Feng >; Zeng, Star ; Ard Biesheuvel > >Subject: [PATCH v3 6/6] MdeModulePkg/DxeCore: implement memory >protection policy > >This implements a DXE memory protection policy that ensure that regions >that don't require executable permissions are mapped with the non-exec >attribute set. > >First of all, it iterates over all entries in the UEFI memory map, and >removes executable permissions according to the configured DXE memory >protection policy, as recorded in PcdDxeMemoryProtectionPolicy. > >Secondly, it sets or clears the non-executable attribute when allocating >or freeing pages, both for page based or pool based allocations. > >Note that this complements the image protection facility, which applies >strict permissions to BootServicesCode/RuntimeServicesCode regions when >the section alignment allows it. The memory protection configured by this >patch operates on non-code regions only. > >Contributed-under: TianoCore Contribution Agreement 1.0 >Signed-off-by: Ard Biesheuvel >--- > MdeModulePkg/Core/Dxe/DxeMain.h | 24 ++ > MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + > MdeModulePkg/Core/Dxe/Mem/Page.c | 4 + > MdeModulePkg/Core/Dxe/Mem/Pool.c | 7 + > MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 306 >+++++++++++++++++++- > 5 files changed, 341 insertions(+), 1 deletion(-) > >diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h >b/MdeModulePkg/Core/Dxe/DxeMain.h >index b14be9a74d8e..5668c1f2d648 100644 >--- a/MdeModulePkg/Core/Dxe/DxeMain.h >+++ b/MdeModulePkg/Core/Dxe/DxeMain.h >@@ -2949,4 +2949,28 @@ MemoryProtectionExitBootServicesCallback ( > VOID > ); > >+/** >+ Manage memory permission attributes on a memory range, according to >the >+ configured DXE memory protection policy. >+ >+ @param OldType The old memory type of the range >+ @param NewType The new memory type of the range >+ @param Memory The base address of the range >+ @param Length The size of the range (in bytes) >+ >+ @return EFI_SUCCESS If the the CPU arch protocol is not installed= yet >+ @return EFI_SUCCESS If no DXE memory protection policy has been >configured >+ @return EFI_SUCCESS If OldType and NewType use the same permissio= n >attributes >+ @return other Return value of gCpu->SetMemoryAttributes() >+ >+**/ >+EFI_STATUS >+EFIAPI >+ApplyMemoryProtectionPolicy ( >+ IN EFI_MEMORY_TYPE OldType, >+ IN EFI_MEMORY_TYPE NewType, >+ IN EFI_PHYSICAL_ADDRESS Memory, >+ IN UINT64 Length >+ ); >+ > #endif >diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf >b/MdeModulePkg/Core/Dxe/DxeMain.inf >index 371e91cb0d7e..30d5984f7c1f 100644 >--- a/MdeModulePkg/Core/Dxe/DxeMain.inf >+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf >@@ -191,6 +191,7 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath >## CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable = ## >CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy = ## >CONSUMES >+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy >## CONSUMES > > # [Hob] > # RESOURCE_DESCRIPTOR ## CONSUMES >diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c >b/MdeModulePkg/Core/Dxe/Mem/Page.c >index bda4f6397e91..86874906de58 100644 >--- a/MdeModulePkg/Core/Dxe/Mem/Page.c >+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c >@@ -1344,6 +1344,8 @@ CoreAllocatePages ( > NULL > ); > InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); >+ ApplyMemoryProtectionPolicy (EfiConventionalMemory, MemoryType, >*Memory, >+ EFI_PAGES_TO_SIZE (NumberOfPages)); > } > return Status; > } >@@ -1460,6 +1462,8 @@ CoreFreePages ( > NULL > ); > InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); >+ ApplyMemoryProtectionPolicy (MemoryType, EfiConventionalMemory, >Memory, >+ EFI_PAGES_TO_SIZE (NumberOfPages)); > } > return Status; > } >diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c >b/MdeModulePkg/Core/Dxe/Mem/Pool.c >index 410615e0dee9..63b9983b88b5 100644 >--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c >+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c >@@ -305,6 +305,10 @@ CoreAllocatePoolPagesI ( > Buffer =3D CoreAllocatePoolPages (PoolType, NoPages, Granularity); > CoreReleaseMemoryLock (); > >+ if (Buffer !=3D NULL) { >+ ApplyMemoryProtectionPolicy (EfiConventionalMemory, PoolType, >+ (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE >(NoPages)); >+ } > return Buffer; > } > >@@ -555,6 +559,9 @@ CoreFreePoolPagesI ( > CoreAcquireMemoryLock (); > CoreFreePoolPages (Memory, NoPages); > CoreReleaseMemoryLock (); >+ >+ ApplyMemoryProtectionPolicy (PoolType, EfiConventionalMemory, >+ (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, EFI_PAGES_TO_SIZE >(NoPages)); > } > > /** >diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c >b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c >index 46d88463d417..f2a69a3d0df9 100644 >--- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c >+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c >@@ -64,6 +64,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY >KIND, EITHER EXPRESS OR IMPLIED. > #define DO_NOT_PROTECT 0x00000000 > #define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001 > >+#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 >+#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 >+ >+#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ >+ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) >+ > UINT32 mImageProtectionPolicy; > > /** >@@ -647,6 +653,210 @@ UnprotectUefiImage ( > } > > /** >+ Return the EFI memory permission attribute associated with memory >+ type 'Type' under the configured DXE memory protection policy. >+**/ >+STATIC >+UINT64 >+GetPermissionAttributeForMemoryType ( >+ IN EFI_MEMORY_TYPE MemoryType >+ ) >+{ >+ UINT64 TestBit; >+ >+ if ((UINT32) MemoryType >=3D MEMORY_TYPE_OS_RESERVED_MIN) { >+ TestBit =3D BIT63; >+ } else if ((UINT32) MemoryType >=3D MEMORY_TYPE_OEM_RESERVED_MIN) >{ >+ TestBit =3D BIT62; >+ } else { >+ TestBit =3D LShiftU64 (1, MemoryType); >+ } >+ >+ if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) !=3D 0) { >+ return EFI_MEMORY_XP; >+ } else { >+ return 0; >+ } >+} >+ >+/** >+ Sort memory map entries based upon PhysicalStart, from low to high. >+ >+ @param MemoryMap A pointer to the buffer in which firmwar= e >places >+ the current memory map. >+ @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. >+ @param DescriptorSize Size, in bytes, of an individual >EFI_MEMORY_DESCRIPTOR. >+**/ >+STATIC >+VOID >+SortMemoryMap ( >+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, >+ IN UINTN MemoryMapSize, >+ IN UINTN DescriptorSize >+ ) >+{ >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; >+ EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; >+ EFI_MEMORY_DESCRIPTOR TempMemoryMap; >+ >+ MemoryMapEntry =3D MemoryMap; >+ NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, >DescriptorSize); >+ MemoryMapEnd =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap >+ MemoryMapSize); >+ while (MemoryMapEntry < MemoryMapEnd) { >+ while (NextMemoryMapEntry < MemoryMapEnd) { >+ if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry- >>PhysicalStart) { >+ CopyMem (&TempMemoryMap, MemoryMapEntry, >sizeof(EFI_MEMORY_DESCRIPTOR)); >+ CopyMem (MemoryMapEntry, NextMemoryMapEntry, >sizeof(EFI_MEMORY_DESCRIPTOR)); >+ CopyMem (NextMemoryMapEntry, &TempMemoryMap, >sizeof(EFI_MEMORY_DESCRIPTOR)); >+ } >+ >+ NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR >(NextMemoryMapEntry, DescriptorSize); >+ } >+ >+ MemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, >DescriptorSize); >+ NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR >(MemoryMapEntry, DescriptorSize); >+ } >+} >+ >+/** >+ Merge adjacent memory map entries if they use the same memory >protection policy >+ >+ @param[in, out] MemoryMap A pointer to the buffer in whic= h >firmware places >+ the current memory map. >+ @param[in, out] MemoryMapSize A pointer to the size, in bytes= , of >the >+ MemoryMap buffer. On input, thi= s is the size of >+ the current memory map. On out= put, >+ it is the size of new memory ma= p after merge. >+ @param[in] DescriptorSize Size, in bytes, of an individua= l >EFI_MEMORY_DESCRIPTOR. >+**/ >+STATIC >+VOID >+MergeMemoryMapForProtectionPolicy ( >+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, >+ IN OUT UINTN *MemoryMapSize, >+ IN UINTN DescriptorSize >+ ) >+{ >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; >+ UINT64 MemoryBlockLength; >+ EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; >+ EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; >+ UINT64 Attributes; >+ >+ SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); >+ >+ MemoryMapEntry =3D MemoryMap; >+ NewMemoryMapEntry =3D MemoryMap; >+ MemoryMapEnd =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap >+ *MemoryMapSize); >+ while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { >+ CopyMem (NewMemoryMapEntry, MemoryMapEntry, >sizeof(EFI_MEMORY_DESCRIPTOR)); >+ NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR >(MemoryMapEntry, DescriptorSize); >+ >+ do { >+ MemoryBlockLength =3D (UINT64) >(EFI_PAGES_TO_SIZE((UINTN)MemoryMapEntry->NumberOfPages)); >+ Attributes =3D GetPermissionAttributeForMemoryType >(MemoryMapEntry->Type); >+ >+ if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && >+ Attributes =3D=3D GetPermissionAttributeForMemoryType >(NextMemoryMapEntry->Type) && >+ ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) =3D=3D >NextMemoryMapEntry->PhysicalStart)) { >+ MemoryMapEntry->NumberOfPages +=3D NextMemoryMapEntry- >>NumberOfPages; >+ if (NewMemoryMapEntry !=3D MemoryMapEntry) { >+ NewMemoryMapEntry->NumberOfPages +=3D NextMemoryMapEntry- >>NumberOfPages; >+ } >+ >+ NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR >(NextMemoryMapEntry, DescriptorSize); >+ continue; >+ } else { >+ MemoryMapEntry =3D PREVIOUS_MEMORY_DESCRIPTOR >(NextMemoryMapEntry, DescriptorSize); >+ break; >+ } >+ } while (TRUE); >+ >+ MemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, >DescriptorSize); >+ NewMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR >(NewMemoryMapEntry, DescriptorSize); >+ } >+ >+ *MemoryMapSize =3D (UINTN)NewMemoryMapEntry - >(UINTN)MemoryMap; >+ >+ return ; >+} >+ >+ >+/** >+ Remove exec permissions from all regions whose type is identified by >+ PcdDxeNxMemoryProtectionPolicy >+**/ >+STATIC >+VOID >+InitializeDxeNxMemoryProtectionPolicy ( >+ VOID >+ ) >+{ >+ UINTN MemoryMapSize; >+ UINTN MapKey; >+ UINTN DescriptorSize; >+ UINT32 DescriptorVersion; >+ EFI_MEMORY_DESCRIPTOR *MemoryMap; >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; >+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; >+ EFI_STATUS Status; >+ UINT64 Attributes; >+ >+ // >+ // Get the EFI memory map. >+ // >+ MemoryMapSize =3D 0; >+ MemoryMap =3D NULL; >+ >+ Status =3D gBS->GetMemoryMap ( >+ &MemoryMapSize, >+ MemoryMap, >+ &MapKey, >+ &DescriptorSize, >+ &DescriptorVersion >+ ); >+ ASSERT (Status =3D=3D EFI_BUFFER_TOO_SMALL); >+ do { >+ MemoryMap =3D (EFI_MEMORY_DESCRIPTOR *) AllocatePool >(MemoryMapSize); >+ ASSERT (MemoryMap !=3D NULL); >+ Status =3D gBS->GetMemoryMap ( >+ &MemoryMapSize, >+ MemoryMap, >+ &MapKey, >+ &DescriptorSize, >+ &DescriptorVersion >+ ); >+ if (EFI_ERROR (Status)) { >+ FreePool (MemoryMap); >+ } >+ } while (Status =3D=3D EFI_BUFFER_TOO_SMALL); >+ ASSERT_EFI_ERROR (Status); >+ >+ DEBUG((DEBUG_ERROR, "%a: removing exec permissions from memory >regions\n", >+ __FUNCTION__)); >+ >+ MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, >DescriptorSize); >+ >+ MemoryMapEntry =3D MemoryMap; >+ MemoryMapEnd =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap >+ MemoryMapSize); >+ while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) { >+ >+ Attributes =3D GetPermissionAttributeForMemoryType (MemoryMapEntry- >>Type); >+ if (Attributes !=3D 0) { >+ SetUefiImageMemoryAttributes ( >+ MemoryMapEntry->PhysicalStart, >+ EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages), >+ Attributes); >+ } >+ MemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, >DescriptorSize); >+ } >+ FreePool (MemoryMap); >+} >+ >+ >+/** > A notification for CPU_ARCH protocol. > > @param[in] Event Event whose notification function is = being >invoked. >@@ -674,6 +884,17 @@ MemoryProtectionCpuArchProtocolNotify ( > return; > } > >+ // >+ // Apply the memory protection policy on non-BScode/RTcode regions. >+ // >+ if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) !=3D 0) { >+ InitializeDxeNxMemoryProtectionPolicy (); >+ } >+ >+ if (mImageProtectionPolicy =3D=3D 0) { >+ return; >+ } >+ > Status =3D gBS->LocateHandleBuffer ( > ByProtocol, > &gEfiLoadedImageProtocolGuid, >@@ -753,7 +974,7 @@ CoreInitializeMemoryProtection ( > > mImageProtectionPolicy =3D PcdGet32(PcdImageProtectionPolicy); > >- if (mImageProtectionPolicy !=3D 0) { >+ if (mImageProtectionPolicy !=3D 0 || PcdGet64 >(PcdDxeNxMemoryProtectionPolicy) !=3D 0) { > Status =3D CoreCreateEvent ( > EVT_NOTIFY_SIGNAL, > TPL_CALLBACK, >@@ -775,3 +996,86 @@ CoreInitializeMemoryProtection ( > } > return ; > } >+ >+STATIC >+BOOLEAN >+IsInSmm ( >+ VOID >+ ) >+{ >+ BOOLEAN InSmm; >+ >+ InSmm =3D FALSE; >+ if (gSmmBase2 !=3D NULL) { >+ gSmmBase2->InSmm (gSmmBase2, &InSmm); >+ } >+ return InSmm; >+} >+ >+/** >+ Manage memory permission attributes on a memory range, according to >the >+ configured DXE memory protection policy. >+ >+ @param OldType The old memory type of the range >+ @param NewType The new memory type of the range >+ @param Memory The base address of the range >+ @param Length The size of the range (in bytes) >+ >+ @return EFI_SUCCESS If we are executing in SMM mode. No permissio= n >attributes >+ are updated in this case >+ @return EFI_SUCCESS If the the CPU arch protocol is not installed= yet >+ @return EFI_SUCCESS If no DXE memory protection policy has been >configured >+ @return EFI_SUCCESS If OldType and NewType use the same permissio= n >attributes >+ @return other Return value of gCpu->SetMemoryAttributes() >+ >+**/ >+EFI_STATUS >+EFIAPI >+ApplyMemoryProtectionPolicy ( >+ IN EFI_MEMORY_TYPE OldType, >+ IN EFI_MEMORY_TYPE NewType, >+ IN EFI_PHYSICAL_ADDRESS Memory, >+ IN UINT64 Length >+ ) >+{ >+ UINT64 OldAttributes; >+ UINT64 NewAttributes; >+ >+ // >+ // The policy configured in PcdDxeNxMemoryProtectionPolicy >+ // does not apply to allocations performed in SMM mode. >+ // >+ if (IsInSmm ()) { >+ return EFI_SUCCESS; >+ } >+ >+ // >+ // If the CPU arch protocol is not installed yet, we cannot manage memo= ry >+ // permission attributes, and it is the job of the driver that installs= this >+ // protocol to set the permissions on existing allocations. >+ // >+ if (gCpu =3D=3D NULL) { >+ return EFI_SUCCESS; >+ } >+ >+ // >+ // Check if a DXE memory protection policy has been configured >+ // >+ if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) =3D=3D 0) { >+ return EFI_SUCCESS; >+ } >+ >+ // >+ // Update the executable permissions according to the DXE memory >+ // protection policy, but only if the policy is different between >+ // the old and the new type. >+ // >+ OldAttributes =3D GetPermissionAttributeForMemoryType (OldType); >+ NewAttributes =3D GetPermissionAttributeForMemoryType (NewType); >+ >+ if (OldAttributes =3D=3D NewAttributes) { >+ return EFI_SUCCESS; >+ } >+ >+ return gCpu->SetMemoryAttributes (gCpu, Memory, Length, >NewAttributes); >+} >-- >2.7.4