From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web09.8461.1639032700548149997 for ; Wed, 08 Dec 2021 22:51:40 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.com header.s=intel header.b=S9uuiPbV; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: wei6.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639032700; x=1670568700; h=from:to:cc:subject:date:message-id; bh=9R7Kd0GcMnptyhhTQTqu0/v2rpW0Oqym+RBs/prYf1Q=; b=S9uuiPbVhJANRmW7FVJaf6w9WrboSLcsfAyH9dOppqsUGO+xvkkNw6zp e8Z3n4UL7y2mmEunfXcanUucLQ2KPOnLfpNwtGR9/M4SRNQ3to+pWvsK/ 2My8Y010kOvwByRzAKsFBPeN1jTFoQy3YtSBT8175+jM5juD8m1+4Hrws qOkSMF8nXCz4Q/75tf8VIASAOv9UOGsc1ebSLXYDzWzpLHtd16VuHCpVJ kWkeTcgPz0E5GTdeIzf1P0kAZxuGFtsdJ2gC/wjpFKEOxrhysnZ4qxz2L YdA9ncoiQoBSKA73tci2pNemg79oxTdpSYrxGPId3yGiBEvLDfYjZkaQs Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10192"; a="235544317" X-IronPort-AV: E=Sophos;i="5.88,191,1635231600"; d="scan'208";a="235544317" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Dec 2021 22:51:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,191,1635231600"; d="scan'208";a="516165840" Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.25]) by orsmga008.jf.intel.com with ESMTP; 08 Dec 2021 22:51:37 -0800 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Sami Mujawar , Jiewen Yao , Supreeth Venkatesh , Liming Gao Subject: [edk2-devel][Patch] StandaloneMmPkg/FvLib: Support large file with EFI_FFS_FILE_HEADER2. Date: Thu, 9 Dec 2021 14:51:33 +0800 Message-Id: <20211209065133.7748-1-wei6.xu@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3769 Current FvLib will hit parse issue when encountering LARGE file, then ignore latter ffs/section, thus causing required drivers not being dispatched. Therefore, need to add support for EFI_FFS_FILE_HEADER2 and EFI_COMMON_SECTION_HEADER2 in FvLib to fix this issue. Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Jiewen Yao Cc: Supreeth Venkatesh Cc: Liming Gao Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Library/FvLib/FvLib.c | 65 ++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Library/FvLib/FvLib.c index aa36a35eff..89504b9ee9 100644 --- a/StandaloneMmPkg/Library/FvLib/FvLib.c +++ b/StandaloneMmPkg/Library/FvLib/FvLib.c @@ -1,8 +1,8 @@ /** @file -Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -61,22 +61,24 @@ CalculateHeaderChecksum ( ) { UINT8 *ptr; UINTN Index; UINT8 Sum; + UINTN Size; - Sum = 0; - ptr = (UINT8 *)FileHeader; + Sum = 0; + ptr = (UINT8 *)FileHeader; + Size = IS_FFS_FILE2 (FileHeader) ? sizeof (EFI_FFS_FILE_HEADER2) : sizeof (EFI_FFS_FILE_HEADER); - for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) { + for (Index = 0; Index < Size - 3; Index += 4) { Sum = (UINT8)(Sum + ptr[Index]); Sum = (UINT8)(Sum + ptr[Index + 1]); Sum = (UINT8)(Sum + ptr[Index + 2]); Sum = (UINT8)(Sum + ptr[Index + 3]); } - for ( ; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) { + for ( ; Index < Size; Index++) { Sum = (UINT8)(Sum + ptr[Index]); } // // State field (since this indicates the different state of file). @@ -155,11 +157,12 @@ FfsFindNextFile ( } else { // // Length is 24 bits wide so mask upper 8 bits // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. // - FileLength = FFS_FILE_SIZE (*FileHeader); + FileLength = IS_FFS_FILE2 (*FileHeader) ? + FFS_FILE2_SIZE (*FileHeader) : FFS_FILE_SIZE (*FileHeader); FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize); } FileOffset = (UINT32)((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader); @@ -170,18 +173,25 @@ FfsFindNextFile ( // FileState = GetFileState (ErasePolarity, FfsFileHeader); switch (FileState) { case EFI_FILE_HEADER_INVALID: - FileOffset += sizeof (EFI_FFS_FILE_HEADER); - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + if (IS_FFS_FILE2 (FfsFileHeader)) { + FileOffset += sizeof (EFI_FFS_FILE_HEADER2); + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + FileOffset += sizeof (EFI_FFS_FILE_HEADER); + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + } + break; case EFI_FILE_DATA_VALID: case EFI_FILE_MARKED_FOR_UPDATE: if (CalculateHeaderChecksum (FfsFileHeader) == 0) { - FileLength = FFS_FILE_SIZE (FfsFileHeader); + FileLength = IS_FFS_FILE2 (FfsFileHeader) ? + FFS_FILE2_SIZE (FfsFileHeader) : FFS_FILE_SIZE (FfsFileHeader); FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) { *FileHeader = FfsFileHeader; @@ -195,11 +205,12 @@ FfsFindNextFile ( } break; case EFI_FILE_DELETED: - FileLength = FFS_FILE_SIZE (FfsFileHeader); + FileLength = IS_FFS_FILE2 (FfsFileHeader) ? + FFS_FILE2_SIZE (FfsFileHeader) : FFS_FILE_SIZE (FfsFileHeader); FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); FileOffset += FileOccupiedSize; FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); break; @@ -251,11 +262,11 @@ FindFfsSectionInSections ( CurrentAddress = EndOfSection; Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress; - Size = SECTION_SIZE (Section); + Size = IS_SECTION2 (Section) ? SECTION2_SIZE (Section) : SECTION_SIZE (Section); if (Size < sizeof (*Section)) { return EFI_VOLUME_CORRUPTED; } EndOfSection = CurrentAddress + Size; @@ -304,13 +315,17 @@ FfsFindSection ( // // Size is 24 bits wide so mask upper 8 bits. // Does not include FfsFileHeader header size // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. // - Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); - FileSize = FFS_FILE_SIZE (FfsFileHeader); - FileSize -= sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsFileHeader)) { + Section = (EFI_COMMON_SECTION_HEADER *)((EFI_FFS_FILE_HEADER2 *)FfsFileHeader + 1); + FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); + FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + } Status = FindFfsSectionInSections ( Section, FileSize, SectionType, @@ -349,29 +364,39 @@ FfsFindSectionData ( // // Size is 24 bits wide so mask upper 8 bits. // Does not include FfsFileHeader header size // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. // - Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); - FileSize = FFS_FILE_SIZE (FfsFileHeader); - FileSize -= sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsFileHeader)) { + Section = (EFI_COMMON_SECTION_HEADER *)((EFI_FFS_FILE_HEADER2 *)FfsFileHeader + 1); + FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); + FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + } *SectionData = NULL; ParsedLength = 0; while (ParsedLength < FileSize) { if (Section->Type == SectionType) { - *SectionData = (VOID *)(Section + 1); - *SectionDataSize = SECTION_SIZE (Section); + if (IS_SECTION2 (Section)) { + *SectionData = (VOID *)((EFI_COMMON_SECTION_HEADER2 *)Section + 1); + *SectionDataSize = SECTION2_SIZE (Section); + } else { + *SectionData = (VOID *)(Section + 1); + *SectionDataSize = SECTION_SIZE (Section); + } + return EFI_SUCCESS; } // // Size is 24 bits wide so mask upper 8 bits. // SectionLength is adjusted it is 4 byte aligned. // Go to the next section // - SectionLength = SECTION_SIZE (Section); + SectionLength = IS_SECTION2 (Section) ? SECTION2_SIZE (Section) : SECTION_SIZE (Section); SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); ParsedLength += SectionLength; Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength); } -- 2.16.2.windows.1