RETURN_STATUS Status;\r
EFI_IMAGE_DOS_HEADER DosHdr;\r
UINTN Size;\r
+ UINTN ReadSize;\r
UINT16 Magic;\r
UINT32 SectionHeaderOffset;\r
UINT32 Index;\r
// Read the DOS image header to check for its existence\r
//\r
Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
0,\r
&Size,\r
&DosHdr\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
// location in both images.\r
//\r
Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
ImageContext->PeCoffHeaderOffset,\r
&Size,\r
Hdr.Pe32\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
// 1. Check FileHeader.SizeOfOptionalHeader filed.\r
//\r
if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {\r
if (Hdr.Pe32->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
return RETURN_UNSUPPORTED;\r
}\r
}\r
\r
//\r
- // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file\r
+ // 2.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file.\r
//\r
Size = 1;\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
Hdr.Pe32->OptionalHeader.SizeOfHeaders - 1,\r
&Size,\r
&BufferData\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
//\r
if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <\r
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
- return RETURN_INVALID_PARAMETER;\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+ return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
- // Read section header from file\r
+ // Read last byte of section header from file\r
//\r
Size = 1;\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +\r
&Size,\r
&BufferData\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
}\r
// 1. Check FileHeader.SizeOfOptionalHeader filed.\r
//\r
if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {\r
if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
return RETURN_UNSUPPORTED;\r
}\r
}\r
\r
//\r
- // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file\r
+ // 2.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file.\r
//\r
Size = 1;\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - 1,\r
&Size,\r
&BufferData\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
//\r
if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <\r
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
- return RETURN_INVALID_PARAMETER;\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+ return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
- // Read section header from file\r
+ // Read last byte of section header from file\r
//\r
Size = 1;\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +\r
&Size,\r
&BufferData\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
}\r
// Read section header from file\r
//\r
Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
SectionHeaderOffset,\r
&Size,\r
&SectionHeader\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
// Check the member data to avoid overflow.\r
//\r
if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) {\r
- return RETURN_INVALID_PARAMETER;\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+ return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
// Read the last byte to make sure the data is in the image region.\r
//\r
Size = 1;\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData - 1,\r
&Size,\r
&BufferData\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
}\r
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
UINTN Size;\r
+ UINTN ReadSize;\r
UINTN Index;\r
UINTN DebugDirectoryEntryRva;\r
UINTN DebugDirectoryEntryFileOffset;\r
// This case is not a valid TE image. \r
//\r
if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {\r
- return RETURN_INVALID_PARAMETER;\r
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+ return RETURN_UNSUPPORTED;\r
}\r
\r
if (!(ImageContext->IsTeImage)) {\r
// Read section header from file\r
//\r
Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
SectionHeaderOffset,\r
&Size,\r
&SectionHeader\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
// Read next debug directory entry\r
//\r
Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
DebugDirectoryEntryFileOffset + Index,\r
&Size,\r
&DebugEntry\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
// Read section header from file\r
//\r
Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
SectionHeaderOffset,\r
&Size,\r
&SectionHeader\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
// Read next debug directory entry\r
//\r
Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+ ReadSize = Size;\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
DebugDirectoryEntryFileOffset + Index,\r
&Size,\r
&DebugEntry\r
);\r
- if (RETURN_ERROR (Status)) {\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ if (Size != ReadSize) {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
return Status;\r
}\r
\r
\r
for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {\r
if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+ //\r
+ // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it.\r
+ //\r
+ if (ResourceDirectoryEntry->u1.s.NameOffset >= DirectoryEntry->Size) {\r
+ continue;\r
+ }\r
ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);\r
String = &ResourceDirectoryString->String[0];\r
\r
//\r
FixupData = RelocationData;\r
while (RelocBase < RelocBaseEnd) {\r
+ //\r
+ // Add check for RelocBase->SizeOfBlock field.\r
+ //\r
+ if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+ //\r
+ // Data invalid, cannot continue to relocate the image, just return.\r
+ //\r
+ return;\r
+ }\r
\r
Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
PE/COFF image starting at byte offset FileOffset into the buffer specified by Buffer. \r
The size of the buffer actually read is returned in ReadSize.\r
\r
+ The caller must make sure the FileOffset and ReadSize within the file scope.\r
+\r
If FileHandle is NULL, then ASSERT().\r
If ReadSize is NULL, then ASSERT().\r
If Buffer is NULL, then ASSERT().\r