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

Reply via email to