Add more check for the bmp file to avoid access violation.

Signed-off-by: Dong Eric <eric.dong@intel.com>
Reviewed-by: Gao Liming <liming.gao@intel.com>
Reviewed-by: Zhang Chao <chao.b.zhang@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13185 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ydong10
2012-04-11 07:56:50 +00:00
parent ba46ab9479
commit a46c36572d
4 changed files with 218 additions and 6 deletions

View File

@ -1,6 +1,6 @@
/*++ /*++
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -162,22 +162,78 @@ Returns:
UINTN Height; UINTN Height;
UINTN Width; UINTN Width;
UINTN ImageIndex; UINTN ImageIndex;
UINTN DataSizePerLine;
BOOLEAN IsAllocated; BOOLEAN IsAllocated;
UINT32 ColorMapNum;
if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
return EFI_INVALID_PARAMETER;
}
BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
//
// Doesn't support compress.
//
if (BmpHeader->CompressionType != 0) { if (BmpHeader->CompressionType != 0) {
return EFI_UNSUPPORTED; 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. // Calculate Color Map offset in the image.
// //
Image = BmpImage; Image = BmpImage;
BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); 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 // Calculate graphics image data address in the image

View File

@ -1,6 +1,6 @@
/*++ /*++
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -163,22 +163,78 @@ Returns:
UINTN Height; UINTN Height;
UINTN Width; UINTN Width;
UINTN ImageIndex; UINTN ImageIndex;
UINTN DataSizePerLine;
BOOLEAN IsAllocated; BOOLEAN IsAllocated;
UINT32 ColorMapNum;
if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
return EFI_INVALID_PARAMETER;
}
BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
//
// Doesn't support compress.
//
if (BmpHeader->CompressionType != 0) { if (BmpHeader->CompressionType != 0) {
return EFI_UNSUPPORTED; 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. // Calculate Color Map offset in the image.
// //
Image = BmpImage; Image = BmpImage;
BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); 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 // Calculate graphics image data address in the image

View File

@ -601,7 +601,13 @@ ConvertBmpToGopBlt (
UINTN Height; UINTN Height;
UINTN Width; UINTN Width;
UINTN ImageIndex; UINTN ImageIndex;
UINT32 DataSizePerLine;
BOOLEAN IsAllocated; BOOLEAN IsAllocated;
UINT32 ColorMapNum;
if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
return EFI_INVALID_PARAMETER;
}
BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
@ -616,11 +622,57 @@ ConvertBmpToGopBlt (
return EFI_UNSUPPORTED; 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. // Calculate Color Map offset in the image.
// //
Image = BmpImage; Image = BmpImage;
BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); 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 // Calculate graphics image data address in the image
@ -798,6 +850,7 @@ EnableQuietBoot (
UINTN NewDestY; UINTN NewDestY;
UINTN NewHeight; UINTN NewHeight;
UINTN NewWidth; UINTN NewWidth;
UINT64 BufferSize;
UgaDraw = NULL; UgaDraw = NULL;
// //
@ -1082,7 +1135,22 @@ Done:
FreePool (Blt); 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) { if (LogoBlt == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }

View File

@ -157,6 +157,8 @@ SetBootLogo (
IN UINTN Height IN UINTN Height
) )
{ {
UINT64 BufferSize;
if (BltBuffer == NULL) { if (BltBuffer == NULL) {
mIsLogoValid = FALSE; mIsLogoValid = FALSE;
mAcpiBgrtStatusChanged = TRUE; mAcpiBgrtStatusChanged = TRUE;
@ -173,8 +175,23 @@ SetBootLogo (
mLogoBltBuffer = NULL; 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 ( mLogoBltBuffer = AllocateCopyPool (
Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), (UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),
BltBuffer BltBuffer
); );
if (mLogoBltBuffer == NULL) { if (mLogoBltBuffer == NULL) {
@ -330,6 +347,21 @@ InstallBootGraphicsResourceTable (
// Allocate memory for BMP file. // Allocate memory for BMP file.
// //
PaddingSize = mLogoWidth & 0x3; 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); BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER);
ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize); ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize);
if (ImageBuffer == NULL) { if (ImageBuffer == NULL) {