VirtualBox

Ignore:
Timestamp:
Oct 28, 2015 8:17:18 PM (9 years ago)
Author:
vboxsync
Message:

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

Location:
trunk/src/VBox/Devices/EFI/Firmware
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/Firmware

  • trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoff.c

    r48674 r58459  
    33  only supports relocating IA32, x64, IPF, and EBC images.
    44
    5   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
     5  Caution: This file requires additional review when modified.
     6  This library will have external input - PE/COFF image.
     7  This external input must be validated carefully to avoid security issue like
     8  buffer overflow, integer overflow.
     9
     10  The basic guideline is that caller need provide ImageContext->ImageRead () with the
     11  necessary data range check, to make sure when this library reads PE/COFF image, the
     12  PE image buffer is always in valid range.
     13  This library will also do some additional check for PE header fields.
     14
     15  PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header.
     16  PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image.
     17
     18  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
    619  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
    720  This program and the accompanying materials
     
    1629
    1730#include "BasePeCoffLibInternals.h"
     31
     32/**
     33  Adjust some fields in section header for TE image.
     34
     35  @param  SectionHeader             Pointer to the section header.
     36  @param  TeStrippedOffset          Size adjust for the TE image.
     37
     38**/
     39VOID
     40PeCoffLoaderAdjustOffsetForTeImage (
     41  EFI_IMAGE_SECTION_HEADER              *SectionHeader,
     42  UINT32                                TeStrippedOffset
     43  )
     44{
     45  SectionHeader->VirtualAddress   -= TeStrippedOffset;
     46  SectionHeader->PointerToRawData -= TeStrippedOffset;
     47}
    1848
    1949/**
     
    4979/**
    5080  Retrieves the PE or TE Header from a PE/COFF or TE image.
    51   Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
     81
     82  Caution: This function may receive untrusted input.
     83  PE/COFF image is external input, so this routine will
     84  also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
    5285  SizeOfHeader, Section Data Region and Security Data Region be in PE image range.
    5386
     
    68101  EFI_IMAGE_DOS_HEADER  DosHdr;
    69102  UINTN                 Size;
     103  UINTN                 ReadSize;
    70104  UINT16                Magic;
    71105  UINT32                SectionHeaderOffset;
    72106  UINT32                Index;
     107  UINT32                HeaderWithoutDataDir;
    73108  CHAR8                 BufferData;
    74109  UINTN                 NumberOfSections;
     
    79114  //
    80115  Size = sizeof (EFI_IMAGE_DOS_HEADER);
     116  ReadSize = Size;
    81117  Status = ImageContext->ImageRead (
    82118                           ImageContext->Handle,
     
    85121                           &DosHdr
    86122                           );
    87   if (RETURN_ERROR (Status)) {
     123  if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    88124    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     125    if (Size != ReadSize) {
     126      Status = RETURN_UNSUPPORTED;
     127    }
    89128    return Status;
    90129  }
     
    106145  //
    107146  Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
     147  ReadSize = Size;
    108148  Status = ImageContext->ImageRead (
    109149                           ImageContext->Handle,
     
    112152                           Hdr.Pe32
    113153                           );
    114   if (RETURN_ERROR (Status)) {
     154  if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    115155    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     156    if (Size != ReadSize) {
     157      Status = RETURN_UNSUPPORTED;
     158    }
    116159    return Status;
    117160  }
     
    132175    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
    133176
     177    //
     178    // Check the StrippedSize.
     179    //
     180    if (sizeof (EFI_TE_IMAGE_HEADER) >= (UINT32)Hdr.Te->StrippedSize) {
     181      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     182      return RETURN_UNSUPPORTED;
     183    }
     184
     185    //
     186    // Check the SizeOfHeaders field.
     187    //
     188    if (Hdr.Te->BaseOfCode <= Hdr.Te->StrippedSize) {
     189      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     190      return RETURN_UNSUPPORTED;
     191    }
     192
     193    //
     194    // Read last byte of Hdr.Te->SizeOfHeaders from the file.
     195    //
     196    Size = 1;
     197    ReadSize = Size;
     198    Status = ImageContext->ImageRead (
     199                             ImageContext->Handle,
     200                             ImageContext->SizeOfHeaders - 1,
     201                             &Size,
     202                             &BufferData
     203                             );
     204    if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     205      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     206      if (Size != ReadSize) {
     207        Status = RETURN_UNSUPPORTED;
     208      }
     209      return Status;
     210    }
     211
     212    //
     213    // TE Image Data Directory Entry size is non-zero, but the Data Directory Virtual Address is zero.
     214    // This case is not a valid TE image.
     215    //
     216    if ((Hdr.Te->DataDirectory[0].Size != 0 && Hdr.Te->DataDirectory[0].VirtualAddress == 0) ||
     217        (Hdr.Te->DataDirectory[1].Size != 0 && Hdr.Te->DataDirectory[1].VirtualAddress == 0)) {
     218      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     219      return RETURN_UNSUPPORTED;
     220    }
    134221  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)  {
    135222    ImageContext->IsTeImage = FALSE;
     
    140227    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    141228      //
    142       // 1. Check FileHeader.SizeOfOptionalHeader filed.
     229      // 1. Check OptionalHeader.NumberOfRvaAndSizes filed.
    143230      //
    144231      if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {
     232        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
    145233        return RETURN_UNSUPPORTED;
    146234      }
    147235
    148236      //
    149       // 2. Check the OptionalHeader.SizeOfHeaders field.
    150       // This field will be use like the following mode, so just compare the result.
    151       // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
    152       //
    153       if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {
    154         if (Hdr.Pe32->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {
    155           return RETURN_UNSUPPORTED;
    156         }
    157       }
    158 
    159       //
    160       // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file
     237      // 2. Check the FileHeader.SizeOfOptionalHeader field.
     238      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so
     239      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.
     240      //
     241      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
     242      if (((UINT32)Hdr.Pe32->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
     243          Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
     244        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     245        return RETURN_UNSUPPORTED;
     246      }
     247
     248      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
     249      //
     250      // 3. Check the FileHeader.NumberOfSections field.
     251      //
     252      if (Hdr.Pe32->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {
     253        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     254        return RETURN_UNSUPPORTED;
     255      }
     256      if ((Hdr.Pe32->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32->FileHeader.NumberOfSections) {
     257        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     258        return RETURN_UNSUPPORTED;
     259      }
     260
     261      //
     262      // 4. Check the OptionalHeader.SizeOfHeaders field.
     263      //
     264      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {
     265        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     266        return RETURN_UNSUPPORTED;
     267      }
     268      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders >= Hdr.Pe32->OptionalHeader.SizeOfImage) {
     269        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     270        return RETURN_UNSUPPORTED;
     271      }
     272      if ((Hdr.Pe32->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32->FileHeader.NumberOfSections) {
     273        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     274        return RETURN_UNSUPPORTED;
     275      }
     276
     277      //
     278      // 4.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file.
    161279      //
    162280      Size = 1;
     281      ReadSize = Size;
    163282      Status = ImageContext->ImageRead (
    164283                               ImageContext->Handle,
     
    167286                               &BufferData
    168287                               );
    169       if (RETURN_ERROR (Status)) {
     288      if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     289        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     290        if (Size != ReadSize) {
     291          Status = RETURN_UNSUPPORTED;
     292        }
    170293        return Status;
    171294      }
     
    183306          if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <
    184307              Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
    185             return RETURN_INVALID_PARAMETER;
     308            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     309            return RETURN_UNSUPPORTED;
    186310          }
    187311
    188312          //
    189           // Read section header from file
     313          // Read last byte of section header from file
    190314          //
    191315          Size = 1;
     316          ReadSize = Size;
    192317          Status = ImageContext->ImageRead (
    193318                                   ImageContext->Handle,
     
    197322                                   &BufferData
    198323                                   );
    199           if (RETURN_ERROR (Status)) {
     324          if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     325            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     326            if (Size != ReadSize) {
     327              Status = RETURN_UNSUPPORTED;
     328            }
    200329            return Status;
    201330          }
     
    213342    } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    214343      //
    215       // 1. Check FileHeader.SizeOfOptionalHeader filed.
     344      // 1. Check FileHeader.NumberOfRvaAndSizes filed.
    216345      //
    217346      if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {
     347        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
    218348        return RETURN_UNSUPPORTED;
    219349      }
    220 
    221       //
    222       // 2. Check the OptionalHeader.SizeOfHeaders field.
    223       // This field will be use like the following mode, so just compare the result.
    224       // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
    225       //
    226       if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {
    227         if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {
    228           return RETURN_UNSUPPORTED;
    229         }
    230       }
    231 
    232       //
    233       // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file
     350      //
     351      // 2. Check the FileHeader.SizeOfOptionalHeader field.
     352      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so
     353      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.
     354      //
     355      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER64) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
     356      if (((UINT32)Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
     357          Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
     358        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     359        return RETURN_UNSUPPORTED;
     360      }
     361
     362      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;
     363      //
     364      // 3. Check the FileHeader.NumberOfSections field.
     365      //
     366      if (Hdr.Pe32Plus->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {
     367        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     368        return RETURN_UNSUPPORTED;
     369      }
     370      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32Plus->FileHeader.NumberOfSections) {
     371        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     372        return RETURN_UNSUPPORTED;
     373      }
     374
     375      //
     376      // 4. Check the OptionalHeader.SizeOfHeaders field.
     377      //
     378      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {
     379        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     380        return RETURN_UNSUPPORTED;
     381      }
     382      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders >= Hdr.Pe32Plus->OptionalHeader.SizeOfImage) {
     383        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     384        return RETURN_UNSUPPORTED;
     385      }
     386      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32Plus->FileHeader.NumberOfSections) {
     387        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     388        return RETURN_UNSUPPORTED;
     389      }
     390
     391      //
     392      // 4.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file.
    234393      //
    235394      Size = 1;
     395      ReadSize = Size;
    236396      Status = ImageContext->ImageRead (
    237397                               ImageContext->Handle,
     
    240400                               &BufferData
    241401                               );
    242       if (RETURN_ERROR (Status)) {
     402      if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     403        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     404        if (Size != ReadSize) {
     405          Status = RETURN_UNSUPPORTED;
     406        }
    243407        return Status;
    244408      }
     
    256420          if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <
    257421              Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
    258             return RETURN_INVALID_PARAMETER;
     422            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     423            return RETURN_UNSUPPORTED;
    259424          }
    260425
    261426          //
    262           // Read section header from file
     427          // Read last byte of section header from file
    263428          //
    264429          Size = 1;
     430          ReadSize = Size;
    265431          Status = ImageContext->ImageRead (
    266432                                   ImageContext->Handle,
     
    270436                                   &BufferData
    271437                                   );
    272           if (RETURN_ERROR (Status)) {
     438          if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     439            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     440            if (Size != ReadSize) {
     441              Status = RETURN_UNSUPPORTED;
     442            }
    273443            return Status;
    274444          }
     
    318488    //
    319489    Size = sizeof (EFI_IMAGE_SECTION_HEADER);
     490    ReadSize = Size;
    320491    Status = ImageContext->ImageRead (
    321492                             ImageContext->Handle,
     
    324495                             &SectionHeader
    325496                             );
    326     if (RETURN_ERROR (Status)) {
     497    if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     498      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     499      if (Size != ReadSize) {
     500        Status = RETURN_UNSUPPORTED;
     501      }
    327502      return Status;
    328503    }
    329504
     505    //
     506    // Adjust some field in Section Header for TE image.
     507    //
     508    if (ImageContext->IsTeImage) {
     509      PeCoffLoaderAdjustOffsetForTeImage (&SectionHeader, (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
     510    }
     511
    330512    if (SectionHeader.SizeOfRawData > 0) {
    331513      //
     514      // Section data should bigger than the Pe header.
     515      //
     516      if (SectionHeader.VirtualAddress < ImageContext->SizeOfHeaders ||
     517          SectionHeader.PointerToRawData < ImageContext->SizeOfHeaders) {
     518        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     519        return RETURN_UNSUPPORTED;
     520      }
     521
     522      //
    332523      // Check the member data to avoid overflow.
    333524      //
    334525      if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) {
    335         return RETURN_INVALID_PARAMETER;
     526        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     527        return RETURN_UNSUPPORTED;
    336528      }
    337529
     
    341533      //
    342534      Size = 1;
     535      ReadSize = Size;
    343536      Status = ImageContext->ImageRead (
    344537                               ImageContext->Handle,
     
    347540                               &BufferData
    348541                               );
    349       if (RETURN_ERROR (Status)) {
     542      if (RETURN_ERROR (Status) || (Size != ReadSize)) {
     543        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     544        if (Size != ReadSize) {
     545          Status = RETURN_UNSUPPORTED;
     546        }
    350547        return Status;
    351548      }
     
    377574  to invoking this service.
    378575
    379   Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
     576  Caution: This function may receive untrusted input.
     577  PE/COFF image is external input, so this routine will
     578  also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
    380579  SizeOfHeader, Section Data Region and Security Data Region be in PE image range.
    381580
     
    399598  EFI_IMAGE_DATA_DIRECTORY              *DebugDirectoryEntry;
    400599  UINTN                                 Size;
     600  UINTN                                 ReadSize;
    401601  UINTN                                 Index;
    402602  UINTN                                 DebugDirectoryEntryRva;
     
    407607  UINT32                                NumberOfRvaAndSizes;
    408608  UINT16                                Magic;
     609  UINT32                                TeStrippedOffset;
    409610
    410611  if (ImageContext == NULL) {
     
    428629  //
    429630  if (!(ImageContext->IsTeImage)) {
     631    TeStrippedOffset = 0;
    430632    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    431633      //
     
    440642    }
    441643  } else {
    442     ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
     644    TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
     645    ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + TeStrippedOffset);
    443646  }
    444647
     
    474677    ImageContext->RelocationsStripped = FALSE;
    475678  }
    476  
    477   //
    478   // TE Image Relocation Data Directory Entry size is non-zero, but the Relocation Data Directory Virtual Address is zero.
    479   // This case is not a valid TE image.
    480   //
    481   if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {
    482     return RETURN_INVALID_PARAMETER;
    483   }
    484679
    485680  if (!(ImageContext->IsTeImage)) {
     
    521716        //
    522717        Size = sizeof (EFI_IMAGE_SECTION_HEADER);
     718        ReadSize = Size;
    523719        Status = ImageContext->ImageRead (
    524720                                 ImageContext->Handle,
     
    527723                                 &SectionHeader
    528724                                 );
    529         if (RETURN_ERROR (Status)) {
     725        if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    530726          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     727          if (Size != ReadSize) {
     728            Status = RETURN_UNSUPPORTED;
     729          }
    531730          return Status;
    532731        }
     
    548747          //
    549748          Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
     749          ReadSize = Size;
    550750          Status = ImageContext->ImageRead (
    551751                                   ImageContext->Handle,
     
    554754                                   &DebugEntry
    555755                                   );
    556           if (RETURN_ERROR (Status)) {
     756          if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    557757            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     758            if (Size != ReadSize) {
     759              Status = RETURN_UNSUPPORTED;
     760            }
    558761            return Status;
    559762          }
     763
     764          //
     765          // From PeCoff spec, when DebugEntry.RVA == 0 means this debug info will not load into memory.
     766          // Here we will always load EFI_IMAGE_DEBUG_TYPE_CODEVIEW type debug info. so need adjust the
     767          // ImageContext->ImageSize when DebugEntry.RVA == 0.
     768          //
    560769          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
    561770            ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
     
    582791      //
    583792      Size   = sizeof (EFI_IMAGE_SECTION_HEADER);
     793      ReadSize = Size;
    584794      Status = ImageContext->ImageRead (
    585795                               ImageContext->Handle,
     
    588798                               &SectionHeader
    589799                               );
    590       if (RETURN_ERROR (Status)) {
     800      if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    591801        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     802        if (Size != ReadSize) {
     803          Status = RETURN_UNSUPPORTED;
     804        }
    592805        return Status;
    593806      }
     
    597810        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -
    598811                                        SectionHeader.VirtualAddress +
    599                                         SectionHeader.PointerToRawData +
    600                                         sizeof (EFI_TE_IMAGE_HEADER) -
    601                                         Hdr.Te->StrippedSize;
     812                                        SectionHeader.PointerToRawData -
     813                                        TeStrippedOffset;
    602814
    603815        //
     
    623835      //
    624836      if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) {
    625         ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize);
     837        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) - TeStrippedOffset;
    626838      }
    627839
     
    635847        //
    636848        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
     849        ReadSize = Size;
    637850        Status = ImageContext->ImageRead (
    638851                                 ImageContext->Handle,
     
    641854                                 &DebugEntry
    642855                                 );
    643         if (RETURN_ERROR (Status)) {
     856        if (RETURN_ERROR (Status) || (Size != ReadSize)) {
    644857          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     858          if (Size != ReadSize) {
     859            Status = RETURN_UNSUPPORTED;
     860          }
    645861          return Status;
    646862        }
     
    661877  Converts an image address to the loaded address.
    662878
    663   @param  ImageContext  The context of the image being loaded.
    664   @param  Address       The relative virtual address to be converted to the loaded address.
     879  @param  ImageContext      The context of the image being loaded.
     880  @param  Address           The address to be converted to the loaded address.
     881  @param  TeStrippedOffset  Stripped offset for TE image.
    665882
    666883  @return The converted address or NULL if the address can not be converted.
     
    670887PeCoffLoaderImageAddress (
    671888  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,
    672   IN     UINTN                                 Address
     889  IN     UINTN                                 Address,
     890  IN     UINTN                                 TeStrippedOffset
    673891  )
    674892{
     
    676894  // Make sure that Address and ImageSize is correct for the loaded image.
    677895  //
    678   if (Address >= ImageContext->ImageSize) {
     896  if (Address >= ImageContext->ImageSize + TeStrippedOffset) {
    679897    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
    680898    return NULL;
    681899  }
    682900
    683   return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address);
     901  return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address - TeStrippedOffset);
    684902}
    685903
     
    724942  EFI_IMAGE_DATA_DIRECTORY              *RelocDir;
    725943  UINT64                                Adjust;
     944  EFI_IMAGE_BASE_RELOCATION             *RelocBaseOrg;
    726945  EFI_IMAGE_BASE_RELOCATION             *RelocBase;
    727946  EFI_IMAGE_BASE_RELOCATION             *RelocBaseEnd;
     
    737956  UINT32                                NumberOfRvaAndSizes;
    738957  UINT16                                Magic;
     958  UINT32                                TeStrippedOffset;
    739959
    740960  ASSERT (ImageContext != NULL);
     
    767987  if (!(ImageContext->IsTeImage)) {
    768988    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
    769 
     989    TeStrippedOffset = 0;
    770990    Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);
    771991
     
    8001020    // the optional header to verify a desired directory entry is there.
    8011021    //
    802 
    803     if ((NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) && (RelocDir->Size > 0)) {
    804       RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
    805       RelocBaseEnd = PeCoffLoaderImageAddress (
    806                       ImageContext,
    807                       RelocDir->VirtualAddress + RelocDir->Size - 1
    808                       );
    809       if (RelocBase == NULL || RelocBaseEnd == NULL) {
    810         return RETURN_LOAD_ERROR;
    811       }
    812     } else {
    813       //
    814       // Set base and end to bypass processing below.
    815       //
    816       RelocBase = RelocBaseEnd = NULL;
     1022    if ((NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)) {
     1023      RelocDir = NULL;
    8171024    }
    8181025  } else {
    8191026    Hdr.Te             = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
    820     Adjust             = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase);
     1027    TeStrippedOffset   = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
     1028    Adjust             = (UINT64) (BaseAddress - (Hdr.Te->ImageBase + TeStrippedOffset));
    8211029    if (Adjust != 0) {
    822       Hdr.Te->ImageBase  = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
     1030      Hdr.Te->ImageBase  = (UINT64) (BaseAddress - TeStrippedOffset);
    8231031    }
    8241032
     
    8271035    //
    8281036    RelocDir = &Hdr.Te->DataDirectory[0];
    829     if (RelocDir->Size > 0) {
    830       RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(
    831                                       ImageContext->ImageAddress +
    832                                       RelocDir->VirtualAddress +
    833                                       sizeof(EFI_TE_IMAGE_HEADER) -
    834                                       Hdr.Te->StrippedSize
    835                                       );
    836       RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);
    837     } else {
    838       //
    839       // Set base and end to bypass processing below.
    840       //
    841       RelocBase = RelocBaseEnd = NULL;   
    842     }
    843   }
     1037  }
     1038
     1039  if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
     1040    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
     1041    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext,
     1042                                                                            RelocDir->VirtualAddress + RelocDir->Size - 1,
     1043                                                                            TeStrippedOffset
     1044                                                                            );
     1045    if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
     1046      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1047      return RETURN_LOAD_ERROR;
     1048    }
     1049  } else {
     1050    //
     1051    // Set base and end to bypass processing below.
     1052    //
     1053    RelocBase = RelocBaseEnd = NULL;   
     1054  }
     1055  RelocBaseOrg = RelocBase;
    8441056
    8451057  //
     
    8541066
    8551067      Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
    856       RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
    857      
    858       //
    859       // Make sure RelocEnd is in the Image range.
    860       //
    861       if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||
    862           (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {
     1068      //
     1069      // Add check for RelocBase->SizeOfBlock field.
     1070      //
     1071      if (RelocBase->SizeOfBlock == 0) {
    8631072        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
    8641073        return RETURN_LOAD_ERROR;
    8651074      }
    866 
    867       if (!(ImageContext->IsTeImage)) {
    868         FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
    869         if (FixupBase == NULL) {
     1075      if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {
     1076        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1077        return RETURN_LOAD_ERROR;
     1078      }
     1079
     1080      RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
     1081      if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {
     1082        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1083        return RETURN_LOAD_ERROR;
     1084      }
     1085      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);
     1086      if (FixupBase == NULL) {
     1087        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1088        return RETURN_LOAD_ERROR;
     1089      } 
     1090
     1091      //
     1092      // Run this relocation record
     1093      //
     1094      while (Reloc < RelocEnd) {
     1095        Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);
     1096        if (Fixup == NULL) {
     1097          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
    8701098          return RETURN_LOAD_ERROR;
    8711099        }
    872       } else {
    873         FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
    874                       RelocBase->VirtualAddress +
    875                       sizeof(EFI_TE_IMAGE_HEADER) -
    876                       Hdr.Te->StrippedSize
    877                       );
    878       }   
    879 
    880       //
    881       // Run this relocation record
    882       //
    883       while (Reloc < RelocEnd) {
    884 
    885         Fixup = FixupBase + (*Reloc & 0xFFF);
    8861100        switch ((*Reloc) >> 12) {
    8871101        case EFI_IMAGE_REL_BASED_ABSOLUTE:
     
    9501164      RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
    9511165    }
     1166    ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);
    9521167
    9531168    //
     
    10131228  CHAR8                                 *Base;
    10141229  CHAR8                                 *End;
    1015   CHAR8                                 *MaxEnd;
    10161230  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
    10171231  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
     
    10251239  EFI_IMAGE_RESOURCE_DATA_ENTRY         *ResourceDataEntry;
    10261240  CHAR16                                *String;
    1027 
     1241  UINT32                                Offset;
     1242  UINT32                                TeStrippedOffset;
    10281243
    10291244  ASSERT (ImageContext != NULL);
     
    11121327      );
    11131328    NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);
     1329    TeStrippedOffset = 0;
    11141330  } else {
    11151331    Status = ImageContext->ImageRead (
     
    11211337
    11221338    Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
    1123 
    11241339    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
    11251340                      (UINTN)ImageContext->ImageAddress +
     
    11271342                      );
    11281343    NumberOfSections  = (UINTN) (Hdr.Te->NumberOfSections);
    1129 
     1344    TeStrippedOffset  = (UINT32) Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
    11301345  }
    11311346
     
    11391354  //
    11401355  Section = FirstSection;
    1141   for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {
     1356  for (Index = 0; Index < NumberOfSections; Index++) {
    11421357    //
    11431358    // Read the section
     
    11511366    // Compute sections address
    11521367    //
    1153     Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);
    1154     End = PeCoffLoaderImageAddress (
    1155             ImageContext,
    1156             Section->VirtualAddress + Section->Misc.VirtualSize - 1
    1157             );
     1368    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress, TeStrippedOffset);
     1369    End  = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress + Section->Misc.VirtualSize - 1, TeStrippedOffset);
    11581370
    11591371    //
     
    11651377    }
    11661378
    1167     if (ImageContext->IsTeImage) {
    1168       Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
    1169       End  = (CHAR8 *)((UINTN) End +  sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
    1170     }
    1171 
    1172     if (End > MaxEnd) {
    1173       MaxEnd = End;
    1174     }
    1175 
    11761379    if (Section->SizeOfRawData > 0) {
    1177       if (!(ImageContext->IsTeImage)) {
    1178         Status = ImageContext->ImageRead (
    1179                                 ImageContext->Handle,
    1180                                 Section->PointerToRawData,
    1181                                 &Size,
    1182                                 Base
    1183                                 );
    1184       } else {
    1185         Status = ImageContext->ImageRead (
    1186                                 ImageContext->Handle,
    1187                                 Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize,
    1188                                 &Size,
    1189                                 Base
    1190                                 );
    1191       }
    1192 
     1380      Status = ImageContext->ImageRead (
     1381                              ImageContext->Handle,
     1382                              Section->PointerToRawData - TeStrippedOffset,
     1383                              &Size,
     1384                              Base
     1385                              );
    11931386      if (RETURN_ERROR (Status)) {
    11941387        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
     
    12251418      ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
    12261419                                                            ImageContext,
    1227                                                             (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint
     1420                                                            (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint,
     1421                                                            0
    12281422                                                            );
    12291423    } else {
     
    12331427      ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
    12341428                                                            ImageContext,
    1235                                                             (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint
     1429                                                            (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint,
     1430                                                            0
    12361431                                                            );
    12371432    }
    12381433  } else {
    1239     ImageContext->EntryPoint =  (PHYSICAL_ADDRESS) (
    1240                                 (UINTN)ImageContext->ImageAddress  +
    1241                                 (UINTN)Hdr.Te->AddressOfEntryPoint +
    1242                                 (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
    1243                                 (UINTN)Hdr.Te->StrippedSize
    1244                                 );
     1434    ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
     1435                                                          ImageContext,
     1436                                                          (UINTN)Hdr.Te->AddressOfEntryPoint,
     1437                                                          TeStrippedOffset
     1438                                                          );
    12451439  }
    12461440
     
    12671461    }
    12681462
     1463    //
     1464    // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.
     1465    //
    12691466    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
    1270       ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
     1467      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
    12711468    } else {
    12721469      ImageContext->FixupDataSize = 0;
     
    12741471  } else {
    12751472    DirectoryEntry              = &Hdr.Te->DataDirectory[0];
    1276     ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
     1473    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
    12771474  }
    12781475  //
     
    12861483  //
    12871484  if (ImageContext->DebugDirectoryEntryRva != 0) {
    1288     if (!(ImageContext->IsTeImage)) {
    1289       DebugEntry = PeCoffLoaderImageAddress (
    1290                     ImageContext,
    1291                     ImageContext->DebugDirectoryEntryRva
    1292                     );
    1293     } else {
    1294       DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
    1295                       ImageContext->ImageAddress +
    1296                       ImageContext->DebugDirectoryEntryRva +
    1297                       sizeof(EFI_TE_IMAGE_HEADER) -
    1298                       Hdr.Te->StrippedSize
    1299                       );
    1300     }
    1301 
    1302     if (DebugEntry != NULL) {
    1303       TempDebugEntryRva = DebugEntry->RVA;
    1304       if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
    1305         Section--;
    1306         if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {
    1307           TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
    1308         } else {
    1309           TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
    1310         }
    1311       }
    1312 
    1313       if (TempDebugEntryRva != 0) {
    1314         if (!(ImageContext->IsTeImage)) {
    1315           ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);
    1316         } else {
    1317           ImageContext->CodeView = (VOID *)(
    1318                                     (UINTN)ImageContext->ImageAddress +
    1319                                     (UINTN)TempDebugEntryRva +
    1320                                     (UINTN)sizeof (EFI_TE_IMAGE_HEADER) -
    1321                                     (UINTN) Hdr.Te->StrippedSize
    1322                                     );
    1323         }
    1324 
    1325         if (ImageContext->CodeView == NULL) {
     1485    DebugEntry = PeCoffLoaderImageAddress (
     1486                ImageContext,
     1487                ImageContext->DebugDirectoryEntryRva,
     1488                TeStrippedOffset
     1489                );
     1490    if (DebugEntry == NULL) {
     1491      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1492      return RETURN_LOAD_ERROR;
     1493    }
     1494
     1495    TempDebugEntryRva = DebugEntry->RVA;
     1496    if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
     1497      Section--;
     1498      if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {
     1499        TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
     1500      } else {
     1501        TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
     1502      }
     1503    }
     1504
     1505    if (TempDebugEntryRva != 0) {
     1506      ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva, TeStrippedOffset);
     1507      if (ImageContext->CodeView == NULL) {
     1508        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
     1509        return RETURN_LOAD_ERROR;
     1510      }
     1511
     1512      if (DebugEntry->RVA == 0) {
     1513        Size = DebugEntry->SizeOfData;
     1514        Status = ImageContext->ImageRead (
     1515                                ImageContext->Handle,
     1516                                DebugEntry->FileOffset - TeStrippedOffset,
     1517                                &Size,
     1518                                ImageContext->CodeView
     1519                                );
     1520        //
     1521        // Should we apply fix up to this field according to the size difference between PE and TE?
     1522        // Because now we maintain TE header fields unfixed, this field will also remain as they are
     1523        // in original PE image.
     1524        //
     1525
     1526        if (RETURN_ERROR (Status)) {
    13261527          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
    13271528          return RETURN_LOAD_ERROR;
    13281529        }
    13291530
    1330         if (DebugEntry->RVA == 0) {
    1331           Size = DebugEntry->SizeOfData;
    1332           if (!(ImageContext->IsTeImage)) {
    1333             Status = ImageContext->ImageRead (
    1334                                     ImageContext->Handle,
    1335                                     DebugEntry->FileOffset,
    1336                                     &Size,
    1337                                     ImageContext->CodeView
    1338                                     );
    1339           } else {
    1340             Status = ImageContext->ImageRead (
    1341                                     ImageContext->Handle,
    1342                                     DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize,
    1343                                     &Size,
    1344                                     ImageContext->CodeView
    1345                                     );
    1346             //
    1347             // Should we apply fix up to this field according to the size difference between PE and TE?
    1348             // Because now we maintain TE header fields unfixed, this field will also remain as they are
    1349             // in original PE image.
    1350             //
    1351           }
    1352 
    1353           if (RETURN_ERROR (Status)) {
    1354             ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
    1355             return RETURN_LOAD_ERROR;
    1356           }
    1357 
    1358           DebugEntry->RVA = TempDebugEntryRva;
    1359         }
    1360 
    1361         switch (*(UINT32 *) ImageContext->CodeView) {
    1362         case CODEVIEW_SIGNATURE_NB10:
    1363           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
    1364           break;
    1365 
    1366         case CODEVIEW_SIGNATURE_RSDS:
    1367           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
    1368           break;
    1369 
    1370         case CODEVIEW_SIGNATURE_MTOC:
    1371           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
    1372           break;
    1373 
    1374         default:
    1375           break;
    1376         }
     1531        DebugEntry->RVA = TempDebugEntryRva;
     1532      }
     1533
     1534      switch (*(UINT32 *) ImageContext->CodeView) {
     1535      case CODEVIEW_SIGNATURE_NB10:
     1536        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {
     1537          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1538          return RETURN_UNSUPPORTED;
     1539        }
     1540        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
     1541        break;
     1542
     1543      case CODEVIEW_SIGNATURE_RSDS:
     1544        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {
     1545          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1546          return RETURN_UNSUPPORTED;
     1547        }
     1548        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
     1549        break;
     1550
     1551      case CODEVIEW_SIGNATURE_MTOC:
     1552        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {
     1553          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1554          return RETURN_UNSUPPORTED;
     1555        }
     1556        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
     1557        break;
     1558
     1559      default:
     1560        break;
    13771561      }
    13781562    }
     
    13881572      // Use PE32 offset
    13891573      //
     1574      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
    13901575      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];
    13911576    } else {
     
    13931578      // Use PE32+ offset
    13941579      //
     1580      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
    13951581      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];
    13961582    }
    13971583
    1398     if (DirectoryEntry->Size != 0) {
    1399       Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress);
     1584    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && DirectoryEntry->Size != 0) {
     1585      Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress, 0);
    14001586      if (Base != NULL) {
    14011587        ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;
     1588        Offset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) *
     1589               (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);
     1590        if (Offset > DirectoryEntry->Size) {
     1591          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1592          return RETURN_UNSUPPORTED;
     1593        }
    14021594        ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
    14031595
    14041596        for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {
    14051597          if (ResourceDirectoryEntry->u1.s.NameIsString) {
     1598            //
     1599            // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it.
     1600            //
     1601            if (ResourceDirectoryEntry->u1.s.NameOffset >= DirectoryEntry->Size) {
     1602              ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1603              return RETURN_UNSUPPORTED;
     1604            }
    14061605            ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);
    14071606            String = &ResourceDirectoryString->String[0];
     
    14181617                // Move to next level - resource Name
    14191618                //
     1619                if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) {
     1620                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1621                  return RETURN_UNSUPPORTED;
     1622                }
    14201623                ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
     1624                Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) +
     1625                         sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);
     1626                if (Offset > DirectoryEntry->Size) {
     1627                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1628                  return RETURN_UNSUPPORTED;
     1629                }
    14211630                ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
    14221631
     
    14251634                  // Move to next level - resource Language
    14261635                  //
     1636                  if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) {
     1637                    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1638                    return RETURN_UNSUPPORTED;
     1639                  }
    14271640                  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
     1641                  Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) +
     1642                           sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);
     1643                  if (Offset > DirectoryEntry->Size) {
     1644                    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1645                    return RETURN_UNSUPPORTED;
     1646                  }
    14281647                  ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
    14291648                }
     
    14341653              //
    14351654              if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {
     1655                if (ResourceDirectoryEntry->u2.OffsetToData >= DirectoryEntry->Size) {
     1656                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
     1657                  return RETURN_UNSUPPORTED;
     1658                }
    14361659                ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);
    1437                 ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData);
     1660                ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData, 0);
    14381661                break;
    14391662              }
     
    15791802  FixupData = RelocationData;
    15801803  while (RelocBase < RelocBaseEnd) {
     1804    //
     1805    // Add check for RelocBase->SizeOfBlock field.
     1806    //
     1807    if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {
     1808      //
     1809      // Data invalid, cannot continue to relocate the image, just return.
     1810      //
     1811      return;
     1812    }
    15811813
    15821814    Reloc     = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
     
    16311863
    16321864        FixupData = FixupData + sizeof (UINT64);
    1633         break;
    1634 
    1635       case EFI_IMAGE_REL_BASED_HIGHADJ:
    1636         //
    1637         // Not valid Relocation type for UEFI image, ASSERT
    1638         //
    1639         ASSERT (FALSE);
    16401865        break;
    16411866
     
    16721897  The size of the buffer actually read is returned in ReadSize.
    16731898 
     1899  The caller must make sure the FileOffset and ReadSize within the file scope.
     1900
    16741901  If FileHandle is NULL, then ASSERT().
    16751902  If ReadSize is NULL, then ASSERT().
  • trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf

    r48674 r58459  
    55#  The X64 version library support loading IA32, X64 and EBC PE/COFF images.
    66#
    7 #  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
     7#  Caution: This module requires additional review when modified.
     8#  This library will have external input - PE/COFF image.
     9#  This external input must be validated carefully to avoid security issue like
     10#  buffer overflow, integer overflow.
     11#
     12#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
    813#  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
    914#
     
    2126  INF_VERSION                    = 0x00010005
    2227  BASE_NAME                      = BasePeCoffLib
     28  MODULE_UNI_FILE                = BasePeCoffLib.uni
    2329  FILE_GUID                      = 556f5d10-7309-4af4-b80a-8196bd60946f
    2430  MODULE_TYPE                    = BASE
     
    2834
    2935#
    30 #  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM
     36#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64
    3137#
    3238
     
    4450  Arm/PeCoffLoaderEx.c
    4551
     52[Sources.AARCH64]
     53  AArch64/PeCoffLoaderEx.c
     54
    4655[Packages]
    4756  MdePkg/MdePkg.dec
  • trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h

    r48674 r58459  
    117117  Converts an image address to the loaded address.
    118118
    119   @param  ImageContext  The context of the image being loaded.
    120   @param  Address       The address to be converted to the loaded address.
     119  @param  ImageContext      The context of the image being loaded.
     120  @param  Address           The address to be converted to the loaded address.
     121  @param  TeStrippedOffset  Stripped offset for TE image.
    121122
    122123  @return The converted address or NULL if the address can not be converted.
     
    126127PeCoffLoaderImageAddress (
    127128  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,
    128   IN     UINTN                                 Address
     129  IN     UINTN                                 Address,
     130  IN     UINTN                                 TeStrippedOffset
    129131  );
    130132
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette