Revision: 14287
          http://edk2.svn.sourceforge.net/edk2/?rev=14287&view=rev
Author:   vanjeff
Date:     2013-04-18 05:37:12 +0000 (Thu, 18 Apr 2013)
Log Message:
-----------
Sync patches r14252, r14258, r14283 and r14284 from main trunk.
1. If DataSize or VariableNameSize is near MAX_ADDRESS, this can cause the 
computed PayLoadSize to overflow to a small value and pass the check in 
InitCommunicateBuffer(). To protect against this vulnerability, check DataSize 
and VariableNameSize to make sure PayloadSize doesn't overflow.
2. Update SMM variable DXE driver GetNextVariable interface to comply with UEFI 
spec VariableNameSize is the returned buffer size. GetNextVariable should 
behavior correct if it is bigger than SMM communication buffer or less than 
string size of VariableName. 
3. Update code not to block application/driver load when event log is full.
4. MdeModulePkg/AtaBus: AtaBusDxe module would ignore ATA Pass Thru Protocol 
instances that do not have the LOGICAL attribute set.

Revision Links:
--------------
    http://edk2.svn.sourceforge.net/edk2/?rev=14252&view=rev
    http://edk2.svn.sourceforge.net/edk2/?rev=14258&view=rev
    http://edk2.svn.sourceforge.net/edk2/?rev=14283&view=rev
    http://edk2.svn.sourceforge.net/edk2/?rev=14284&view=rev

Modified Paths:
--------------
    branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
    branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
    branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
    
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
    
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
    branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
    
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c

Modified: branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c        
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c        
2013-04-18 05:37:12 UTC (rev 14287)
@@ -4,7 +4,7 @@
   This file implements protocol interfaces: Driver Binding protocol,
   Block IO protocol and DiskInfo protocol.
 
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 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
@@ -630,11 +630,36 @@
   }
 
   //
+  // Test to see if this ATA Pass Thru Protocol is for a LOGICAL channel
+  //
+  if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL) 
== 0) {
+    //
+    // Close the I/O Abstraction(s) used to perform the supported test
+    //
+    gBS->CloseProtocol (
+          Controller,
+          &gEfiAtaPassThruProtocolGuid,
+          This->DriverBindingHandle,
+          Controller
+          );
+    return EFI_UNSUPPORTED;
+  }
+
+  //
   // Test RemainingDevicePath is valid or not.
   //
   if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) 
{
     Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, 
&PortMultiplierPort);
     if (EFI_ERROR (Status)) {
+      //
+      // Close the I/O Abstraction(s) used to perform the supported test
+      //
+      gBS->CloseProtocol (
+            Controller,
+            &gEfiAtaPassThruProtocolGuid,
+            This->DriverBindingHandle,
+            Controller
+            );
       return Status;
     }
   }

