Revision: 14299
http://edk2.svn.sourceforge.net/edk2/?rev=14299&view=rev
Author: vanjeff
Date: 2013-04-19 07:34:41 +0000 (Fri, 19 Apr 2013)
Log Message:
-----------
Sync patches r13470, r13477, r13518, r13545, r13954, r13763 and r14145 from
main trunk.
1. MdeModulePkg PI SMM Core: Unregister handler for SMM Ready To Lock event in
SmmReadyToLockHandler() at first call so that it won't be invoked again.
2. Add more SMRAM range check to 3 SMI handler.
3. Add SMRAM range check to fault tolerant write SMM SMI handler.
4. Add more security check for CommBuffer+CommBufferSize.
5. Add more exact SMM check in SmmFaultTolerantWriteHandler.
6. In order to make sure the image is section alignment, after allocate buffer
for TE image, it will adjust the base address. But it has two potential issues:
One is the start address may not section alignment, second is the buffer is not
bigger enough to do the adjustment. This patch fixes these two issues.
Revision Links:
--------------
http://edk2.svn.sourceforge.net/edk2/?rev=13470&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=13477&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=13518&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=13545&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=13954&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=13763&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=14145&view=rev
Modified Paths:
--------------
branches/UDK2010.SR1/MdeModulePkg/Core/Pei/Image/Image.c
branches/UDK2010.SR1/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
branches/UDK2010.SR1/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
branches/UDK2010.SR1/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
branches/UDK2010.SR1/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
Modified: branches/UDK2010.SR1/MdeModulePkg/Core/Pei/Image/Image.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Core/Pei/Image/Image.c 2013-04-19
06:58:47 UTC (rev 14298)
+++ branches/UDK2010.SR1/MdeModulePkg/Core/Pei/Image/Image.c 2013-04-19
07:34:41 UTC (rev 14299)
@@ -1,7 +1,7 @@
/** @file
Pei Core Load Image Support
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -348,6 +348,7 @@
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
PEI_CORE_INSTANCE *Private;
+ UINT64 AlignImageSize;
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
@@ -377,6 +378,19 @@
// Allocate Memory for the image when memory is ready, boot mode is not S3,
and image is relocatable.
//
if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) &&
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ //
+ // Allocate more buffer to avoid buffer overflow.
+ //
+ if (ImageContext.IsTeImage) {
+ AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *)
Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
+ } else {
+ AlignImageSize = ImageContext.ImageSize;
+ }
+
+ if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
+ AlignImageSize += ImageContext.SectionAlignment;
+ }
+
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private);
if (EFI_ERROR (Status)){
@@ -384,10 +398,10 @@
//
// The PEIM is not assiged valid address, try to allocate page to load
it.
//
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)
AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)
AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));
}
} else {
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages
(EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages
(EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));
}
ASSERT (ImageContext.ImageAddress != 0);
if (ImageContext.ImageAddress == 0) {
@@ -395,6 +409,15 @@
}
//
+ // Adjust the Image Address to make sure it is section alignment.
+ //
+ if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
+ ImageContext.ImageAddress =
+ (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
+ ~((UINTN)ImageContext.SectionAlignment - 1);
+ }
+ //
+ // Fix alignment requirement when Load IPF TeImage into memory.
// Skip the reserved space for the stripped PeHeader when load TeImage
into memory.
//
if (ImageContext.IsTeImage) {
Modified: branches/UDK2010.SR1/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
2013-04-19 06:58:47 UTC (rev 14298)
+++ branches/UDK2010.SR1/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
2013-04-19 07:34:41 UTC (rev 14299)
@@ -76,7 +76,7 @@
//
SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = {
{ SmmDriverDispatchHandler, &gEfiEventDxeDispatchGuid, NULL, TRUE
},
- { SmmReadyToLockHandler, &gEfiDxeSmmReadyToLockProtocolGuid, NULL, FALSE
},
+ { SmmReadyToLockHandler, &gEfiDxeSmmReadyToLockProtocolGuid, NULL, TRUE
},
{ SmmLegacyBootHandler, &gEfiEventLegacyBootGuid, NULL, FALSE
},
{ SmmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE
},
{ NULL, NULL, NULL, FALSE }
Modified:
branches/UDK2010.SR1/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
===================================================================
---
branches/UDK2010.SR1/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
2013-04-19 06:58:47 UTC (rev 14298)
+++
branches/UDK2010.SR1/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
2013-04-19 07:34:41 UTC (rev 14299)
@@ -9,6 +9,13 @@
This library is mainly used by SMM Core to start performance logging to
ensure that
SMM Performance and PerformanceEx Protocol are installed at the very
beginning of SMM phase.
+ Caution: This module requires additional review when modified.
+ This driver will have external input - performance data and communicate
buffer in SMM mode.
+ This external input must be validated carefully to avoid security issue like
+ buffer overflow, integer overflow.
+
+ SmmPerformanceHandlerEx(), SmmPerformanceHandler() will receive untrusted
input and do basic validation.
+
Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD
License
@@ -474,6 +481,9 @@
Communication service SMI Handler entry.
This SMI handler provides services for the performance wrapper driver.
+
+ Caution: This function may receive untrusted input.
+ Communicate buffer and buffer size are external input, so this function
will do basic validation.
@param[in] DispatchHandle The unique handle assigned to this handler by
SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which
was specified when the
@@ -506,8 +516,22 @@
GaugeEntryExArray = NULL;
- ASSERT (CommBuffer != NULL);
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+ if(*CommBufferSize < sizeof (SMM_PERF_COMMUNICATE_EX)) {
+ return EFI_SUCCESS;
+ }
+
+ if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer,
*CommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SMM communcation data buffer is in SMRAM!\n"));
+ return EFI_SUCCESS;
+ }
+
SmmPerfCommData = (SMM_PERF_COMMUNICATE_EX *)CommBuffer;
switch (SmmPerfCommData->Function) {
@@ -528,9 +552,9 @@
//
DataSize = SmmPerfCommData->NumberOfEntries *
sizeof(GAUGE_DATA_ENTRY_EX);
if (IsAddressInSmram
((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeDataEx, DataSize)) {
- DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));
+ DEBUG ((EFI_D_ERROR, "SMM Performance Data buffer is in SMRAM!\n"));
Status = EFI_ACCESS_DENIED;
- break ;
+ break;
}
GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
@@ -543,11 +567,12 @@
break;
default:
- ASSERT (FALSE);
Status = EFI_UNSUPPORTED;
}
+
SmmPerfCommData->ReturnStatus = Status;
+
return EFI_SUCCESS;
}
@@ -556,6 +581,9 @@
This SMI handler provides services for the performance wrapper driver.
+ Caution: This function may receive untrusted input.
+ Communicate buffer and buffer size are external input, so this function will
do basic validation.
+
@param[in] DispatchHandle The unique handle assigned to this handler by
SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which
was specified when the
handler was registered.
@@ -586,11 +614,25 @@
UINTN DataSize;
UINTN Index;
UINTN LogEntryKey;
-
+
GaugeEntryExArray = NULL;
- ASSERT (CommBuffer != NULL);
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+ if(*CommBufferSize < sizeof (SMM_PERF_COMMUNICATE)) {
+ return EFI_SUCCESS;
+ }
+
+ if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer,
*CommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SMM communcation data buffer is in SMRAM!\n"));
+ return EFI_SUCCESS;
+ }
+
SmmPerfCommData = (SMM_PERF_COMMUNICATE *)CommBuffer;
switch (SmmPerfCommData->Function) {
@@ -611,9 +653,9 @@
//
DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY);
if (IsAddressInSmram
((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeData, DataSize)) {
- DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));
+ DEBUG ((EFI_D_ERROR, "SMM Performance Data buffer is in SMRAM!\n"));
Status = EFI_ACCESS_DENIED;
- break ;
+ break;
}
GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
@@ -630,11 +672,12 @@
break;
default:
- ASSERT (FALSE);
Status = EFI_UNSUPPORTED;
}
+
SmmPerfCommData->ReturnStatus = Status;
+
return EFI_SUCCESS;
}
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
===================================================================
---
branches/UDK2010.SR1/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
2013-04-19 06:58:47 UTC (rev 14298)
+++
branches/UDK2010.SR1/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
2013-04-19 07:34:41 UTC (rev 14299)
@@ -4,6 +4,13 @@
This module registers report status code listener to collect performance data
for SMM driver boot records and S3 Suspend Performance Record.
+ Caution: This module requires additional review when modified.
+ This driver will have external input - communicate buffer in SMM mode.
+ This external input must be validated carefully to avoid security issue like
+ buffer overflow, integer overflow.
+
+ FpdtSmiHandler() will receive untrusted input and do basic validation.
+
Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD
License
@@ -203,6 +210,9 @@
This SMI handler provides services for report SMM boot records.
+ Caution: This function may receive untrusted input.
+ Communicate buffer and buffer size are external input, so this function will
do basic validation.
+
@param[in] DispatchHandle The unique handle assigned to this handler by
SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which
was specified when the
handler was registered.
@@ -210,10 +220,14 @@
be conveyed from a non-SMM environment into
an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No
other handlers should still be called.
- @retval EFI_INVALID_PARAMETER The interrupt parameter is not valid.
- @retval EFI_ACCESS_DENIED The interrupt buffer can't be written.
- @retval EFI_UNSUPPORTED The interrupt is not supported.
+ @retval EFI_SUCCESS The interrupt was handled and
quiesced. No other handlers
+ should still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced
but other handlers should
+ still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending
and other handlers should still
+ be called.
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be
quiesced.
+
**/
EFI_STATUS
EFIAPI
@@ -226,15 +240,27 @@
{
EFI_STATUS Status;
SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
+
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ if(*CommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
+ return EFI_SUCCESS;
+ }
- ASSERT (CommBuffer != NULL);
- if (CommBuffer == NULL || *CommBufferSize < sizeof
(SMM_BOOT_RECORD_COMMUNICATE)) {
- return EFI_INVALID_PARAMETER;
+ if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer,
*CommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SMM communication data buffer is in SMRAM!\n"));
+ return EFI_SUCCESS;
}
- Status = EFI_SUCCESS;
SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)CommBuffer;
+ Status = EFI_SUCCESS;
+
switch (SmmCommData->Function) {
case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :
SmmCommData->BootRecordSize = mBootRecordSize;
@@ -245,13 +271,13 @@
Status = EFI_INVALID_PARAMETER;
break;
}
-
+
//
// Sanity check
//
SmmCommData->BootRecordSize = mBootRecordSize;
if (InternalIsAddressInSmram
((EFI_PHYSICAL_ADDRESS)(UINTN)SmmCommData->BootRecordData, mBootRecordSize)) {
- DEBUG ((EFI_D_ERROR, "Smm Data buffer is in SMRAM!\n"));
+ DEBUG ((EFI_D_ERROR, "SMM Data buffer is in SMRAM!\n"));
Status = EFI_ACCESS_DENIED;
break;
}
@@ -264,11 +290,11 @@
break;
default:
- ASSERT (FALSE);
Status = EFI_UNSUPPORTED;
}
SmmCommData->ReturnStatus = Status;
+
return EFI_SUCCESS;
}
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
===================================================================
---
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
2013-04-19 06:58:47 UTC (rev 14298)
+++
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
2013-04-19 07:34:41 UTC (rev 14299)
@@ -40,7 +40,10 @@
If one of them is not satisfied, FtwWrite may fail.
Usually, Spare area only takes one block. That's SpareAreaLength =
BlockSize, NumberOfSpareBlock = 1.
-Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ Caution: This module requires additional review when modified.
+ This driver need to make sure the CommBuffer is not in the SMRAM range.
+
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -56,11 +59,43 @@
#include <Protocol/SmmSwapAddressRange.h>
#include "FaultTolerantWrite.h"
#include "FaultTolerantWriteSmmCommon.h"
+#include <Protocol/SmmAccess2.h>
EFI_EVENT mFvbRegistration = NULL;
EFI_FTW_DEVICE *mFtwDevice = NULL;
+EFI_SMRAM_DESCRIPTOR *mSmramRanges;
+UINTN mSmramRangeCount;
+
/**
+ This function check if the address is in SMRAM.
+
+ @param Buffer the buffer address to be checked.
+ @param Length the buffer length to be checked.
+
+ @retval TRUE this address is in SMRAM.
+ @retval FALSE this address is NOT in SMRAM.
+**/
+BOOLEAN
+InternalIsAddressInSmram (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < mSmramRangeCount; Index ++) {
+ if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer <
mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||
+ ((mSmramRanges[Index].CpuStart >= Buffer) &&
(mSmramRanges[Index].CpuStart < Buffer + Length))) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
Retrive the SMM FVB protocol interface by HANDLE.
@param[in] FvBlockHandle The handle of SMM FVB protocol that provides
services for
@@ -263,6 +298,11 @@
This SMI handler provides services for the fault tolerant write wrapper
driver.
+ Caution: This function requires additional review when modified.
+ This driver need to make sure the CommBuffer is not in the SMRAM range.
+ Also in FTW_FUNCTION_GET_LAST_WRITE case, check
SmmFtwGetLastWriteHeader->Data +
+ SmmFtwGetLastWriteHeader->PrivateDataSize within communication buffer.
+
@param[in] DispatchHandle The unique handle assigned to this handler by
SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which
was specified when the
handler was registered.
@@ -297,14 +337,40 @@
SMM_FTW_GET_LAST_WRITE_HEADER *SmmFtwGetLastWriteHeader;
VOID *PrivateData;
EFI_HANDLE SmmFvbHandle;
+ UINTN InfoSize;
- ASSERT (CommBuffer != NULL);
- ASSERT (CommBufferSize != NULL);
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ if (*CommBufferSize < SMM_FTW_COMMUNICATE_HEADER_SIZE) {
+ return EFI_SUCCESS;
+ }
+
+ if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer,
*CommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SMM communication buffer size is in SMRAM!\n"));
+ return EFI_SUCCESS;
+ }
+
SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *)CommBuffer;
switch (SmmFtwFunctionHeader->Function) {
case FTW_FUNCTION_GET_MAX_BLOCK_SIZE:
- SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *)
SmmFtwFunctionHeader->Data;
+ SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *)
SmmFtwFunctionHeader->Data;
+ InfoSize = sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER);
+
+ //
+ // SMRAM range check already covered before
+ //
+ if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {
+ DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size
limit!\n"));
+ Status = EFI_ACCESS_DENIED;
+ break;
+ }
+
Status = FtwGetMaxBlockSize (
&mFtwDevice->FtwInstance,
&SmmGetMaxBlockSizeHeader->BlockSize
@@ -364,6 +430,17 @@
case FTW_FUNCTION_GET_LAST_WRITE:
SmmFtwGetLastWriteHeader = (SMM_FTW_GET_LAST_WRITE_HEADER *)
SmmFtwFunctionHeader->Data;
+ InfoSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) +
SmmFtwGetLastWriteHeader->PrivateDataSize;
+
+ //
+ // SMRAM range check already covered before
+ //
+ if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {
+ DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size
limit!\n"));
+ Status = EFI_ACCESS_DENIED;
+ break;
+ }
+
Status = FtwGetLastWrite (
&mFtwDevice->FtwInstance,
&SmmFtwGetLastWriteHeader->CallerId,
@@ -377,7 +454,6 @@
break;
default:
- ASSERT (FALSE);
Status = EFI_UNSUPPORTED;
}
@@ -477,6 +553,8 @@
{
EFI_STATUS Status;
EFI_HANDLE FtwHandle;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ UINTN Size;
//
// Allocate private data structure for SMM FTW protocol and do some
initialization
@@ -485,8 +563,30 @@
if (EFI_ERROR(Status)) {
return Status;
}
-
+
//
+ // Get SMRAM information
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID
**)&SmmAccess);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = 0;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ Size,
+ (VOID **)&mSmramRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ //
// Register FvbNotificationEvent () notify function.
//
Status = gSmst->SmmRegisterProtocolNotify (
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
===================================================================
---
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
2013-04-19 06:58:47 UTC (rev 14298)
+++
branches/UDK2010.SR1/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
2013-04-19 07:34:41 UTC (rev 14299)
@@ -4,7 +4,7 @@
# depends on the full functionality SMM FVB protocol that support read,
write/erase
# flash access.
#
-# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD
License
@@ -57,6 +57,7 @@
gEfiSmmSwapAddressRangeProtocolGuid |
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES
gEfiSmmFaultTolerantWriteProtocolGuid ## PRODUCES
+ gEfiSmmAccess2ProtocolGuid ## CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
2013-04-19 06:58:47 UTC (rev 14298)
+++ branches/UDK2010.SR1/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
2013-04-19 07:34:41 UTC (rev 14299)
@@ -70,8 +70,39 @@
}
/**
+ This function check if the address refered by Buffer and Length is valid.
+
+ @param Buffer the buffer address to be checked.
+ @param Length the buffer length to be checked.
+
+ @retval TRUE this address is valid.
+ @retval FALSE this address is NOT valid.
+**/
+BOOLEAN
+IsAddressValid (
+ IN UINTN Buffer,
+ IN UINTN Length
+ )
+{
+ if (Buffer > (MAX_ADDRESS - Length)) {
+ //
+ // Overflow happen
+ //
+ return FALSE;
+ }
+ if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)Buffer, (UINT64)Length)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
Dispatch function for SMM lock box save.
+ Caution: This function may receive untrusted input.
+ Restore buffer and length are external input, so this function will validate
+ it is in SMRAM.
+
@param LockBoxParameterSave parameter of lock box save
**/
VOID
@@ -91,6 +122,15 @@
}
//
+ // Sanity check
+ //
+ if (!IsAddressValid ((UINTN)LockBoxParameterSave->Buffer,
(UINTN)LockBoxParameterSave->Length)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Save address in SMRAM!\n"));
+ LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
+ return ;
+ }
+
+ //
// Save data
//
Status = SaveLockBox (
@@ -137,6 +177,10 @@
/**
Dispatch function for SMM lock box update.
+ Caution: This function may receive untrusted input.
+ Restore buffer and length are external input, so this function will validate
+ it is in SMRAM.
+
@param LockBoxParameterUpdate parameter of lock box update
**/
VOID
@@ -156,6 +200,15 @@
}
//
+ // Sanity check
+ //
+ if (!IsAddressValid ((UINTN)LockBoxParameterUpdate->Buffer,
(UINTN)LockBoxParameterUpdate->Length)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Update address in SMRAM!\n"));
+ LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
+ return ;
+ }
+
+ //
// Update data
//
Status = UpdateLockBox (
@@ -171,6 +224,10 @@
/**
Dispatch function for SMM lock box restore.
+ Caution: This function may receive untrusted input.
+ Restore buffer and length are external input, so this function will validate
+ it is in SMRAM.
+
@param LockBoxParameterRestore parameter of lock box restore
**/
VOID
@@ -183,7 +240,7 @@
//
// Sanity check
//
- if (IsAddressInSmram (LockBoxParameterRestore->Buffer,
LockBoxParameterRestore->Length)) {
+ if (!IsAddressValid ((UINTN)LockBoxParameterRestore->Buffer,
(UINTN)LockBoxParameterRestore->Length)) {
DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM!\n"));
LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
return ;
@@ -229,6 +286,9 @@
/**
Dispatch function for a Software SMI handler.
+ Caution: This function may receive untrusted input.
+ Communicate buffer and buffer size are external input, so this function will
do basic validation.
+
@param DispatchHandle The unique handle assigned to this handler by
SmiHandlerRegister().
@param Context Points to an optional handler context which was
specified when the
handler was registered.
@@ -252,6 +312,18 @@
DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Enter\n"));
+ //
+ // Sanity check
+ //
+ if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size invalid!\n"));
+ return EFI_SUCCESS;
+ }
+ if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer in SMRAM!\n"));
+ return EFI_SUCCESS;
+ }
+
LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*)((UINTN)CommBuffer);
LockBoxParameterHeader->ReturnStatus = (UINT64)-1;
@@ -262,21 +334,42 @@
switch (LockBoxParameterHeader->Command) {
case EFI_SMM_LOCK_BOX_COMMAND_SAVE:
+ if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for SAVE
invalid!\n"));
+ break;
+ }
SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)(UINTN)LockBoxParameterHeader);
break;
case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:
+ if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for UPDATE
invalid!\n"));
+ break;
+ }
SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN)LockBoxParameterHeader);
break;
case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:
+ if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for RESTORE
invalid!\n"));
+ break;
+ }
SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)(UINTN)LockBoxParameterHeader);
break;
case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:
+ if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for SET_ATTRIBUTES
invalid!\n"));
+ break;
+ }
SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)(UINTN)LockBoxParameterHeader);
break;
case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:
+ if (*CommBufferSize <
sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for
RESTORE_ALL_IN_PLACE invalid!\n"));
+ break;
+ }
SmmLockBoxRestoreAllInPlace
((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)(UINTN)LockBoxParameterHeader);
break;
default:
+ DEBUG ((EFI_D_ERROR, "SmmLockBox Command invalid!\n"));
break;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits