From nobody Tue Feb 10 06:52:31 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+105370+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+105370+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1685355463; cv=none; d=zohomail.com; s=zohoarc; b=PU8yB8u2ewHHp11ZI5WP0fXOsCBDCZi3iiSAMV6DW0qcCFgYPvMyjViw04ncwRLiZgpTRfiwk+evTAwbtkJmGaI0xAazvdAhlXtaDtTy0bQGvOIs6VAIyta6+iKymPgfTRwC6uudmVqtRCeiFwjFtnRWlxL0zFNl0xiQVFYZDL8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1685355463; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=AWBg6q7uwLq5yhcch+sbehwBookYGjC9o6Nx4KYhEag=; b=nGZBAM5Xg9781nriXGhlvMQRrxeibFv5i1RUIg6HLrSTFXJrzaLfcKmlnkLEO/zyTOAHppdQdocFjRhuJoij3MHVOKLMKufqk35is0uYBu4UJgA5mFl33K42HDgCilaY2YM9GBBixhVcg9wJmT+ypgkj7mvAO0nZGD3oPzhArc4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+105370+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1685355463300368.3962502082304; Mon, 29 May 2023 03:17:43 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 2KUDYY1788612x84RI1HSAZt; Mon, 29 May 2023 03:17:42 -0700 X-Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web10.46512.1685355461422191016 for ; Mon, 29 May 2023 03:17:41 -0700 X-Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EA72561362; Mon, 29 May 2023 10:17:40 +0000 (UTC) X-Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1FE6C433D2; Mon, 29 May 2023 10:17:37 +0000 (UTC) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Ray Ni , Jiewen Yao , Gerd Hoffmann , Taylor Beebe , Oliver Smith-Denny , Dandan Bi , Liming Gao , "Kinney, Michael D" , Leif Lindholm , Michael Kubacki Subject: [edk2-devel] [RFC PATCH 08/11] MdeModulePkg/DxeIpl: Relocate and remap XIP capable DXE drivers Date: Mon, 29 May 2023 12:17:02 +0200 Message-Id: <20230529101705.2476949-9-ardb@kernel.org> In-Reply-To: <20230529101705.2476949-1-ardb@kernel.org> References: <20230529101705.2476949-1-ardb@kernel.org> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ardb@kernel.org X-Gm-Message-State: oFL1oPMHU8rtQ9eBHOGPt17cx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1685355462; bh=kOFMUKMhKISEB80t6YzTzVvir+SClZRFyDyYHGp+V1c=; h=Cc:Date:From:Reply-To:Subject:To; b=X0tdRczr8T091McgFbf3uR1m+wAvEi93k6xnUJIb/aLHEwetPb/HdQLlU1CW+V974wA d4JoamcexCAqVgYeS/iCdgWhYLjCVR9YqbTA2otROQQVwYPQsiTkPVSK/4G0ka7uWdLBH CnHz/vZBcpgwV8zO0vRcentV972e7v6HQtw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1685355463911100001 Content-Type: text/plain; charset="utf-8" Before handing over to the DXE core, iterate over all known FFS files and find the ones that can execute in place. These files are then relocated in place and mapped with restricted permissions, allowing the DXE core to dispatch them without the need to perform any manipulation of the file contents or the page table permissions. Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 196 ++++++++++++++++++++ 2 files changed, 197 insertions(+) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/Dx= eIplPeim/DxeIpl.inf index f1990eac77607854..60112100df78b396 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -65,6 +65,7 @@ [LibraryClasses] PeimEntryPoint DebugLib DebugAgentLib + PeCoffLib PeiServicesTablePointerLib PerformanceLib =20 diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/Dxe= IplPeim/DxeLoad.c index 2c19f1a507baf34a..1f20db1faffbd1d2 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -10,6 +10,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 #include "DxeIpl.h" =20 +#include +#include + // // Module Globals used in the DXE to PEI hand off // These must be module globals, so the stack can be switched @@ -228,6 +231,197 @@ ValidateMemoryTypeInfoVariable ( return TRUE; } =20 +/** + Support routine for the PE/COFF Loader that reads a buffer from a PE/COF= F file. + The function is used for XIP code to have optimized memory copy. + + @param FileHandle The handle to the PE/COFF file + @param FileOffset The offset, in bytes, into the file to read + @param ReadSize The number of bytes to read from the file startin= g at FileOffset + @param Buffer A pointer to the buffer to read the data into. + + @return EFI_SUCCESS ReadSize bytes of data were read into Buffer from= the + PE/COFF file starting at FileOffset + +**/ +STATIC +EFI_STATUS +EFIAPI +PeiImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + CHAR8 *Destination8; + CHAR8 *Source8; + + Destination8 =3D Buffer; + Source8 =3D (CHAR8 *)((UINTN)FileHandle + FileOffset); + if (Destination8 !=3D Source8) { + CopyMem (Destination8, Source8, *ReadSize); + } + + return EFI_SUCCESS; +} + +STATIC +VOID +RemapImage ( + IN EDKII_MEMORY_ATTRIBUTE_PPI *MemoryPpi, + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_SECTION_HEADER *Section; + PHYSICAL_ADDRESS SectionAddress; + EFI_STATUS Status; + UINT64 Permissions; + UINTN Index; + + if (MemoryPpi =3D=3D NULL) { + return; + } + + Hdr.Union =3D (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 *)ImageContext-= >Handle + + ImageContext->PeCoffHead= erOffset); + ASSERT (Hdr.Pe32->Signature =3D=3D EFI_IMAGE_NT_SIGNATURE); + + Section =3D (EFI_IMAGE_SECTION_HEADER *)((UINT8 *)Hdr.Union + sizeof (UI= NT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + Hdr.Pe32->FileHeader.SizeOfOption= alHeader + ); + + for (Index =3D 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++= ) { + SectionAddress =3D ImageContext->ImageAddress + Section[Index].Virtual= Address; + Permissions =3D 0; + + if ((Section[Index].Characteristics & EFI_IMAGE_SCN_MEM_WRITE) =3D=3D = 0) { + Permissions |=3D EFI_MEMORY_RO; + } + + if ((Section[Index].Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) =3D= =3D 0) { + Permissions |=3D EFI_MEMORY_XP; + } + + Status =3D MemoryPpi->SetPermissions ( + MemoryPpi, + SectionAddress, + Section[Index].Misc.VirtualSize, + Permissions, + Permissions ^ EFI_MEMORY_RO ^ EFI_MEMORY_XP + ); + ASSERT_EFI_ERROR (Status); + } +} + +STATIC +VOID +RelocateAndRemapDriversInPlace ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 AuthenticationState; + EDKII_MEMORY_ATTRIBUTE_PPI *MemoryPpi; + + MemoryPpi =3D NULL; + PeiServicesLocatePpi (&gEdkiiMemoryAttributePpiGuid, 0, NULL, (VOID **)&= MemoryPpi); + + Instance =3D 0; + do { + // + // Traverse all firmware volume instances + // + Status =3D PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + if (Status =3D=3D EFI_NOT_FOUND) { + return; + } + + ASSERT_EFI_ERROR (Status); + + FileHandle =3D NULL; + do { + Status =3D PeiServicesFfsFindNextFile ( + EFI_FV_FILETYPE_DRIVER, + VolumeHandle, + &FileHandle); + if (Status =3D=3D EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + + ZeroMem (&ImageContext, sizeof (ImageContext)); + + Status =3D PeiServicesFfsFindSectionData3 ( + EFI_SECTION_PE32, + 0, + FileHandle, + &ImageContext.Handle, + &AuthenticationState + ); + if (Status =3D=3D EFI_NOT_FOUND) { + continue; + } + + ASSERT_EFI_ERROR (Status); + + ImageContext.ImageRead =3D PeiImageRead; + Status =3D PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + continue; + } + + ImageContext.ImageAddress =3D (PHYSICAL_ADDRESS)(UINTN)ImageContext.= Handle; + if ((ImageContext.ImageAddress & (ImageContext.SectionAlignment - 1)= ) !=3D 0) { + DEBUG ((DEBUG_VERBOSE, "%a: skip PE image at %p\n", __func__, Imag= eContext.Handle)); + continue; + } + + DEBUG (( + DEBUG_INFO, + "%a: relocate PE image at %p for execution in place\n", + __func__, + ImageContext.Handle + )); + + // + // 'Load' the image in-place - this just performs a sanity check on + // the PE metadata but does not actually move any data + // + Status =3D PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + continue; + } + + // + // Relocate this driver in place + // + Status =3D PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + continue; + } + + // + // Apply section permissions to the page tables + // + RemapImage (MemoryPpi, &ImageContext); + + } while (TRUE); + + Instance++; + } while (TRUE); +} + /** Main entry point to last PEIM. =20 @@ -436,6 +630,8 @@ DxeLoadCore ( DxeCoreEntryPoint ); =20 + RelocateAndRemapDriversInPlace (); + // // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT // --=20 2.39.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105370): https://edk2.groups.io/g/devel/message/105370 Mute This Topic: https://groups.io/mt/99197142/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-