From a46c36572d080dbd6c674e156b5ec486517c67c1 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Wed, 11 Apr 2012 07:56:50 +0000 Subject: Add more check for the bmp file to avoid access violation. Signed-off-by: Dong Eric Reviewed-by: Gao Liming Reviewed-by: Zhang Chao git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13185 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/GenericBdsLib/BdsConsole.c | 74 +++++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'IntelFrameworkModulePkg/Library') diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c index 4fca0f3b12..1ded13637d 100644 --- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c +++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c @@ -601,7 +601,13 @@ ConvertBmpToGopBlt ( UINTN Height; UINTN Width; UINTN ImageIndex; + UINT32 DataSizePerLine; BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + return EFI_INVALID_PARAMETER; + } BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; @@ -616,11 +622,57 @@ ConvertBmpToGopBlt ( return EFI_UNSUPPORTED; } + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) { + return EFI_UNSUPPORTED; + } + + // + // The data size in each line must be 4 byte alignment. + // + DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3); + BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight); + if (BltBufferSize > (UINT32) ~0) { + return EFI_INVALID_PARAMETER; + } + + if ((BmpHeader->Size != BmpImageSize) || + (BmpHeader->Size < BmpHeader->ImageOffset) || + (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) { + return EFI_INVALID_PARAMETER; + } + // // Calculate Color Map offset in the image. // Image = BmpImage; BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { + return EFI_INVALID_PARAMETER; + } + + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { + switch (BmpHeader->BitPerPixel) { + case 1: + ColorMapNum = 2; + break; + case 4: + ColorMapNum = 16; + break; + case 8: + ColorMapNum = 256; + break; + default: + ColorMapNum = 0; + break; + } + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) != sizeof (BMP_COLOR_MAP) * ColorMapNum) { + return EFI_INVALID_PARAMETER; + } + } // // Calculate graphics image data address in the image @@ -636,8 +688,8 @@ ConvertBmpToGopBlt ( // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow // if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { - return EFI_UNSUPPORTED; - } + return EFI_UNSUPPORTED; + } BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); IsAllocated = FALSE; @@ -798,6 +850,7 @@ EnableQuietBoot ( UINTN NewDestY; UINTN NewHeight; UINTN NewWidth; + UINT64 BufferSize; UgaDraw = NULL; // @@ -1082,7 +1135,22 @@ Done: FreePool (Blt); } - LogoBlt = AllocateZeroPool (LogoWidth * LogoHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + // + // Ensure the LogoHeight * LogoWidth doesn't overflow + // + if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { + return EFI_UNSUPPORTED; + } + BufferSize = MultU64x64 (LogoWidth, LogoHeight); + + // + // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow + // + if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + return EFI_UNSUPPORTED; + } + + LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); if (LogoBlt == NULL) { return EFI_OUT_OF_RESOURCES; } -- cgit v1.2.3