From nobody Fri Nov 1 04:33:20 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 1523025831058955.6020370441989; Fri, 6 Apr 2018 07:43:51 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 9A88D22620E7A; Fri, 6 Apr 2018 07:43:49 -0700 (PDT) Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id 9F1AE22620E64 for ; Fri, 6 Apr 2018 07:43:47 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 57C991529; Fri, 6 Apr 2018 07:43:47 -0700 (PDT) Received: from u201365.usa.Arm.com (bc-c3-3-14.eu.iaas.arm.com [10.6.43.238]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D3FA23F587; Fri, 6 Apr 2018 07:43:45 -0700 (PDT) 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=217.140.101.70; helo=foss.arm.com; envelope-from=supreeth.venkatesh@arm.com; receiver=edk2-devel@lists.01.org From: Supreeth Venkatesh To: edk2-devel@lists.01.org Date: Fri, 6 Apr 2018 15:42:20 +0100 Message-Id: <20180406144223.10931-16-supreeth.venkatesh@arm.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180406144223.10931-1-supreeth.venkatesh@arm.com> References: <20180406144223.10931-1-supreeth.venkatesh@arm.com> Subject: [edk2] [PATCH v1 15/18] ArmPkg: Extra action to update permissions for S-ELO MM Image. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, jiewen.yao@intel.com, liming.gao@intel.com, michael.d.kinney@intel.com 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 Standalone MM drivers runs in S-EL0 in AArch64 on ARM Standard Platforms and is deployed during SEC phase. The memory allocated to the Standalone MM drivers should be marked as RO+X. During PE/COFF Image section parsing, this patch implements extra action "UpdatePeCoffPermissions" to request the privileged firmware in EL3 to update the permissions. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Achin Gupta Signed-off-by: Supreeth Venkatesh --- .../DebugPeCoffExtraActionLib.c | 185 +++++++++++++++++= ++-- .../DebugPeCoffExtraActionLib.inf | 7 + 2 files changed, 181 insertions(+), 11 deletions(-) diff --git a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActio= nLib.c b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib= .c index f298e58cdf..c87aaf05c7 100644 --- a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c +++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c @@ -15,14 +15,165 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EIT= HER EXPRESS OR IMPLIED. **/ =20 #include -#include =20 +#include #include -#include #include +#include +#include +#include #include #include =20 +typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +STATIC +RETURN_STATUS +UpdatePeCoffPermissions ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN REGION_PERMISSION_UPDATE_FUNC NoExecUpdater, + IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater + ) +{ + RETURN_STATUS Status; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; + UINTN Size; + UINTN ReadSize; + UINT32 SectionHeaderOffset; + UINTN NumberOfSections; + UINTN Index; + EFI_IMAGE_SECTION_HEADER SectionHeader; + PE_COFF_LOADER_IMAGE_CONTEXT TmpContext; + EFI_PHYSICAL_ADDRESS Base; + + // + // We need to copy ImageContext since PeCoffLoaderGetImageInfo () + // will mangle the ImageAddress field + // + CopyMem (&TmpContext, ImageContext, sizeof (TmpContext)); + + if (TmpContext.PeCoffHeaderOffset =3D=3D 0) { + Status =3D PeCoffLoaderGetImageInfo (&TmpContext); + if (RETURN_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: PeCoffLoaderGetImageInfo () failed (Status =3D %r)\n", + __FUNCTION__, Status)); + return Status; + } + } + + if (TmpContext.IsTeImage && + TmpContext.ImageAddress =3D=3D ImageContext->ImageAddress) { + DEBUG ((DEBUG_INFO, "%a: ignoring XIP TE image at 0x%lx\n", __FUNCTION= __, + ImageContext->ImageAddress)); + return RETURN_SUCCESS; + } + + if (TmpContext.SectionAlignment < EFI_PAGE_SIZE) { + // + // The sections need to be at least 4 KB aligned, since that is the + // granularity at which we can tighten permissions. So just clear the + // noexec permissions on the entire region. + // + if (!TmpContext.IsTeImage) { + DEBUG ((DEBUG_WARN, + "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n", + __FUNCTION__, ImageContext->ImageAddress, TmpContext.SectionAlignm= ent)); + } + Base =3D ImageContext->ImageAddress & ~(EFI_PAGE_SIZE - 1); + Size =3D ImageContext->ImageAddress - Base + ImageContext->ImageSize; + return NoExecUpdater (Base, ALIGN_VALUE (Size, EFI_PAGE_SIZE)); + } + + // + // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much + // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Mag= ic + // determines if this is a PE32 or PE32+ image. The magic is in the same + // location in both images. + // + Hdr.Union =3D &HdrData; + Size =3D sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); + ReadSize =3D Size; + Status =3D TmpContext.ImageRead (TmpContext.Handle, + TmpContext.PeCoffHeaderOffset, &Size, Hdr.Pe32); + if (RETURN_ERROR (Status) || (Size !=3D ReadSize)) { + DEBUG ((DEBUG_ERROR, + "%a: TmpContext.ImageRead () failed (Status =3D %r)\n", + __FUNCTION__, Status)); + return Status; + } + + ASSERT (Hdr.Pe32->Signature =3D=3D EFI_IMAGE_NT_SIGNATURE); + + SectionHeaderOffset =3D TmpContext.PeCoffHeaderOffset + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER); + NumberOfSections =3D (UINTN)(Hdr.Pe32->FileHeader.NumberOfSections); + + switch (Hdr.Pe32->OptionalHeader.Magic) { + case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: + SectionHeaderOffset +=3D Hdr.Pe32->FileHeader.SizeOfOptionalHeader; + break; + case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC: + SectionHeaderOffset +=3D Hdr.Pe32Plus->FileHeader.SizeOfOptionalHead= er; + break; + default: + ASSERT (FALSE); + } + + // + // Iterate over the sections + // + for (Index =3D 0; Index < NumberOfSections; Index++) { + // + // Read section header from file + // + Size =3D sizeof (EFI_IMAGE_SECTION_HEADER); + ReadSize =3D Size; + Status =3D TmpContext.ImageRead (TmpContext.Handle, SectionHeaderOffse= t, + &Size, &SectionHeader); + if (RETURN_ERROR (Status) || (Size !=3D ReadSize)) { + DEBUG ((DEBUG_ERROR, + "%a: TmpContext.ImageRead () failed (Status =3D %r)\n", + __FUNCTION__, Status)); + return Status; + } + + Base =3D TmpContext.ImageAddress + SectionHeader.VirtualAddress; + + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D= 0) { + + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) =3D=3D= 0 && + TmpContext.ImageType !=3D EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER= ) { + + DEBUG ((DEBUG_INFO, + "%a: Mapping section %d of image at 0x%lx with RO-XN permissions= and size 0x%x\n", + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); + ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize); + } else { + DEBUG ((DEBUG_WARN, + "%a: Mapping section %d of image at 0x%lx with RW-XN permissions= and size 0x%x\n", + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); + } + } else { + DEBUG ((DEBUG_INFO, + "%a: Mapping section %d of image at 0x%lx with RO-XN permissions= and size 0x%x\n", + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); + ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize); + + DEBUG ((DEBUG_INFO, + "%a: Mapping section %d of image at 0x%lx with RO-X permissions = and size 0x%x\n", + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); + NoExecUpdater (Base, SectionHeader.Misc.VirtualSize); + } + + SectionHeaderOffset +=3D sizeof (EFI_IMAGE_SECTION_HEADER); + } + return RETURN_SUCCESS; +} =20 /** If the build is done on cygwin the paths are cygpaths. @@ -83,23 +234,29 @@ PeCoffLoaderRelocateImageExtraAction ( CHAR8 Temp[512]; #endif =20 + if (PcdGetBool(PcdStandaloneMmEnable) =3D=3D TRUE) + { + UpdatePeCoffPermissions (ImageContext, ArmClearMemoryRegionNoExec, + ArmSetMemoryRegionReadOnly); + } + if (ImageContext->PdbPointer) { #ifdef __CC_ARM #if (__ARMCC_VERSION < 500000) // Print out the command for the RVD debugger to load symbols for this= image - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "load /a /ni /np %a &0x%p\n", DeCygwi= nPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Imag= eContext->ImageAddress + ImageContext->SizeOfHeaders))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwi= nPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Imag= eContext->ImageAddress + ImageContext->SizeOfHeaders))); #else // Print out the command for the DS-5 to load symbols for this image - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "add-symbol-file %a 0x%p\n", DeCygwin= PathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Image= Context->ImageAddress + ImageContext->SizeOfHeaders))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", DeCygwin= PathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Image= Context->ImageAddress + ImageContext->SizeOfHeaders))); #endif #elif __GNUC__ // This may not work correctly if you generate PE/COFF directlyas then= the Offset would not be required - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "add-symbol-file %a 0x%p\n", DeCygwin= PathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Image= Context->ImageAddress + ImageContext->SizeOfHeaders))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", DeCygwin= PathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Image= Context->ImageAddress + ImageContext->SizeOfHeaders))); #else - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Loading driver at 0x%11p EntryPoint= =3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_PO= INT (ImageContext->EntryPoint))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint= =3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_PO= INT (ImageContext->EntryPoint))); #endif } else { - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Loading driver at 0x%11p EntryPoint= =3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_PO= INT (ImageContext->EntryPoint))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint= =3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_PO= INT (ImageContext->EntryPoint))); } } =20 @@ -125,17 +282,23 @@ PeCoffLoaderUnloadImageExtraAction ( CHAR8 Temp[512]; #endif =20 + if (PcdGetBool(PcdStandaloneMmEnable) =3D=3D TRUE) + { + UpdatePeCoffPermissions (ImageContext, ArmSetMemoryRegionNoExec, + ArmClearMemoryRegionReadOnly); + } + if (ImageContext->PdbPointer) { #ifdef __CC_ARM // Print out the command for the RVD debugger to load symbols for this= image - DEBUG ((EFI_D_ERROR, "unload symbols_only %a\n", DeCygwinPathIfNeeded = (ImageContext->PdbPointer, Temp, sizeof (Temp)))); + DEBUG ((DEBUG_ERROR, "unload symbols_only %a\n", DeCygwinPathIfNeeded = (ImageContext->PdbPointer, Temp, sizeof (Temp)))); #elif __GNUC__ // This may not work correctly if you generate PE/COFF directlyas then= the Offset would not be required - DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfN= eeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext= ->ImageAddress + ImageContext->SizeOfHeaders))); + DEBUG ((DEBUG_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfN= eeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext= ->ImageAddress + ImageContext->SizeOfHeaders))); #else - DEBUG ((EFI_D_ERROR, "Unloading %a\n", ImageContext->PdbPointer)); + DEBUG ((DEBUG_ERROR, "Unloading %a\n", ImageContext->PdbPointer)); #endif } else { - DEBUG ((EFI_D_ERROR, "Unloading driver at 0x%11p\n", (VOID *)(UINTN) I= mageContext->ImageAddress)); + DEBUG ((DEBUG_ERROR, "Unloading driver at 0x%11p\n", (VOID *)(UINTN) I= mageContext->ImageAddress)); } } diff --git a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActio= nLib.inf b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionL= ib.inf index c1f717e5bd..38bf3993ae 100644 --- a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf +++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf @@ -33,7 +33,14 @@ DebugPeCoffExtraActionLib.c =20 [Packages] + ArmPkg/ArmPkg.dec MdePkg/MdePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[FeaturePcd] + gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable =20 [LibraryClasses] + ArmMmuLib DebugLib + PcdLib --=20 2.16.2 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel