From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web08.2942.1623477812804127942 for ; Fri, 11 Jun 2021 23:03:32 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: ray.ni@intel.com) IronPort-SDR: RQtcDpA6/ncgYCQWUfpvg6B8LxqwavevSLJFZ7uEAFMUaQmhqcbcfZUzXQ4CINdGIj9RMCSl0Q 6B1Ku+1BUgTg== X-IronPort-AV: E=McAfee;i="6200,9189,10012"; a="186021770" X-IronPort-AV: E=Sophos;i="5.83,268,1616482800"; d="scan'208";a="186021770" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2021 23:03:32 -0700 IronPort-SDR: fz1jIC5JIpsjts73zsxpg7QnYTqSrxENDHPxEJjJpB71jUONVMXXzGM5C66EqPme+fA1OqghKD De45UiNkfbdQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,268,1616482800"; d="scan'208";a="553615910" Received: from ray-dev.ccr.corp.intel.com ([10.239.158.87]) by fmsmga001.fm.intel.com with ESMTP; 11 Jun 2021 23:03:30 -0700 From: "Ni, Ray" To: devel@edk2.groups.io Cc: =?UTF-8?q?Marvin=20H=C3=A4user?= , Guo Dong , Benjamin You Subject: [PATCH] UefiPayloadPkg/PayloadLoader: Add more checks to verify ELF images Date: Sat, 12 Jun 2021 14:03:04 +0800 Message-Id: <20210612060304.43-1-ray.ni@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable More checks are added to verify ELF image. ParseElfImage() is changed to InitializeElfContext() Signed-off-by: Ray Ni Cc: Marvin H=C3=A4user Cc: Guo Dong Cc: Benjamin You --- UefiPayloadPkg/PayloadLoaderPeim/ElfLib.h | 11 +- .../PayloadLoaderPeim/ElfLib/Elf32Lib.c | 38 ++-- .../PayloadLoaderPeim/ElfLib/Elf64Lib.c | 39 ++-- .../PayloadLoaderPeim/ElfLib/ElfLib.c | 210 +++++++++++++----- .../PayloadLoaderPeim/PayloadLoaderPeim.c | 6 +- 5 files changed, 188 insertions(+), 116 deletions(-) diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib.h b/UefiPayloadPkg/Pay= loadLoaderPeim/ElfLib.h index 9cfc2912cf..0ed93140a9 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib.h +++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib.h @@ -17,7 +17,6 @@ #define ELF_PT_LOAD 1=0D =0D typedef struct {=0D - RETURN_STATUS ParseStatus; ///< Return the status after Pars= eElfImage().=0D UINT8 *FileBase; ///< The source location in memor= y.=0D UINTN FileSize; ///< The size including sections = that don't require loading.=0D UINT8 *PreferredImageAddress; ///< The preferred image to be lo= aded. No relocation is needed if loaded to this address.=0D @@ -45,7 +44,10 @@ typedef struct { /**=0D Parse the ELF image info.=0D =0D - @param[in] ImageBase Memory address of an image.=0D + On return, all fields in ElfCt are updated except ImageAddress.=0D +=0D + @param[in] FileBase Memory address of an image.=0D + @param[in] MaxFileSize The maximum file size.=0D @param[out] ElfCt The EFL image context pointer.=0D =0D @retval EFI_INVALID_PARAMETER Input parameters are not valid.=0D @@ -55,8 +57,9 @@ typedef struct { **/=0D EFI_STATUS=0D EFIAPI=0D -ParseElfImage (=0D - IN VOID *ImageBase,=0D +InitializeElfContext (=0D + IN VOID *FileBase,=0D + IN UINTN MaxFileSize,=0D OUT ELF_IMAGE_CONTEXT *ElfCt=0D );=0D =0D diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c b/UefiPaylo= adPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c index 3fa100ce4a..79f4ce623b 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c @@ -115,7 +115,7 @@ ProcessRelocation32 ( UINT32 Type;=0D =0D for ( Index =3D 0=0D - ; RelaEntrySize * Index < RelaSize=0D + ; Index < RelaSize / RelaEntrySize=0D ; Index++, Rela =3D ELF_NEXT_ENTRY (Elf32_Rela, Rela, RelaEntrySize)= =0D ) {=0D //=0D @@ -137,7 +137,6 @@ ProcessRelocation32 ( // Dynamic section doesn't contain entries of this type.=0D //=0D DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type))= ;=0D - ASSERT (FALSE);=0D } else {=0D *Ptr +=3D (UINT32) Delta;=0D }=0D @@ -164,7 +163,6 @@ ProcessRelocation32 ( // Calculation: B + A=0D //=0D if (RelaType =3D=3D SHT_RELA) {=0D - ASSERT (*Ptr =3D=3D 0);=0D *Ptr =3D (UINT32) Delta + Rela->r_addend;=0D } else {=0D //=0D @@ -177,7 +175,6 @@ ProcessRelocation32 ( // non-Dynamic section doesn't contain entries of this type.=0D //=0D DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type))= ;=0D - ASSERT (FALSE);=0D }=0D break;=0D =0D @@ -236,12 +233,12 @@ RelocateElf32Dynamic ( //=0D // It's abnormal a DYN ELF doesn't contain a dynamic section.=0D //=0D - ASSERT (DynShdr !=3D NULL);=0D if (DynShdr =3D=3D NULL) {=0D return EFI_UNSUPPORTED;=0D }=0D - ASSERT (DynShdr->sh_type =3D=3D SHT_DYNAMIC);=0D - ASSERT (DynShdr->sh_entsize >=3D sizeof (*Dyn));=0D + if ((DynShdr->sh_type !=3D SHT_DYNAMIC) || DynShdr->sh_entsize < sizeof = (*Dyn)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D =0D //=0D // 2. Locate the relocation section from the dynamic section.=0D @@ -286,9 +283,6 @@ RelocateElf32Dynamic ( }=0D =0D if (RelaOffset =3D=3D MAX_UINT64) {=0D - ASSERT (RelaCount =3D=3D 0);=0D - ASSERT (RelaEntrySize =3D=3D 0);=0D - ASSERT (RelaSize =3D=3D 0);=0D //=0D // It's fine that a DYN ELF doesn't contain relocation section.=0D //=0D @@ -299,23 +293,22 @@ RelocateElf32Dynamic ( // Verify the existence of the relocation section.=0D //=0D RelShdr =3D GetElf32SectionByRange (ElfCt->FileBase, RelaOffset, RelaSiz= e);=0D - ASSERT (RelShdr !=3D NULL);=0D if (RelShdr =3D=3D NULL) {=0D return EFI_UNSUPPORTED;=0D }=0D - ASSERT (RelShdr->sh_type =3D=3D RelaType);=0D - ASSERT (RelShdr->sh_entsize =3D=3D RelaEntrySize);=0D + if ((RelShdr->sh_type !=3D RelaType) || (RelShdr->sh_entsize !=3D RelaEn= trySize)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D =0D //=0D // 3. Process the relocation section.=0D //=0D - ProcessRelocation32 (=0D - (Elf32_Rela *) (ElfCt->FileBase + RelShdr->sh_offset),=0D - RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,=0D - (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddress,=0D - TRUE=0D - );=0D - return EFI_SUCCESS;=0D + return ProcessRelocation32 (=0D + (Elf32_Rela *) (ElfCt->FileBase + RelShdr->sh_offset),=0D + RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,=0D + (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddr= ess,=0D + TRUE=0D + );=0D }=0D =0D /**=0D @@ -331,7 +324,6 @@ RelocateElf32Sections ( IN ELF_IMAGE_CONTEXT *ElfCt=0D )=0D {=0D - EFI_STATUS Status;=0D Elf32_Ehdr *Ehdr;=0D Elf32_Shdr *RelShdr;=0D Elf32_Shdr *Shdr;=0D @@ -351,9 +343,7 @@ RelocateElf32Sections ( //=0D if (Ehdr->e_type =3D=3D ET_DYN) {=0D DEBUG ((DEBUG_INFO, "DYN ELF: Relocate using dynamic sections...\n"));= =0D - Status =3D RelocateElf32Dynamic (ElfCt);=0D - ASSERT_EFI_ERROR (Status);=0D - return Status;=0D + return RelocateElf32Dynamic (ElfCt);=0D }=0D =0D //=0D diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c b/UefiPaylo= adPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c index e364807007..cfe70639ca 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c @@ -115,7 +115,7 @@ ProcessRelocation64 ( UINT32 Type;=0D =0D for ( Index =3D 0=0D - ; MultU64x64 (RelaEntrySize, Index) < RelaSize=0D + ; Index < DivU64x64Remainder (RelaSize, RelaEntrySize, NULL)=0D ; Index++, Rela =3D ELF_NEXT_ENTRY (Elf64_Rela, Rela, RelaEntrySize)= =0D ) {=0D //=0D @@ -138,7 +138,6 @@ ProcessRelocation64 ( // Dynamic section doesn't contain entries of this type.=0D //=0D DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type))= ;=0D - ASSERT (FALSE);=0D } else {=0D *Ptr +=3D Delta;=0D }=0D @@ -149,7 +148,6 @@ ProcessRelocation64 ( // Dynamic section doesn't contain entries of this type.=0D //=0D DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type));= =0D - ASSERT (FALSE);=0D break;=0D =0D case R_X86_64_RELATIVE:=0D @@ -173,7 +171,6 @@ ProcessRelocation64 ( // Calculation: B + A=0D //=0D if (RelaType =3D=3D SHT_RELA) {=0D - ASSERT (*Ptr =3D=3D 0);=0D *Ptr =3D Delta + Rela->r_addend;=0D } else {=0D //=0D @@ -186,7 +183,6 @@ ProcessRelocation64 ( // non-Dynamic section doesn't contain entries of this type.=0D //=0D DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type))= ;=0D - ASSERT (FALSE);=0D }=0D break;=0D =0D @@ -245,12 +241,12 @@ RelocateElf64Dynamic ( //=0D // It's abnormal a DYN ELF doesn't contain a dynamic section.=0D //=0D - ASSERT (DynShdr !=3D NULL);=0D if (DynShdr =3D=3D NULL) {=0D return EFI_UNSUPPORTED;=0D }=0D - ASSERT (DynShdr->sh_type =3D=3D SHT_DYNAMIC);=0D - ASSERT (DynShdr->sh_entsize >=3D sizeof (*Dyn));=0D + if ((DynShdr->sh_type !=3D SHT_DYNAMIC) || DynShdr->sh_entsize < sizeof = (*Dyn)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D =0D //=0D // 2. Locate the relocation section from the dynamic section.=0D @@ -295,9 +291,6 @@ RelocateElf64Dynamic ( }=0D =0D if (RelaOffset =3D=3D MAX_UINT64) {=0D - ASSERT (RelaCount =3D=3D 0);=0D - ASSERT (RelaEntrySize =3D=3D 0);=0D - ASSERT (RelaSize =3D=3D 0);=0D //=0D // It's fine that a DYN ELF doesn't contain relocation section.=0D //=0D @@ -308,23 +301,22 @@ RelocateElf64Dynamic ( // Verify the existence of the relocation section.=0D //=0D RelShdr =3D GetElf64SectionByRange (ElfCt->FileBase, RelaOffset, RelaSiz= e);=0D - ASSERT (RelShdr !=3D NULL);=0D if (RelShdr =3D=3D NULL) {=0D return EFI_UNSUPPORTED;=0D }=0D - ASSERT (RelShdr->sh_type =3D=3D RelaType);=0D - ASSERT (RelShdr->sh_entsize =3D=3D RelaEntrySize);=0D + if ((RelShdr->sh_type !=3D RelaType) || (RelShdr->sh_entsize !=3D RelaEn= trySize)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D =0D //=0D // 3. Process the relocation section.=0D //=0D - ProcessRelocation64 (=0D - (Elf64_Rela *) (ElfCt->FileBase + RelShdr->sh_offset),=0D - RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,=0D - (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddress,=0D - TRUE=0D - );=0D - return EFI_SUCCESS;=0D + return ProcessRelocation64 (=0D + (Elf64_Rela *) (ElfCt->FileBase + RelShdr->sh_offset),=0D + RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,=0D + (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddr= ess,=0D + TRUE=0D + );=0D }=0D =0D /**=0D @@ -340,7 +332,6 @@ RelocateElf64Sections ( IN ELF_IMAGE_CONTEXT *ElfCt=0D )=0D {=0D - EFI_STATUS Status;=0D Elf64_Ehdr *Ehdr;=0D Elf64_Shdr *RelShdr;=0D Elf64_Shdr *Shdr;=0D @@ -360,9 +351,7 @@ RelocateElf64Sections ( //=0D if (Ehdr->e_type =3D=3D ET_DYN) {=0D DEBUG ((DEBUG_INFO, "DYN ELF: Relocate using dynamic sections...\n"));= =0D - Status =3D RelocateElf64Dynamic (ElfCt);=0D - ASSERT_EFI_ERROR (Status);=0D - return Status;=0D + return RelocateElf64Dynamic (ElfCt);=0D }=0D =0D //=0D diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfLib.c b/UefiPayload= Pkg/PayloadLoaderPeim/ElfLib/ElfLib.c index 531b3486d2..70de81c3ac 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfLib.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfLib.c @@ -11,22 +11,32 @@ /**=0D Check if the ELF image is valid.=0D =0D - @param[in] ImageBase Memory address of an image.=0D + @param[in] FileBase Memory address of an image.=0D + @param[in] MaxFileSize The maximum file size.=0D =0D @retval TRUE if valid.=0D =0D **/=0D BOOLEAN=0D IsElfFormat (=0D - IN CONST UINT8 *ImageBase=0D + IN CONST UINT8 *FileBase,=0D + IN UINTN MaxFileSize=0D )=0D {=0D Elf32_Ehdr *Elf32Hdr;=0D Elf64_Ehdr *Elf64Hdr;=0D =0D - ASSERT (ImageBase !=3D NULL);=0D + ASSERT (FileBase !=3D NULL);=0D =0D - Elf32Hdr =3D (Elf32_Ehdr *)ImageBase;=0D + Elf32Hdr =3D (Elf32_Ehdr *)FileBase;=0D + Elf64Hdr =3D (Elf64_Ehdr *)FileBase;=0D +=0D + //=0D + // Make sure MaxFileSize covers e_ident[].=0D + //=0D + if (MaxFileSize < sizeof (Elf32Hdr->e_ident)) {=0D + return FALSE;=0D + }=0D =0D //=0D // Start with correct signature "\7fELF"=0D @@ -50,15 +60,13 @@ IsElfFormat ( // Check 32/64-bit architecture=0D //=0D if (Elf32Hdr->e_ident[EI_CLASS] =3D=3D ELFCLASS64) {=0D - Elf64Hdr =3D (Elf64_Ehdr *)Elf32Hdr;=0D - Elf32Hdr =3D NULL;=0D - } else if (Elf32Hdr->e_ident[EI_CLASS] =3D=3D ELFCLASS32) {=0D - Elf64Hdr =3D NULL;=0D - } else {=0D - return FALSE;=0D - }=0D + //=0D + // Before accessing fields in Elf64_Ehdr, make sure the MaxFileSize co= vers the entire header.=0D + //=0D + if (MaxFileSize < sizeof (Elf64_Ehdr)) {=0D + return FALSE;=0D + }=0D =0D - if (Elf64Hdr !=3D NULL) {=0D //=0D // Support intel architecture only for now=0D //=0D @@ -79,7 +87,7 @@ IsElfFormat ( if (Elf64Hdr->e_version !=3D EV_CURRENT) {=0D return FALSE;=0D }=0D - } else {=0D + } else if (Elf32Hdr->e_ident[EI_CLASS] =3D=3D ELFCLASS32) {=0D //=0D // Support intel architecture only for now=0D //=0D @@ -100,7 +108,10 @@ IsElfFormat ( if (Elf32Hdr->e_version !=3D EV_CURRENT) {=0D return FALSE;=0D }=0D + } else {=0D + return FALSE;=0D }=0D +=0D return TRUE;=0D }=0D =0D @@ -108,6 +119,7 @@ IsElfFormat ( Calculate a ELF file size.=0D =0D @param[in] ElfCt ELF image context pointer.=0D + @param[in] MaxFileSize The maximum file size.=0D @param[out] FileSize Return the file size.=0D =0D @retval EFI_INVALID_PARAMETER ElfCt or SecPos is NULL.=0D @@ -117,12 +129,12 @@ IsElfFormat ( EFI_STATUS=0D CalculateElfFileSize (=0D IN ELF_IMAGE_CONTEXT *ElfCt,=0D + IN UINTN MaxFileSize,=0D OUT UINTN *FileSize=0D )=0D {=0D EFI_STATUS Status;=0D - UINTN FileSize1;=0D - UINTN FileSize2;=0D + UINT32 Index;=0D Elf32_Ehdr *Elf32Hdr;=0D Elf64_Ehdr *Elf64Hdr;=0D UINTN Offset;=0D @@ -132,24 +144,34 @@ CalculateElfFileSize ( return EFI_INVALID_PARAMETER;=0D }=0D =0D - // Use last section as end of file=0D - Status =3D GetElfSectionPos (ElfCt, ElfCt->ShNum - 1, &Offset, &Size);=0D - if (EFI_ERROR(Status)) {=0D - return EFI_UNSUPPORTED;=0D - }=0D - FileSize1 =3D Offset + Size;=0D -=0D - // Use end of section header as end of file=0D - FileSize2 =3D 0;=0D + //=0D + // Optional section headers might exist in the end of file.=0D + //=0D + *FileSize =3D 0;=0D if (ElfCt->EiClass =3D=3D ELFCLASS32) {=0D Elf32Hdr =3D (Elf32_Ehdr *)ElfCt->FileBase;=0D - FileSize2 =3D Elf32Hdr->e_shoff + Elf32Hdr->e_shentsize * Elf32Hdr->e_= shnum;=0D + *FileSize =3D Elf32Hdr->e_shoff + Elf32Hdr->e_shentsize * Elf32Hdr->e_= shnum;=0D } else if (ElfCt->EiClass =3D=3D ELFCLASS64) {=0D Elf64Hdr =3D (Elf64_Ehdr *)ElfCt->FileBase;=0D - FileSize2 =3D (UINTN)(Elf64Hdr->e_shoff + Elf64Hdr->e_shentsize * Elf6= 4Hdr->e_shnum);=0D + *FileSize =3D (UINTN)(Elf64Hdr->e_shoff + Elf64Hdr->e_shentsize * Elf6= 4Hdr->e_shnum);=0D }=0D =0D - *FileSize =3D MAX(FileSize1, FileSize2);=0D + //=0D + // Get the end of section body.=0D + //=0D + for (Index =3D 0; Index < ElfCt->ShNum; Index++) {=0D + Status =3D GetElfSectionPos (ElfCt, Index, &Offset, &Size);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + if ((Offset >=3D MaxFileSize) || (Size > MaxFileSize - Offset)) {=0D + //=0D + // Section body is outside of file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D + *FileSize =3D MAX (*FileSize, Offset + Size);=0D + }=0D =0D return EFI_SUCCESS;=0D }=0D @@ -213,7 +235,8 @@ GetElfSegmentInfo ( =0D On return, all fields in ElfCt are updated except ImageAddress.=0D =0D - @param[in] ImageBase Memory address of an image.=0D + @param[in] FileBase Memory address of an image.=0D + @param[in] MaxFileSize The maximum file size.=0D @param[out] ElfCt The EFL image context pointer.=0D =0D @retval EFI_INVALID_PARAMETER Input parameters are not valid.=0D @@ -223,8 +246,9 @@ GetElfSegmentInfo ( **/=0D EFI_STATUS=0D EFIAPI=0D -ParseElfImage (=0D - IN VOID *ImageBase,=0D +InitializeElfContext (=0D + IN VOID *FileBase,=0D + IN UINTN MaxFileSize,=0D OUT ELF_IMAGE_CONTEXT *ElfCt=0D )=0D {=0D @@ -238,30 +262,58 @@ ParseElfImage ( UINTN End;=0D UINTN Base;=0D =0D - if (ElfCt =3D=3D NULL) {=0D - return EFI_INVALID_PARAMETER;=0D - }=0D + ASSERT (ElfCt !=3D NULL);=0D +=0D ZeroMem (ElfCt, sizeof(ELF_IMAGE_CONTEXT));=0D =0D - if (ImageBase =3D=3D NULL) {=0D - return (ElfCt->ParseStatus =3D EFI_INVALID_PARAMETER);=0D + if (FileBase =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D }=0D =0D - ElfCt->FileBase =3D (UINT8 *)ImageBase;=0D - if (!IsElfFormat (ElfCt->FileBase)) {=0D - return (ElfCt->ParseStatus =3D EFI_UNSUPPORTED);=0D + ElfCt->FileBase =3D (UINT8 *)FileBase;=0D + if (!IsElfFormat (ElfCt->FileBase, MaxFileSize)) {=0D + return EFI_UNSUPPORTED;=0D }=0D =0D Elf32Hdr =3D (Elf32_Ehdr *)ElfCt->FileBase;=0D ElfCt->EiClass =3D Elf32Hdr->e_ident[EI_CLASS];=0D if (ElfCt->EiClass =3D=3D ELFCLASS32) {=0D if ((Elf32Hdr->e_type !=3D ET_EXEC) && (Elf32Hdr->e_type !=3D ET_DYN))= {=0D - return (ElfCt->ParseStatus =3D EFI_UNSUPPORTED);=0D + return EFI_UNSUPPORTED;=0D }=0D - Elf32Shdr =3D (Elf32_Shdr *)GetElf32SectionByIndex (ElfCt->FileBase, E= lf32Hdr->e_shstrndx);=0D +=0D + if ((Elf32Hdr->e_phoff >=3D MaxFileSize) || ((UINT32) (Elf32Hdr->e_phe= ntsize * Elf32Hdr->e_phnum) > MaxFileSize - Elf32Hdr->e_phoff)) {=0D + //=0D + // Program headers are outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if ((Elf32Hdr->e_shoff >=3D MaxFileSize) || ((UINT32) (Elf32Hdr->e_she= ntsize * Elf32Hdr->e_shnum) > MaxFileSize - Elf32Hdr->e_shoff)) {=0D + //=0D + // Section headers are outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (Elf32Hdr->e_entry >=3D MaxFileSize) {=0D + //=0D + // Entrypoint is outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + Elf32Shdr =3D GetElf32SectionByIndex (ElfCt->FileBase, Elf32Hdr->e_shs= trndx);=0D if (Elf32Shdr =3D=3D NULL) {=0D - return (ElfCt->ParseStatus =3D EFI_UNSUPPORTED);=0D + return EFI_UNSUPPORTED;=0D }=0D + if ((Elf32Shdr->sh_offset >=3D MaxFileSize) || (Elf32Shdr->sh_size > M= axFileSize - Elf32Shdr->sh_offset)) {=0D + //=0D + // String section is outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D ElfCt->EntryPoint =3D (UINTN)Elf32Hdr->e_entry;=0D ElfCt->ShNum =3D Elf32Hdr->e_shnum;=0D ElfCt->PhNum =3D Elf32Hdr->e_phnum;=0D @@ -270,12 +322,41 @@ ParseElfImage ( } else {=0D Elf64Hdr =3D (Elf64_Ehdr *)Elf32Hdr;=0D if ((Elf64Hdr->e_type !=3D ET_EXEC) && (Elf64Hdr->e_type !=3D ET_DYN))= {=0D - return (ElfCt->ParseStatus =3D EFI_UNSUPPORTED);=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if ((Elf64Hdr->e_phoff >=3D MaxFileSize) || ((UINT32) Elf64Hdr->e_phen= tsize * Elf64Hdr->e_phnum > MaxFileSize - (UINTN) Elf64Hdr->e_phoff)) {=0D + //=0D + // Program headers are outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if ((Elf64Hdr->e_shoff >=3D MaxFileSize) || ((UINT32) Elf64Hdr->e_shen= tsize * Elf64Hdr->e_shnum > MaxFileSize - (UINTN) Elf64Hdr->e_shoff)) {=0D + //=0D + // Section headers are outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (Elf64Hdr->e_entry >=3D MaxFileSize) {=0D + //=0D + // Entrypoint is outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D }=0D - Elf64Shdr =3D (Elf64_Shdr *)GetElf64SectionByIndex (ElfCt->FileBase, E= lf64Hdr->e_shstrndx);=0D +=0D + Elf64Shdr =3D GetElf64SectionByIndex (ElfCt->FileBase, Elf64Hdr->e_shs= trndx);=0D if (Elf64Shdr =3D=3D NULL) {=0D - return (ElfCt->ParseStatus =3D EFI_UNSUPPORTED);=0D + return EFI_UNSUPPORTED;=0D + }=0D + if ((Elf64Shdr->sh_offset >=3D MaxFileSize) || (Elf64Shdr->sh_size > M= axFileSize - Elf64Shdr->sh_offset)) {=0D + //=0D + // String section is outside of the file range.=0D + //=0D + return EFI_UNSUPPORTED;=0D }=0D +=0D ElfCt->EntryPoint =3D (UINTN)Elf64Hdr->e_entry;=0D ElfCt->ShNum =3D Elf64Hdr->e_shnum;=0D ElfCt->PhNum =3D Elf64Hdr->e_phnum;=0D @@ -297,6 +378,13 @@ ParseElfImage ( continue;=0D }=0D =0D + //=0D + // Loadable process segments must have congruent values for p_vaddr an= d p_offset, modulo the page size.=0D + //=0D + if ((SegInfo.MemAddr % EFI_PAGE_SIZE) !=3D (SegInfo.Offset % EFI_PAGE_= SIZE)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D if (SegInfo.MemLen !=3D SegInfo.Length) {=0D //=0D // Not enough space to execute at current location.=0D @@ -317,8 +405,7 @@ ParseElfImage ( ElfCt->ImageSize =3D End - Base + 1;=0D ElfCt->PreferredImageAddress =3D (VOID *) Base;=0D =0D - CalculateElfFileSize (ElfCt, &ElfCt->FileSize);=0D - return (ElfCt->ParseStatus =3D EFI_SUCCESS);;=0D + return CalculateElfFileSize (ElfCt, MaxFileSize, &ElfCt->FileSize);=0D }=0D =0D /**=0D @@ -348,10 +435,6 @@ LoadElfImage ( return EFI_INVALID_PARAMETER;=0D }=0D =0D - if (EFI_ERROR (ElfCt->ParseStatus)) {=0D - return ElfCt->ParseStatus;=0D - }=0D -=0D if (ElfCt->ImageAddress =3D=3D NULL) {=0D return EFI_INVALID_PARAMETER;=0D }=0D @@ -370,6 +453,8 @@ LoadElfImage ( /**=0D Get a ELF section name from its index.=0D =0D + ElfCt is returned from InitializeElfContext().=0D +=0D @param[in] ElfCt ELF image context pointer.=0D @param[in] SectionIndex ELF section index.=0D @param[out] SectionName The pointer to the section name.=0D @@ -389,25 +474,25 @@ GetElfSectionName ( Elf32_Shdr *Elf32Shdr;=0D Elf64_Shdr *Elf64Shdr;=0D CHAR8 *Name;=0D + UINTN MaxSize;=0D =0D if ((ElfCt =3D=3D NULL) || (SectionName =3D=3D NULL)) {=0D return EFI_INVALID_PARAMETER;=0D }=0D =0D - if (EFI_ERROR (ElfCt->ParseStatus)) {=0D - return ElfCt->ParseStatus;=0D - }=0D -=0D - Name =3D NULL;=0D + Name =3D NULL;=0D + MaxSize =3D 0;=0D if (ElfCt->EiClass =3D=3D ELFCLASS32) {=0D Elf32Shdr =3D GetElf32SectionByIndex (ElfCt->FileBase, SectionIndex);= =0D if ((Elf32Shdr !=3D NULL) && (Elf32Shdr->sh_name < ElfCt->ShStrLen)) {= =0D - Name =3D (CHAR8 *)(ElfCt->FileBase + ElfCt->ShStrOff + Elf32Shdr->sh= _name);=0D + Name =3D (CHAR8 *)(ElfCt->FileBase + ElfCt->ShStrOff + Elf32Shdr-= >sh_name);=0D + MaxSize =3D ElfCt->ShStrLen - Elf32Shdr->sh_name;=0D }=0D } else if (ElfCt->EiClass =3D=3D ELFCLASS64) {=0D Elf64Shdr =3D GetElf64SectionByIndex (ElfCt->FileBase, SectionIndex);= =0D if ((Elf64Shdr !=3D NULL) && (Elf64Shdr->sh_name < ElfCt->ShStrLen)) {= =0D - Name =3D (CHAR8 *)(ElfCt->FileBase + ElfCt->ShStrOff + Elf64Shdr->sh= _name);=0D + Name =3D (CHAR8 *)(ElfCt->FileBase + ElfCt->ShStrOff + Elf64Shdr-= >sh_name);=0D + MaxSize =3D ElfCt->ShStrLen - Elf64Shdr->sh_name;=0D }=0D }=0D =0D @@ -415,6 +500,13 @@ GetElfSectionName ( return EFI_NOT_FOUND;=0D }=0D =0D + if (AsciiStrnLenS (Name, MaxSize) =3D=3D MaxSize) {=0D + //=0D + // No null terminator is found for the section name.=0D + //=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D *SectionName =3D Name;=0D return EFI_SUCCESS;=0D }=0D @@ -449,10 +541,6 @@ GetElfSectionPos ( return EFI_INVALID_PARAMETER;=0D }=0D =0D - if (EFI_ERROR (ElfCt->ParseStatus)) {=0D - return ElfCt->ParseStatus;=0D - }=0D -=0D if (ElfCt->EiClass =3D=3D ELFCLASS32) {=0D Elf32Shdr =3D GetElf32SectionByIndex (ElfCt->FileBase, Index);=0D if (Elf32Shdr !=3D NULL) {=0D diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c b/UefiPay= loadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c index 44639f9fd2..efedaef1b3 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c @@ -69,8 +69,10 @@ PeiLoadFileLoadPayload ( return Status;=0D }=0D =0D - ZeroMem (&Context, sizeof (Context));=0D - Status =3D ParseElfImage (Elf, &Context);=0D + //=0D + // Trust the ELF image loaded from FV.=0D + //=0D + Status =3D InitializeElfContext (Elf, MAX_UINTN - (UINTN) Elf, &Contex= t);=0D } while (EFI_ERROR (Status));=0D =0D DEBUG ((=0D --=20 2.31.1.windows.1