From a46c36572d080dbd6c674e156b5ec486517c67c1 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Wed, 11 Apr 2012 07:56:50 +0000 Subject: [PATCH] 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/Dxe/Graphics/Graphics.c | 58 ++++++++++++++- .../Library/Dxe/GraphicsLite/Graphics.c | 58 ++++++++++++++- .../Library/GenericBdsLib/BdsConsole.c | 74 ++++++++++++++++++- .../BootGraphicsResourceTableDxe.c | 34 ++++++++- 4 files changed, 218 insertions(+), 6 deletions(-) diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c index 6a8183e131..9549217388 100644 --- a/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c +++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Graphics.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 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 @@ -162,22 +162,78 @@ Returns: UINTN Height; UINTN Width; UINTN ImageIndex; + UINTN DataSizePerLine; BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + return EFI_INVALID_PARAMETER; + } BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { return EFI_UNSUPPORTED; } + // + // Doesn't support compress. + // if (BmpHeader->CompressionType != 0) { return EFI_UNSUPPORTED; } + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - ((UINTN) &(((BMP_IMAGE_HEADER *)0)->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 diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Graphics.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Graphics.c index cfdccc5455..5123aacf45 100644 --- a/EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Graphics.c +++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/GraphicsLite/Graphics.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 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 @@ -163,22 +163,78 @@ Returns: UINTN Height; UINTN Width; UINTN ImageIndex; + UINTN DataSizePerLine; BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + return EFI_INVALID_PARAMETER; + } BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { return EFI_UNSUPPORTED; } + // + // Doesn't support compress. + // if (BmpHeader->CompressionType != 0) { return EFI_UNSUPPORTED; } + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - ((UINTN) &(((BMP_IMAGE_HEADER *)0)->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 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; } diff --git a/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c b/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c index d365985389..df770fc647 100644 --- a/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c +++ b/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c @@ -157,6 +157,8 @@ SetBootLogo ( IN UINTN Height ) { + UINT64 BufferSize; + if (BltBuffer == NULL) { mIsLogoValid = FALSE; mAcpiBgrtStatusChanged = TRUE; @@ -172,9 +174,24 @@ SetBootLogo ( FreePool (mLogoBltBuffer); mLogoBltBuffer = NULL; } + + // + // Ensure the Height * Width doesn't overflow + // + if (Height > DivU64x64Remainder ((UINTN) ~0, Width, NULL)) { + return EFI_UNSUPPORTED; + } + BufferSize = MultU64x64 (Width, Height); + + // + // 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; + } mLogoBltBuffer = AllocateCopyPool ( - Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), + (UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), BltBuffer ); if (mLogoBltBuffer == NULL) { @@ -330,6 +347,21 @@ InstallBootGraphicsResourceTable ( // Allocate memory for BMP file. // PaddingSize = mLogoWidth & 0x3; + + // + // First check mLogoWidth * 3 + PaddingSize doesn't overflow + // + if (mLogoWidth > (((UINT32) ~0) - PaddingSize) / 3 ) { + return EFI_UNSUPPORTED; + } + + // + // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER) doesn't overflow + // + if (mLogoHeight > (((UINT32) ~0) - sizeof (BMP_IMAGE_HEADER)) / (mLogoWidth * 3 + PaddingSize)) { + return EFI_UNSUPPORTED; + } + BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER); ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize); if (ImageBuffer == NULL) { -- 2.39.2