[if gte mso 9]>

[edk2] FindImageBase and FVs with 0xff padding.

Subject: [edk2] FindImageBase and FVs with 0xff padding.

From: Tim Lewis <tim.lewis@insyde.com>

To: "edk2-devel@lists.sourceforge.net" <edk2-devel@lists.sourceforge.net>

Date: 2014-11-07 07:13:07

  • 2014-11-07 07:13:07  Tim Lewis   [edk2] FindImageBase and FVs with 0xff padding.

There are several instances of a function like FindImageBase() (IntelFspWrapperPkg, OvmfPkg/Sec). These functions all share common flaws:

 

1)      If the FV does not begin with a file, then the code does not correctly skip the empty space at the beginning of the FV that is filled with 0xFF. This happens when the gap at the beginning of the FV is less than 24 bytes. This happens because a FILETYPE_PAD file requires at least 24 bytes for the header and header alignment only needs to be 8 bytes. Per the PI specification, it is filled with the ERASE_POLARITY value (0x00 or 0xff)

2)      If the FV does not end with a file, a similar result happens because the empty space is assumed to be a file header and the new “size” of the file is either 0xffffffff or 0x00000000, both of which lead to problems.

3)      If the FV is less than 24 bytes in length the code will fail. This is a rare case, but it is possible to have valid FVs like this, per the spec.

 

Consider this piece from IntelFspWrapperPkg

 

for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {

 

    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;

    if (CurrentAddress > EndOfFirmwareVolume) {

      return EFI_NOT_FOUND;

    }

 

   /* CONSIDER THE CASE WHERE THERE IS EMPTY SPACE AT THE BEGINNING OF THE FV */

    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;

    if (IS_FFS_FILE2 (File)) {

      Size = FFS_FILE2_SIZE (File);

      if (Size <= 0x00FFFFFF) {

        return EFI_NOT_FOUND;

      }

    } else {

      Size = FFS_FILE_SIZE (File);

      if (Size < sizeof (EFI_FFS_FILE_HEADER)) {

        return EFI_NOT_FOUND;

      }

    }

 

    EndOfFile = CurrentAddress + Size;

  /* AT THIS POINT, WE MIGHT BE POINTING TO EndOfFirmwareVolume – 16, pointing to 0xFFFFFFFF */

 

    if (EndOfFile > EndOfFirmwareVolume) {

      return EFI_NOT_FOUND;

    }

 

    //

    // Look for SEC Core / PEI Core files

    //

    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&

        File->Type != EFI_FV_FILETYPE_PEI_CORE) {

      continue;

    }