From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web11.16976.1676301517872236489 for ; Mon, 13 Feb 2023 07:18:38 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=dlBrqVw4; spf=pass (domain: kernel.org, ip: 139.178.84.217, mailfrom: ardb@kernel.org) 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 551D461124; Mon, 13 Feb 2023 15:18:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 21314C433A0; Mon, 13 Feb 2023 15:18:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676301516; bh=XQ/uJWi6rW+f1Al26yI9ZQCHS3S3u9Er7meEcpNOx1U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dlBrqVw4f0sssoCfVs3MtwZDR3IG5X8ciqya967+Fah9RlMz0xOe6Bvf7mhZswdNl msOrmUD3wkokNbX8L88DVbAo3v1pkDJkhN+a1e1oOMuuBf6w9ir7CiI/+Mc1+Qy+J6 SBlXeHO3iMxDK9fpl/9Jyao8Hf15CYTWg5hoSrfwnHauRfvCzR+rQPfhwIMmj444Qi a69rMmaaiW5LeH7Cli1pcehpVhtvYIswoBVdL/NhBM5jqUryyUxnH9PQhc+eAK8jgA Jtw4aCitW8UsBSpx4hzA/9nD8bdICX8Ijg+UR4CKBJ/1mvSyKckbiVQKcVtmGS3ZYl lDwbUov1H7Yzg== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Michael Kinney , Liming Gao , Jiewen Yao , Michael Kubacki , Sean Brogan , Rebecca Cran , Leif Lindholm , Sami Mujawar , Taylor Beebe , Matthew Garrett , Peter Jones , Kees Cook Subject: [RFC 03/13] MdePkg/BasePeCoffLib: Add API to keep track of relocation range Date: Mon, 13 Feb 2023 16:18:00 +0100 Message-Id: <20230213151810.2301480-4-ardb@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230213151810.2301480-1-ardb@kernel.org> References: <20230213151810.2301480-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add a library call to obtain the start and end of the region covered by relocation fixups. This will be used in a future patch to limit the range of memory that needs to be remapped with read-write-execute permissions at ExitBootServices() time. Signed-off-by: Ard Biesheuvel --- MdePkg/Include/Library/PeCoffLib.h | 25 ++++++ MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 83 +++++++++++++++++++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/Pe= CoffLib.h index b45879453785..3706c8a4e858 100644 --- a/MdePkg/Include/Library/PeCoffLib.h +++ b/MdePkg/Include/Library/PeCoffLib.h @@ -382,4 +382,29 @@ PeCoffLoaderUnloadImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext=0D );=0D =0D +/**=0D + Retrieve the range subject to relocation fixups from the recorded fixup = data=0D + of a runtime image=0D +=0D + @param ImageBase The base address of a PE/COFF image tha= t has been loaded=0D + and relocated into system memory.=0D + @param VirtImageBase The request virtual address that the PE= /COFF image is to=0D + be fixed up for.=0D + @param ImageSize The size, in bytes, of the PE/COFF imag= e.=0D + @param RelocationData A pointer to the relocation data that w= as collected when the=0D + PE/COFF image was relocated using PeCof= fLoaderRelocateImage().=0D + @param[out] RelocationRangeMin The start of the relocated range.=0D + @param[out] RelocationRangeMax The end of the relocated range.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +PeCoffLoaderGetRelocationRange (=0D + IN PHYSICAL_ADDRESS ImageBase,=0D + IN UINTN ImageSize,=0D + IN VOID *RelocationData,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMin,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMax=0D + );=0D +=0D #endif=0D diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/Bas= ePeCoffLib/BasePeCoff.c index 97a8aaf8c73d..10f3d04d2490 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -936,6 +936,8 @@ PeCoffLoaderRelocateImage ( PHYSICAL_ADDRESS BaseAddress;=0D UINT32 NumberOfRvaAndSizes;=0D UINT32 TeStrippedOffset;=0D + PHYSICAL_ADDRESS *RelocRangeStart;=0D + PHYSICAL_ADDRESS *RelocRangeEnd;=0D =0D ASSERT (ImageContext !=3D NULL);=0D =0D @@ -1043,6 +1045,21 @@ PeCoffLoaderRelocateImage ( // Run the relocation information and apply the fixups=0D //=0D FixupData =3D ImageContext->FixupData;=0D + if (FixupData !=3D NULL) {=0D + FixupData =3D ALIGN_POINTER (FixupData, sizeof (PHYSICAL_ADDRESS));= =0D +=0D + //=0D + // Use the first two UINT64s in the fixup data to keep track of the = start=0D + // and end of the region that is subject to relocation fixups.=0D + //=0D + RelocRangeStart =3D (PHYSICAL_ADDRESS *)FixupData;=0D + RelocRangeEnd =3D RelocRangeStart + 1;=0D + FixupData +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D +=0D + *RelocRangeStart =3D MAX_UINT64;=0D + *RelocRangeEnd =3D 0;=0D + }=0D +=0D while ((UINTN)RelocBase < (UINTN)RelocBaseEnd) {=0D Reloc =3D (UINT16 *)((CHAR8 *)RelocBase + sizeof (EFI_IMAGE_BASE_REL= OCATION));=0D //=0D @@ -1070,6 +1087,14 @@ PeCoffLoaderRelocateImage ( return RETURN_LOAD_ERROR;=0D }=0D =0D + //=0D + // Capture this page in the recorded relocation range=0D + //=0D + if (FixupData !=3D NULL) {=0D + *RelocRangeStart =3D MIN (*RelocRangeStart, (UINTN)FixupBase);=0D + *RelocRangeEnd =3D MAX (*RelocRangeEnd, (UINTN)FixupBase + SIZE_= 4KB);=0D + }=0D +=0D //=0D // Run this relocation record=0D //=0D @@ -1470,6 +1495,9 @@ PeCoffLoaderLoadImage ( //=0D ImageContext->FixupData =3D NULL;=0D =0D + // Add two UINT64s at the start to carry the min/max of the relocated ra= nge=0D + ImageContext->FixupDataSize +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D +=0D //=0D // Load the Codeview information if present=0D //=0D @@ -1824,7 +1852,8 @@ PeCoffLoaderRelocateImageForRuntime ( // by code will not be fixed up, since that would set them back to=0D // defaults.=0D //=0D - FixupData =3D RelocationData;=0D + FixupData =3D ALIGN_POINTER (RelocationData, sizeof (PHYSICAL_ADDR= ESS));=0D + FixupData +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D RelocBaseOrig =3D RelocBase;=0D while ((UINTN)RelocBase < (UINTN)RelocBaseEnd) {=0D //=0D @@ -1994,3 +2023,55 @@ PeCoffLoaderUnloadImage ( PeCoffLoaderUnloadImageExtraAction (ImageContext);=0D return RETURN_SUCCESS;=0D }=0D +=0D +/**=0D + Retrieve the range subject to relocation fixups from the recorded fixup = data=0D + of a runtime image=0D +=0D + @param ImageBase The base address of a PE/COFF image tha= t has been loaded=0D + and relocated into system memory.=0D + @param VirtImageBase The request virtual address that the PE= /COFF image is to=0D + be fixed up for.=0D + @param ImageSize The size, in bytes, of the PE/COFF imag= e.=0D + @param RelocationData A pointer to the relocation data that w= as collected when the=0D + PE/COFF image was relocated using PeCof= fLoaderRelocateImage().=0D + @param[out] RelocationRangeMin The start of the relocated range.=0D + @param[out] RelocationRangeMax The end of the relocated range.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +PeCoffLoaderGetRelocationRange (=0D + IN PHYSICAL_ADDRESS ImageBase,=0D + IN UINTN ImageSize,=0D + IN VOID *RelocationData,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMin,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMax=0D + )=0D +{=0D + PHYSICAL_ADDRESS *FixupData;=0D +=0D + if ((RelocationData =3D=3D NULL) || (ImageBase =3D=3D 0x0)) {=0D + return;=0D + }=0D +=0D + FixupData =3D ALIGN_POINTER (RelocationData, sizeof (PHYSICAL_ADDRESS));= =0D +=0D + if ((FixupData[0] =3D=3D MAX_UINT64) && (FixupData[1] =3D=3D 0)) {=0D + // No fixups recorded=0D + *RelocationRangeMin =3D ImageBase;=0D + *RelocationRangeMax =3D ImageBase;=0D + return;=0D + }=0D +=0D + if ((FixupData[0] < ImageBase) ||=0D + (FixupData[1] > (ImageBase + ImageSize))) {=0D + ASSERT (FALSE);=0D + *RelocationRangeMin =3D ImageBase;=0D + *RelocationRangeMax =3D ImageBase + ImageSize;=0D + return;=0D + }=0D +=0D + *RelocationRangeMin =3D FixupData[0];=0D + *RelocationRangeMax =3D FixupData[1];=0D +}=0D --=20 2.39.1