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:
@@ -54,6 +54,50 @@ HASH_TABLE mHash[] = {
|
||||
{ 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.
|
||||
@@ -422,6 +466,10 @@ HashPeImage (
|
||||
if (mImageSize > SumOfBytesHashed) {
|
||||
HashBase = mImageBase + SumOfBytesHashed;
|
||||
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.
|
||||
//
|
||||
@@ -430,6 +478,10 @@ HashPeImage (
|
||||
mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
||||
SumOfBytesHashed);
|
||||
} else {
|
||||
if (mImageSize - SumOfBytesHashed < mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||
Status = FALSE;
|
||||
goto Done;
|
||||
}
|
||||
//
|
||||
// Use PE32+ offset.
|
||||
//
|
||||
@@ -1130,6 +1182,7 @@ DxeImageVerificationHandler (
|
||||
WIN_CERTIFICATE *WinCertificate;
|
||||
UINT32 Policy;
|
||||
UINT8 *SecureBootEnable;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
if (File == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -1216,6 +1269,22 @@ DxeImageVerificationHandler (
|
||||
}
|
||||
mImageBase = (UINT8 *) FileBuffer;
|
||||
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;
|
||||
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/DevicePathLib.h>
|
||||
#include <Library/SecurityManagementLib.h>
|
||||
#include <Library/PeCoffLib.h>
|
||||
#include <Protocol/FirmwareVolume2.h>
|
||||
#include <Protocol/DevicePath.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# The library instance provides security service of image verification.
|
||||
# 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
|
||||
# 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
|
||||
@@ -48,6 +48,7 @@
|
||||
DevicePathLib
|
||||
BaseCryptLib
|
||||
SecurityManagementLib
|
||||
PeCoffLib
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolume2ProtocolGuid
|
||||
|
@@ -36,6 +36,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
BOOLEAN mMeasureGptTableFlag = FALSE;
|
||||
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
UINTN mMeasureGptCount = 0;
|
||||
VOID *mFileBuffer;
|
||||
UINTN mImageSize;
|
||||
|
||||
/**
|
||||
Reads contents of a PE/COFF image in memory buffer.
|
||||
@@ -57,7 +59,27 @@ ImageRead (
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -495,6 +517,10 @@ TcgMeasurePeImage (
|
||||
if (ImageSize > SumOfBytesHashed) {
|
||||
HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;
|
||||
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
|
||||
//
|
||||
@@ -502,6 +528,10 @@ TcgMeasurePeImage (
|
||||
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
|
||||
SumOfBytesHashed);
|
||||
} else {
|
||||
if (ImageSize - SumOfBytesHashed < Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto Finish;
|
||||
}
|
||||
//
|
||||
// Use PE32+ offset
|
||||
//
|
||||
@@ -735,6 +765,9 @@ DxeTpmMeasureBootHandler (
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
mImageSize = FileSize;
|
||||
mFileBuffer = FileBuffer;
|
||||
|
||||
//
|
||||
// Measure PE Image
|
||||
//
|
||||
|
Reference in New Issue
Block a user