From 28186d45660c92b8d98b8b19b5f8e6ff71ea5fba Mon Sep 17 00:00:00 2001 From: ydong10 Date: Tue, 24 Apr 2012 03:00:32 +0000 Subject: Validate some fields in PE image to make sure not access violation for later code. Signed-off-by: Eric Dong Reviewed-by: Liming Gao git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13211 6f19259b-4bc3-4df7-8a09-765794883524 --- .../DxeImageVerificationLib.c | 69 ++++++++++++++++++++++ .../DxeImageVerificationLib.h | 1 + .../DxeImageVerificationLib.inf | 3 +- 3 files changed, 72 insertions(+), 1 deletion(-) (limited to 'SecurityPkg/Library/DxeImageVerificationLib') diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index 19852dd483..6e3e9eea95 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -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) { // diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h index 881e4e5c35..55371e90bf 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h @@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include #include diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf index 1dda6774fa..860d64ba83 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf @@ -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.
+# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
# 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 -- cgit v1.2.3