Modified: branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h  
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h  
2013-04-18 05:37:12 UTC (rev 14287)
@@ -1,7 +1,7 @@
 /** @file
   The file defined some common structures used for communicating between SMM 
variable module and SMM variable wrapper module.
 
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 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 that accompanies this 
distribution.  
 The full text of the license may be found at
@@ -87,7 +87,7 @@
 ///
 typedef struct {
   EFI_GUID    Guid;
-  UINTN       NameSize;
+  UINTN       NameSize;     // Return name buffer size
   CHAR16      Name[1];
 } SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME;
 

Modified: 
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c  
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c  
2013-04-18 05:37:12 UTC (rev 14287)
@@ -2580,6 +2580,11 @@
   ASSERT(VariableStoreHeader->Size == VariableStoreLength);
     
   //
+  // The max variable or hardware error variable size should be < variable 
store size.
+  //
+  ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 
(PcdMaxHardwareErrorVariableSize)) < VariableStoreLength);
+
+  //
   // Parse non-volatile variable data and get last variable offset.
   //
   NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER 
*)(UINTN)VariableStoreBase);

Modified: 
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
--- 
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
     2013-04-18 05:32:02 UTC (rev 14286)
+++ 
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
     2013-04-18 05:37:12 UTC (rev 14287)
@@ -198,6 +198,16 @@
     return EFI_INVALID_PARAMETER;
   }
 
+  if (*DataSize >= mVariableBufferSize) {
+    //
+    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the 
computed PayLoadSize to
+    // overflow to a small value and pass the check in InitCommunicateBuffer().
+    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if 
DataSize is >= mVariableBufferSize.
+    // And there will be further check to ensure the total size is also not > 
mVariableBufferSize.
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
 
   //
@@ -270,27 +280,58 @@
   EFI_STATUS                                      Status;
   UINTN                                           PayloadSize;
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;
+  UINTN                                           SmmCommBufPayloadSize;
 
   if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
     return EFI_INVALID_PARAMETER;
   }
 
+  //
+  // SMM Communication Buffer max payload size
+  //
+  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + 
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);
+
+  //
+  // If input string exceeds SMM payload limit. Return failure
+  //
+  if (StrSize (VariableName) > SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
 
   //
   // Init the communicate buffer. The buffer data size is:
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 
PayloadSize.
   //
-  PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, 
Name) + *VariableNameSize; 
+  if (*VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+    //
+    // If output buffer exceed SMM payload limit. Trim output buffer to SMM 
payload size
+    //
+    *VariableNameSize = SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);
+  }
+  //
+  // Payload should be Guid + NameSize + MAX of Input & Output buffer
+  //
+  PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, 
Name) + MAX (*VariableNameSize, StrSize (VariableName));
+
+
   Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, 
PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
   if (EFI_ERROR (Status)) {
     goto Done;
   }
   ASSERT (SmmGetNextVariableName != NULL);
 
+  //
+  // SMM comm buffer->NameSize is buffer size for return string
+  //
   SmmGetNextVariableName->NameSize = *VariableNameSize;
+
   CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid);
-  CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize);
+  //
+  // Copy whole string
+  //
+  CopyMem (SmmGetNextVariableName->Name, VariableName, StrSize (VariableName));
 
   //
   // Send data to SMM
@@ -355,6 +396,16 @@
     return EFI_INVALID_PARAMETER;
   }
 
+  if (DataSize >= mVariableBufferSize) {
+    //
+    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the 
computed PayLoadSize to
+    // overflow to a small value and pass the check in InitCommunicateBuffer().
+    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if 
DataSize is >= mVariableBufferSize.
+    // And there will be further check to ensure the total size is also not > 
mVariableBufferSize.
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
  
   //

Modified: 
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
===================================================================
--- 
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
        2013-04-18 05:32:02 UTC (rev 14286)
+++ 
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
        2013-04-18 05:37:12 UTC (rev 14287)
@@ -15,7 +15,7 @@
   TcgMeasureGptTable() function will receive untrusted GPT partition table, 
and parse
   partition data carefully.
 
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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 
@@ -664,6 +664,14 @@
              &EventNumber,
              &EventLogLastEntry
              );
+  if (Status == EFI_OUT_OF_RESOURCES) {
+    //
+    // Out of resource here means the image is hashed and its result is 
extended to PCR.
+    // But the event log cann't be saved since log area is full.
+    // Just return EFI_SUCCESS in order not to block the image load.
+    //
+    Status = EFI_SUCCESS;
+  }
 
 Finish:
   FreePool (TcgEvent);

Modified: 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
--- 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c    
    2013-04-18 05:32:02 UTC (rev 14286)
+++ 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c    
    2013-04-18 05:37:12 UTC (rev 14287)
@@ -2810,6 +2810,11 @@
   ASSERT(VariableStoreHeader->Size == VariableStoreLength);
 
   //
+  // The max variable or hardware error variable size should be < variable 
store size.
+  //
+  ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 
(PcdMaxHardwareErrorVariableSize)) < VariableStoreLength);
+
+  //
   // Parse non-volatile variable data and get last variable offset.
   //
   NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER 
*)(UINTN)VariableStoreBase);

Modified: 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
--- 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
   2013-04-18 05:32:02 UTC (rev 14286)
+++ 
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
   2013-04-18 05:37:12 UTC (rev 14287)
@@ -214,6 +214,16 @@
     return EFI_INVALID_PARAMETER;
   }
 
+  if (*DataSize >= mVariableBufferSize) {
+    //
+    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the 
computed PayLoadSize to
+    // overflow to a small value and pass the check in InitCommunicateBuffer().
+    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if 
DataSize is >= mVariableBufferSize.
+    // And there will be further check to ensure the total size is also not > 
mVariableBufferSize.
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
 
   //
@@ -286,27 +296,57 @@
   EFI_STATUS                                      Status;
   UINTN                                           PayloadSize;
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;
+  UINTN                                           SmmCommBufPayloadSize;
 
   if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
     return EFI_INVALID_PARAMETER;
   }
 
+  //
+  // SMM Communication Buffer max payload size
+  //
+  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + 
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);
+
+  //
+  // If input string exceeds SMM payload limit. Return failure
+  //
+  if (StrSize (VariableName) > SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
 
   //
   // Init the communicate buffer. The buffer data size is:
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 
PayloadSize.
   //
-  PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, 
Name) + *VariableNameSize; 
+  if (*VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+    //
+    // If output buffer exceed SMM payload limit. Trim output buffer to SMM 
payload size
+    //
+    *VariableNameSize = SmmCommBufPayloadSize - OFFSET_OF 
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);
+  }
+  //
+  // Payload should be Guid + NameSize + MAX of Input & Output buffer
+  //
+  PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, 
Name) + MAX (*VariableNameSize, StrSize (VariableName));
+
   Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, 
PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
   if (EFI_ERROR (Status)) {
     goto Done;
   }
   ASSERT (SmmGetNextVariableName != NULL);
 
+  //
+  // SMM comm buffer->NameSize is buffer size for return string
+  //
   SmmGetNextVariableName->NameSize = *VariableNameSize;
+
   CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid);
-  CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize);
+  //
+  // Copy whole string
+  //
+  CopyMem (SmmGetNextVariableName->Name, VariableName, StrSize (VariableName));
 
   //
   // Send data to SMM
@@ -374,6 +414,16 @@
     return EFI_INVALID_PARAMETER;
   }
 
+  if (DataSize >= mVariableBufferSize) {
+    //
+    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the 
computed PayLoadSize to
+    // overflow to a small value and pass the check in InitCommunicateBuffer().
+    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if 
DataSize is >= mVariableBufferSize.
+    // And there will be further check to ensure the total size is also not > 
mVariableBufferSize.
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
   AcquireLockOnlyAtBootTime(&mVariableServicesLock);
  
   //

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