From 9004c393520fb3d9ca60282acdf47df11731409a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 6 Oct 2023 12:56:36 +0300 Subject: [PATCH] GenFv: Fixed corruption of FFS file after rebasing. --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 41 +++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 587290b049..f815ad0e1a 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3625,6 +3625,8 @@ Routine Description: UINT32 FfsFileLength; UINTN FileOffset; EFI_FFS_INTEGRITY_CHECK *IntegrityCheck; + UINT8 *AfterPePart; + UINT32 AfterPeSize; Index = 0; Cptr = NULL; @@ -3876,6 +3878,24 @@ Routine Description: } if (ImageFormat == UefiImageFormatUe) { + if ((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) >= 0x00FFFFFFU) { + Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); + return EFI_UNSUPPORTED; + } + + AfterPeSize = GetFfsFileLength (*FfsFile) - (FileOffset + SectPeSize); + AfterPePart = calloc (1, AfterPeSize); + if (AfterPePart == NULL) { + fprintf (stderr, "GenFv: Could not allocate memory for AfterPePart\n"); + return EFI_OUT_OF_RESOURCES; + } + + memmove ( + AfterPePart, + (UINT8 *)((UINTN)(*FfsFile) + FileOffset + SectPeSize), + AfterPeSize + ); + FfsFileLength = GetFfsFileLength (*FfsFile) - SectPeSize + RebasedImageSize; *FfsFile = realloc (*FfsFile, FfsFileLength); if (*FfsFile == NULL) { @@ -3884,12 +3904,23 @@ Routine Description: } *FileSize = FfsFileLength; + CurrentPe32Section.CommonHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)(*FfsFile) + FileOffset - CurSecHdrSize); + CurrentPe32Section.CommonHeader->Size[0] = (UINT8)((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x000000FF); + CurrentPe32Section.CommonHeader->Size[1] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x0000FF00) >> 8); + CurrentPe32Section.CommonHeader->Size[2] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x00FF0000) >> 16); + memmove ( (UINT8 *)((UINTN)(*FfsFile) + FileOffset), RebasedImage, RebasedImageSize ); + memmove ( + (UINT8 *)((UINTN)(*FfsFile) + FileOffset + RebasedImageSize), + AfterPePart, + AfterPeSize + ); + if (FfsHeaderSize > sizeof(EFI_FFS_FILE_HEADER)) { ((EFI_FFS_FILE_HEADER2 *)(*FfsFile))->ExtendedSize = FfsFileLength; } else { @@ -3908,7 +3939,8 @@ Routine Description: IntegrityCheck->Checksum.File = 0; IntegrityCheck->Checksum.Header = CalculateChecksum8 ( - (UINT8 *)(*FfsFile), FfsHeaderSize); + (UINT8 *)(*FfsFile), FfsHeaderSize + ); if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { // @@ -3916,7 +3948,8 @@ Routine Description: // IntegrityCheck->Checksum.File = CalculateChecksum8 ( (UINT8 *)(*FfsFile) + FfsHeaderSize, - FfsFileLength - FfsHeaderSize); + FfsFileLength - FfsHeaderSize + ); } else { IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM; } @@ -3978,7 +4011,9 @@ Routine Description: UefiImageFileBuffer = NULL; UefiImageFileSize = 0; - free (SymbolsPathCpy); + if (SymbolsPathCpy != NULL) { + free (SymbolsPathCpy); + } } return EFI_SUCCESS;