From 5e9dfc67821b75ab606d8565f0bc1133bbc2a92c Mon Sep 17 00:00:00 2001 From: Liming Gao Date: Wed, 13 Jul 2016 20:28:15 +0800 Subject: [PATCH] SecurityPkg SecureBootConfigDxe: Add check for the external PE/COFF image. Use BasePeCoffLib PeCoffLoaderGetImageInfo() to check the PE/COFF image. In V2, add specific ImageRead() to make sure the PE/COFF image content read is within the image buffer. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Liming Gao Reviewed-by: Jiewen Yao Reviewed-by: Chao Zhang --- SecurityPkg/SecurityPkg.dsc | 2 + .../SecureBootConfigDxe.inf | 1 + .../SecureBootConfigImpl.c | 70 +++++++++++++++++++ .../SecureBootConfigImpl.h | 1 + 4 files changed, 74 insertions(+) diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 1960b52d72..21cac786b4 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -34,6 +34,8 @@ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf index 6b143f5e01..fa7c39d6e5 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf @@ -58,6 +58,7 @@ PlatformSecureLib DevicePathLib FileExplorerLib + PeCoffLib [Guids] ## SOMETIMES_CONSUMES ## Variable:L"CustomMode" diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index 3f80441602..0d9618597b 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -1609,6 +1609,54 @@ ON_EXIT: return IsFound; } +/** + Reads contents of a PE/COFF image in memory buffer. + + Caution: This function may receive untrusted input. + PE/COFF image is external input, so this function will make sure the PE/COFF image content + read is within the image 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 +SecureBootConfigImageRead ( + 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; +} + /** Load PE/COFF image information into internal buffer and check its validity. @@ -1625,9 +1673,28 @@ LoadPeImage ( EFI_IMAGE_DOS_HEADER *DosHdr; EFI_IMAGE_NT_HEADERS32 *NtHeader32; EFI_IMAGE_NT_HEADERS64 *NtHeader64; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; NtHeader32 = NULL; NtHeader64 = NULL; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) mImageBase; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecureBootConfigImageRead; + + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + // + // The information can't be got from the invalid PeImage + // + DEBUG ((DEBUG_INFO, "SecureBootConfigDxe: PeImage invalid. \n")); + return Status; + } + // // Read the Dos header // @@ -1689,6 +1756,9 @@ LoadPeImage ( Calculate hash of Pe/Coff image based on the authenticode image hashing in PE/COFF Specification 8.0 Appendix A + Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + the function LoadPeImage (). + @param[in] HashAlg Hash algorithm type. @retval TRUE Successfully hash image. diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h index 0a09ab4966..5055a9e9c3 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h @@ -40,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include -- 2.39.2