mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-28 16:14:04 +02:00
Validate some fields in PE image to make sure not access violation for later code.
Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13211 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
035da677c8
commit
28186d4566
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Core image handling services to load and unload PeImage.
|
Core image handling services to load and unload PeImage.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -232,6 +232,14 @@ CoreReadImageFile (
|
|||||||
UINTN EndPosition;
|
UINTN EndPosition;
|
||||||
IMAGE_FILE_HANDLE *FHand;
|
IMAGE_FILE_HANDLE *FHand;
|
||||||
|
|
||||||
|
if (UserHandle == NULL || ReadSize == NULL || Buffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAX_ADDRESS - Offset < *ReadSize) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
FHand = (IMAGE_FILE_HANDLE *)UserHandle;
|
FHand = (IMAGE_FILE_HANDLE *)UserHandle;
|
||||||
ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
|
ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ PeCoffLoaderGetPeHeaderMagicValue (
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieves the PE or TE Header from a PE/COFF or TE image.
|
Retrieves the PE or TE Header from a PE/COFF or TE image.
|
||||||
|
Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
|
||||||
|
SizeOfHeader, Section Data Region and Security Data Region be in PE image range.
|
||||||
|
|
||||||
@param ImageContext The context of the image being loaded.
|
@param ImageContext The context of the image being loaded.
|
||||||
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
|
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
|
||||||
@ -66,6 +68,10 @@ PeCoffLoaderGetPeHeader (
|
|||||||
EFI_IMAGE_DOS_HEADER DosHdr;
|
EFI_IMAGE_DOS_HEADER DosHdr;
|
||||||
UINTN Size;
|
UINTN Size;
|
||||||
UINT16 Magic;
|
UINT16 Magic;
|
||||||
|
UINT32 SectionHeaderOffset;
|
||||||
|
UINT32 Index;
|
||||||
|
CHAR8 BufferData;
|
||||||
|
EFI_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read the DOS image header to check for its existence
|
// Read the DOS image header to check for its existence
|
||||||
@ -131,6 +137,74 @@ PeCoffLoaderGetPeHeader (
|
|||||||
Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);
|
Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);
|
||||||
|
|
||||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
//
|
||||||
|
// 1. Check FileHeader.SizeOfOptionalHeader filed.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hdr.Pe32->FileHeader.SizeOfOptionalHeader != sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES - Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2. Check the OptionalHeader.SizeOfHeaders field.
|
||||||
|
// This field will be use like the following mode, so just compare the result.
|
||||||
|
// The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
if (Hdr.Pe32->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file
|
||||||
|
//
|
||||||
|
Size = 1;
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
Hdr.Pe32->OptionalHeader.SizeOfHeaders - 1,
|
||||||
|
&Size,
|
||||||
|
&BufferData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the EFI_IMAGE_DIRECTORY_ENTRY_SECURITY data.
|
||||||
|
// Read the last byte to make sure the data is in the image region.
|
||||||
|
// The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
if (Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size != 0) {
|
||||||
|
//
|
||||||
|
// Check the member data to avoid overflow.
|
||||||
|
//
|
||||||
|
if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <
|
||||||
|
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read section header from file
|
||||||
|
//
|
||||||
|
Size = 1;
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +
|
||||||
|
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - 1,
|
||||||
|
&Size,
|
||||||
|
&BufferData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use PE32 offset
|
// Use PE32 offset
|
||||||
//
|
//
|
||||||
@ -140,6 +214,74 @@ PeCoffLoaderGetPeHeader (
|
|||||||
ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
|
ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
|
||||||
|
|
||||||
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
//
|
||||||
|
// 1. Check FileHeader.SizeOfOptionalHeader filed.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader != sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES - Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2. Check the OptionalHeader.SizeOfHeaders field.
|
||||||
|
// This field will be use like the following mode, so just compare the result.
|
||||||
|
// The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file
|
||||||
|
//
|
||||||
|
Size = 1;
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - 1,
|
||||||
|
&Size,
|
||||||
|
&BufferData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the EFI_IMAGE_DIRECTORY_ENTRY_SECURITY data.
|
||||||
|
// Read the last byte to make sure the data is in the image region.
|
||||||
|
// The DataDirectory array begin with 1, not 0, so here use < to compare not <=.
|
||||||
|
//
|
||||||
|
if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {
|
||||||
|
if (Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size != 0) {
|
||||||
|
//
|
||||||
|
// Check the member data to avoid overflow.
|
||||||
|
//
|
||||||
|
if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <
|
||||||
|
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read section header from file
|
||||||
|
//
|
||||||
|
Size = 1;
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +
|
||||||
|
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - 1,
|
||||||
|
&Size,
|
||||||
|
&BufferData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use PE32+ offset
|
// Use PE32+ offset
|
||||||
//
|
//
|
||||||
@ -166,6 +308,55 @@ PeCoffLoaderGetPeHeader (
|
|||||||
return RETURN_UNSUPPORTED;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check each section field.
|
||||||
|
//
|
||||||
|
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
|
||||||
|
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
|
||||||
|
//
|
||||||
|
// Read section header from file
|
||||||
|
//
|
||||||
|
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
SectionHeaderOffset,
|
||||||
|
&Size,
|
||||||
|
&SectionHeader
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SectionHeader.SizeOfRawData > 0) {
|
||||||
|
//
|
||||||
|
// Check the member data to avoid overflow.
|
||||||
|
//
|
||||||
|
if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base on the ImageRead function to check the section data field.
|
||||||
|
// Read the last byte to make sure the data is in the image region.
|
||||||
|
//
|
||||||
|
Size = 1;
|
||||||
|
Status = ImageContext->ImageRead (
|
||||||
|
ImageContext->Handle,
|
||||||
|
SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData - 1,
|
||||||
|
&Size,
|
||||||
|
&BufferData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check next section.
|
||||||
|
//
|
||||||
|
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +376,9 @@ PeCoffLoaderGetPeHeader (
|
|||||||
The ImageRead and Handle fields of ImageContext structure must be valid prior
|
The ImageRead and Handle fields of ImageContext structure must be valid prior
|
||||||
to invoking this service.
|
to invoking this service.
|
||||||
|
|
||||||
|
Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader,
|
||||||
|
SizeOfHeader, Section Data Region and Security Data Region be in PE image range.
|
||||||
|
|
||||||
@param ImageContext The pointer to the image context structure that describes the PE/COFF
|
@param ImageContext The pointer to the image context structure that describes the PE/COFF
|
||||||
image that needs to be examined by this function.
|
image that needs to be examined by this function.
|
||||||
|
|
||||||
|
@ -54,6 +54,50 @@ HASH_TABLE mHash[] = {
|
|||||||
{ L"SHA512", 64, &mHashOidValue[40], 9, NULL, NULL, NULL, NULL }
|
{ L"SHA512", 64, &mHashOidValue[40], 9, NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reads contents of a PE/COFF image in memory buffer.
|
||||||
|
|
||||||
|
@param FileHandle Pointer to the file handle to read the PE/COFF image.
|
||||||
|
@param FileOffset Offset into the PE/COFF image to begin the read operation.
|
||||||
|
@param ReadSize On input, the size in bytes of the requested read operation.
|
||||||
|
On output, the number of bytes actually read.
|
||||||
|
@param Buffer Output buffer that contains the data read from the PE/COFF image.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ImageRead (
|
||||||
|
IN VOID *FileHandle,
|
||||||
|
IN UINTN FileOffset,
|
||||||
|
IN OUT UINTN *ReadSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN EndPosition;
|
||||||
|
|
||||||
|
if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAX_ADDRESS - FileOffset < *ReadSize) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndPosition = FileOffset + *ReadSize;
|
||||||
|
if (EndPosition > mImageSize) {
|
||||||
|
*ReadSize = (UINT32)(mImageSize - FileOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileOffset >= mImageSize) {
|
||||||
|
*ReadSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the image type.
|
Get the image type.
|
||||||
@ -422,6 +466,10 @@ HashPeImage (
|
|||||||
if (mImageSize > SumOfBytesHashed) {
|
if (mImageSize > SumOfBytesHashed) {
|
||||||
HashBase = mImageBase + SumOfBytesHashed;
|
HashBase = mImageBase + SumOfBytesHashed;
|
||||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if (mImageSize - SumOfBytesHashed < mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Use PE32 offset.
|
// Use PE32 offset.
|
||||||
//
|
//
|
||||||
@ -430,6 +478,10 @@ HashPeImage (
|
|||||||
mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
||||||
SumOfBytesHashed);
|
SumOfBytesHashed);
|
||||||
} else {
|
} else {
|
||||||
|
if (mImageSize - SumOfBytesHashed < mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Use PE32+ offset.
|
// Use PE32+ offset.
|
||||||
//
|
//
|
||||||
@ -1130,6 +1182,7 @@ DxeImageVerificationHandler (
|
|||||||
WIN_CERTIFICATE *WinCertificate;
|
WIN_CERTIFICATE *WinCertificate;
|
||||||
UINT32 Policy;
|
UINT32 Policy;
|
||||||
UINT8 *SecureBootEnable;
|
UINT8 *SecureBootEnable;
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
|
||||||
if (File == NULL) {
|
if (File == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -1216,6 +1269,22 @@ DxeImageVerificationHandler (
|
|||||||
}
|
}
|
||||||
mImageBase = (UINT8 *) FileBuffer;
|
mImageBase = (UINT8 *) FileBuffer;
|
||||||
mImageSize = FileSize;
|
mImageSize = FileSize;
|
||||||
|
|
||||||
|
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||||
|
ImageContext.Handle = (VOID *) FileBuffer;
|
||||||
|
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) ImageRead;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get information about the image being loaded
|
||||||
|
//
|
||||||
|
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// The information can't be got from the invalid PeImage
|
||||||
|
//
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;
|
DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;
|
||||||
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
||||||
//
|
//
|
||||||
|
@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/SecurityManagementLib.h>
|
#include <Library/SecurityManagementLib.h>
|
||||||
|
#include <Library/PeCoffLib.h>
|
||||||
#include <Protocol/FirmwareVolume2.h>
|
#include <Protocol/FirmwareVolume2.h>
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# The library instance provides security service of image verification.
|
# The library instance provides security service of image verification.
|
||||||
# Image verification Library module supports UEFI2.3.1
|
# Image verification Library module supports UEFI2.3.1
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -48,6 +48,7 @@
|
|||||||
DevicePathLib
|
DevicePathLib
|
||||||
BaseCryptLib
|
BaseCryptLib
|
||||||
SecurityManagementLib
|
SecurityManagementLib
|
||||||
|
PeCoffLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiFirmwareVolume2ProtocolGuid
|
gEfiFirmwareVolume2ProtocolGuid
|
||||||
|
@ -36,6 +36,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
BOOLEAN mMeasureGptTableFlag = FALSE;
|
BOOLEAN mMeasureGptTableFlag = FALSE;
|
||||||
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||||
UINTN mMeasureGptCount = 0;
|
UINTN mMeasureGptCount = 0;
|
||||||
|
VOID *mFileBuffer;
|
||||||
|
UINTN mImageSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads contents of a PE/COFF image in memory buffer.
|
Reads contents of a PE/COFF image in memory buffer.
|
||||||
@ -57,7 +59,27 @@ ImageRead (
|
|||||||
OUT VOID *Buffer
|
OUT VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINTN EndPosition;
|
||||||
|
|
||||||
|
if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAX_ADDRESS - FileOffset < *ReadSize) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndPosition = FileOffset + *ReadSize;
|
||||||
|
if (EndPosition > mImageSize) {
|
||||||
|
*ReadSize = (UINT32)(mImageSize - FileOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileOffset >= mImageSize) {
|
||||||
|
*ReadSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
|
CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,6 +517,10 @@ TcgMeasurePeImage (
|
|||||||
if (ImageSize > SumOfBytesHashed) {
|
if (ImageSize > SumOfBytesHashed) {
|
||||||
HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;
|
HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;
|
||||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if (ImageSize - SumOfBytesHashed < Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Use PE32 offset
|
// Use PE32 offset
|
||||||
//
|
//
|
||||||
@ -502,6 +528,10 @@ TcgMeasurePeImage (
|
|||||||
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
||||||
SumOfBytesHashed);
|
SumOfBytesHashed);
|
||||||
} else {
|
} else {
|
||||||
|
if (ImageSize - SumOfBytesHashed < Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Use PE32+ offset
|
// Use PE32+ offset
|
||||||
//
|
//
|
||||||
@ -735,6 +765,9 @@ DxeTpmMeasureBootHandler (
|
|||||||
goto Finish;
|
goto Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mImageSize = FileSize;
|
||||||
|
mFileBuffer = FileBuffer;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Measure PE Image
|
// Measure PE Image
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user