@@ -1432,8 +1432,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
14321432 // Check for AppleCRC32 and UsedSpace in ZeroVector
14331433 bool hasAppleCrc32 = false ;
14341434 UINT32 volumeSize = (UINT32 )volume.size ();
1435- UINT32 appleCrc32 = *( UINT32 *)(volume.constData () + 8 );
1436- UINT32 usedSpace = *( UINT32 *)(volume.constData () + 12 );
1435+ UINT32 appleCrc32 = readUnaligned (( UINT32 *)(volume.constData () + 8 ) );
1436+ UINT32 usedSpace = readUnaligned (( UINT32 *)(volume.constData () + 12 ) );
14371437 if (appleCrc32 != 0 ) {
14381438 // Calculate CRC32 of the volume body
14391439 UINT32 crc = (UINT32 )crc32 (0 , (const UINT8 *)(volume.constData () + volumeHeader->HeaderLength ), volumeSize - volumeHeader->HeaderLength );
@@ -2031,7 +2031,37 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index, const bool probe)
20312031
20322032 // Move to next file
20332033 fileOffset += fileSize;
2034- // TODO: check that alignment bytes are all of erase polarity bit, warn if not so
2034+
2035+ // Check for alignment bytes after the current file
2036+ // Files must be aligned to 8 bytes boundary inside the FFS volume
2037+ // The alignment byte should be equal to 0xFF (erasePolarity = 1) or 0x00 (erasePolarity = 0)
2038+ UINT32 numAlignmentBytes = ALIGN8 (fileOffset) - fileOffset;
2039+
2040+ // We might be at the very end of the volume, need a check for it
2041+ if (volumeBodySize < fileOffset + fileSize + numAlignmentBytes) {
2042+ numAlignmentBytes = volumeBodySize - fileOffset - fileSize;
2043+ }
2044+
2045+ if (numAlignmentBytes > 0 ) {
2046+ UByteArray alignmentBytes = volumeBody.mid (fileOffset + fileSize, numAlignmentBytes);
2047+ // Check alignment bytes to be sane
2048+ if (!isUniformByte (alignmentBytes, emptyByte)) {
2049+ msg (usprintf (" %s: unexpected bytes found in alignment area, should all be %s" , __FUNCTION__, emptyByte ? " 0xFF" : " 0x00" ), fileIndex);
2050+
2051+ // Add unexpected alignment bytes to tree item info
2052+ UString info;
2053+ for (UINT8 i = 0 ; i < numAlignmentBytes; i++) {
2054+ info += usprintf (" %02X " , alignmentBytes[i]);
2055+ }
2056+ info = UString (" Alignment bytes: " ) + info + " \n " ;
2057+ model->addInfo (fileIndex, info);
2058+ }
2059+
2060+ // Store alignment bytes for upholding parsing pre/post-conditions (aka "every byte is accounted for")
2061+ model->setAlignmentBytes (fileIndex, alignmentBytes);
2062+ }
2063+
2064+ // Adjust fileOffset
20352065 fileOffset = ALIGN8 (fileOffset);
20362066 }
20372067
@@ -2505,8 +2535,8 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
25052535 return U_INVALID_PARAMETER ;
25062536
25072537 // Search for and parse all sections
2508- UINT32 bodySize = (UINT32 )sections.size ();
2509- UINT32 headerSize = model->headerSize (index);
2538+ UINT32 fileBodySize = (UINT32 )sections.size ();
2539+ UINT32 fileHeaderSize = model->headerSize (index);
25102540 UINT32 sectionOffset = 0 ;
25112541 USTATUS result = U_SUCCESS ;
25122542
@@ -2521,20 +2551,20 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
25212551
25222552 // Iterate over sections
25232553 UINT32 sectionSize = 0 ;
2524- while (sectionOffset < bodySize ) {
2554+ while (sectionOffset < fileBodySize ) {
25252555 // Get section size
25262556 sectionSize = getSectionSize (sections, sectionOffset, ffsVersion);
25272557
25282558 // Check section size to be sane
25292559 if (sectionSize < sizeof (EFI_COMMON_SECTION_HEADER )
2530- || sectionSize > (bodySize - sectionOffset)) {
2560+ || sectionSize > (fileBodySize - sectionOffset)) {
25312561 // Final parsing
25322562 if (!probe) {
25332563 // Add padding to fill the rest of sections
25342564 UByteArray padding = sections.mid (sectionOffset);
25352565
25362566 // Add tree item
2537- UModelIndex dataIndex = model->addItem (headerSize + sectionOffset, Types::Padding, Subtypes::DataPadding, UString (" Non-UEFI data" ), UString (), UString (), UByteArray (), padding, UByteArray (), Fixed, index);
2567+ UModelIndex dataIndex = model->addItem (fileHeaderSize + sectionOffset, Types::Padding, Subtypes::DataPadding, UString (" Non-UEFI data" ), UString (), UString (), UByteArray (), padding, UByteArray (), Fixed, index);
25382568
25392569 // Show message
25402570 msg (usprintf (" %s: non-UEFI data found in sections area" , __FUNCTION__), dataIndex);
@@ -2550,7 +2580,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
25502580
25512581 // Parse section header
25522582 UModelIndex sectionIndex;
2553- result = parseSectionHeader (sections.mid (sectionOffset, sectionSize), headerSize + sectionOffset, index, sectionIndex, probe);
2583+ result = parseSectionHeader (sections.mid (sectionOffset, sectionSize), fileHeaderSize + sectionOffset, index, sectionIndex, probe);
25542584 if (result) {
25552585 if (!probe)
25562586 msg (usprintf (" %s: section header parsing failed with error " , __FUNCTION__) + errorCodeToUString (result), index);
@@ -2560,7 +2590,37 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
25602590
25612591 // Move to next section
25622592 sectionOffset += sectionSize;
2563- // TODO: verify that alignment bytes are actually zero as per PI spec
2593+
2594+ // Check for alignment bytes after the current section
2595+ // Sections must be aligned to 4 bytes boundary inside the FFS file
2596+ // The alignment byte should be equal to 0x00 regardless of erasePolarity
2597+ UINT32 numAlignmentBytes = ALIGN4 (sectionOffset) - sectionOffset;
2598+
2599+ // We might be at the very end of the file, need a check for it
2600+ if (fileBodySize < sectionOffset + sectionSize + numAlignmentBytes) {
2601+ numAlignmentBytes = fileBodySize - sectionOffset - sectionSize;
2602+ }
2603+
2604+ if (numAlignmentBytes > 0 ) {
2605+ UByteArray alignmentBytes = sections.mid (sectionOffset + sectionSize, numAlignmentBytes);
2606+ // Check alignment bytes to be sane
2607+ if (!isUniformByte (alignmentBytes, 0x00 )) {
2608+ msg (usprintf (" %s: unexpected bytes found in alignment area, should all be 0x00" , __FUNCTION__), sectionIndex);
2609+
2610+ // Add unexpected alignment bytes to tree item info
2611+ UString info;
2612+ for (UINT8 i = 0 ; i < numAlignmentBytes; i++) {
2613+ info += usprintf (" %02X " , alignmentBytes[i]);
2614+ }
2615+ info = UString (" Alignment bytes: " ) + info + " \n " ;
2616+ model->addInfo (sectionIndex, info);
2617+ }
2618+
2619+ // Store alignment bytes for upholding parsing pre/post-conditions (aka "every byte is accounted for")
2620+ model->setAlignmentBytes (sectionIndex, alignmentBytes);
2621+ }
2622+
2623+ // Adjust sectionOffset
25642624 sectionOffset = ALIGN4 (sectionOffset);
25652625 }
25662626
0 commit comments