Revision: 14323
          http://edk2.svn.sourceforge.net/edk2/?rev=14323&view=rev
Author:   czhang46
Date:     2013-05-02 01:42:39 +0000 (Thu, 02 May 2013)
Log Message:
-----------
Fix memory overflow & VariableSize check issue for SetVariable append write.

Signed-off-by: Chao Zhang <[email protected]>
Reviewed-by  : Fu Siyuan  <[email protected]>
Reviewed-by  : Dong Guo   <[email protected]>

Modified Paths:
--------------
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
    trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c       
2013-04-28 02:31:36 UTC (rev 14322)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c       
2013-05-02 01:42:39 UTC (rev 14323)
@@ -192,7 +192,7 @@
   //
   // Reserved runtime buffer for "Append" operation in virtual mode.
   //
-  mStorageArea  = AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize));
+  mStorageArea  = AllocateRuntimePool (MAX (PcdGet32 (PcdMaxVariableSize), 
PcdGet32 (PcdMaxHardwareErrorVariableSize)));
   if (mStorageArea == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
@@ -1316,20 +1316,24 @@
   will be appended to the original EFI_SIGNATURE_LIST, duplicate 
EFI_SIGNATURE_DATA
   will be ignored.
 
-  @param[in, out]  Data            Pointer to original EFI_SIGNATURE_LIST.
-  @param[in]       DataSize        Size of Data buffer.
-  @param[in]       NewData         Pointer to new EFI_SIGNATURE_LIST to be 
appended.
-  @param[in]       NewDataSize     Size of NewData buffer.
+  @param[in, out]  Data              Pointer to original EFI_SIGNATURE_LIST.
+  @param[in]       DataSize          Size of Data buffer.
+  @param[in]       FreeBufSize       Size of free data buffer 
+  @param[in]       NewData           Pointer to new EFI_SIGNATURE_LIST to be 
appended.
+  @param[in]       NewDataSize       Size of NewData buffer.
+  @param[out]      MergedBufSize     Size of the merged buffer
 
-  @return Size of the merged buffer.
+  @return EFI_BUFFER_TOO_SMALL if input Data buffer overflowed
 
 **/
-UINTN
+EFI_STATUS
 AppendSignatureList (
   IN  OUT VOID            *Data,
   IN  UINTN               DataSize,
+  IN  UINTN               FreeBufSize,
   IN  VOID                *NewData,
-  IN  UINTN               NewDataSize
+  IN  UINTN               NewDataSize,
+  OUT UINTN               *MergedBufSize
   )
 {
   EFI_SIGNATURE_LIST  *CertList;
@@ -1388,15 +1392,25 @@
         // New EFI_SIGNATURE_DATA, append it.
         //
         if (CopiedCount == 0) {
+          if (FreeBufSize < sizeof (EFI_SIGNATURE_LIST) + 
NewCertList->SignatureHeaderSize) {
+            return EFI_BUFFER_TOO_SMALL;
+          }
+
           //
           // Copy EFI_SIGNATURE_LIST header for only once.
           //
+
           CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + 
NewCertList->SignatureHeaderSize);
           Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + 
NewCertList->SignatureHeaderSize;
+          FreeBufSize -= sizeof (EFI_SIGNATURE_LIST) + 
NewCertList->SignatureHeaderSize;
         }
 
+        if (FreeBufSize < NewCertList->SignatureSize) {
+          return EFI_BUFFER_TOO_SMALL;
+        }
         CopyMem (Tail, NewCert, NewCertList->SignatureSize);
         Tail += NewCertList->SignatureSize;
+        FreeBufSize -= NewCertList->SignatureSize;
         CopiedCount++;
       }
 
@@ -1416,7 +1430,8 @@
     NewCertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) NewCertList + 
NewCertList->SignatureListSize);
   }
 
-  return (Tail - (UINT8 *) Data);
+  *MergedBufSize = (Tail - (UINT8 *) Data);
+  return EFI_SUCCESS;
 }
 
 /**

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h       
2013-04-28 02:31:36 UTC (rev 14322)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h       
2013-05-02 01:42:39 UTC (rev 14323)
@@ -2,7 +2,7 @@
   The internal header file includes the common header files, defines
   internal structure and functions used by AuthService module.
 
-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
@@ -249,20 +249,24 @@
   will be appended to the original EFI_SIGNATURE_LIST, duplicate 
EFI_SIGNATURE_DATA
   will be ignored.
 
-  @param[in, out]  Data            Pointer to original EFI_SIGNATURE_LIST.
-  @param[in]       DataSize        Size of Data buffer.
-  @param[in]       NewData         Pointer to new EFI_SIGNATURE_LIST to be 
appended.
-  @param[in]       NewDataSize     Size of NewData buffer.
+  @param[in, out]  Data             Pointer to original EFI_SIGNATURE_LIST.
+  @param[in]       DataSize         Size of Data buffer.
+  @param[in]       FreeBufSize      Size of free data buffer 
+  @param[in]       NewData          Pointer to new EFI_SIGNATURE_LIST to be 
appended.
+  @param[in]       NewDataSize      Size of NewData buffer.
+  @param[out]      MergedBufSize    Size of the merged buffer
 
-  @return Size of the merged buffer.
+  @return EFI_BUFFER_TOO_SMALL if input Data buffer overflowed
 
 **/
-UINTN
+EFI_STATUS
 AppendSignatureList (
   IN  OUT VOID            *Data,
   IN  UINTN               DataSize,
+  IN  UINTN               FreeBufSize,
   IN  VOID                *NewData,
-  IN  UINTN               NewDataSize
+  IN  UINTN               NewDataSize,
+  OUT UINTN               *MergedBufSize
   );
 
 /**

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2013-04-28 02:31:36 UTC (rev 14322)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2013-05-02 01:42:39 UTC (rev 14323)
@@ -1649,7 +1649,7 @@
   EFI_STATUS                          Status;
   VARIABLE_HEADER                     *NextVariable;
   UINTN                               ScratchSize;
-  UINTN                               ScratchDataSize;
+  UINTN                               MaxDataSize;
   UINTN                               NonVolatileVarableStoreSize;
   UINTN                               VarNameOffset;
   UINTN                               VarDataOffset;
@@ -1664,7 +1664,6 @@
   UINTN                               CacheOffset;
   UINTN                               BufSize;
   UINTN                               DataOffset;
-  UINTN                               RevBufSize;
 
   if (mVariableModuleGlobal->FvbInstance == NULL) {
     //
@@ -1713,8 +1712,8 @@
   //
   NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) 
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
   ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 
(PcdMaxHardwareErrorVariableSize));
-  ScratchDataSize = ScratchSize - sizeof (VARIABLE_HEADER) - StrSize 
(VariableName) - GET_PAD_SIZE (StrSize (VariableName));
 
+
   if (Variable->CurrPtr != NULL) {
     //
     // Update/Delete existing variable.
@@ -1827,14 +1826,36 @@
         DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + 
GET_PAD_SIZE (Variable->CurrPtr->NameSize);
         CopyMem (mStorageArea, (UINT8*)((UINTN) Variable->CurrPtr + 
DataOffset), Variable->CurrPtr->DataSize);
 
+        //
+        // Set Max Common Variable Data Size as default MaxDataSize 
+        //
+        MaxDataSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) 
- StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));
+
+
         if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
             ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || 
(StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) ||
             (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp 
(VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {
+
           //
           // For variables with formatted as EFI_SIGNATURE_LIST, the driver 
shall not perform an append of
           // EFI_SIGNATURE_DATA values that are already part of the existing 
variable value.
           //
-          BufSize = AppendSignatureList (mStorageArea, 
Variable->CurrPtr->DataSize, Data, DataSize);
+          Status = AppendSignatureList (
+                     mStorageArea, 
+                     Variable->CurrPtr->DataSize, 
+                     MaxDataSize - Variable->CurrPtr->DataSize,
+                     Data, 
+                     DataSize, 
+                     &BufSize
+                     );
+          if (Status == EFI_BUFFER_TOO_SMALL) {
+            //
+            // Signture List is too long, Failed to Append
+            //
+            Status = EFI_INVALID_PARAMETER;
+            goto Done;
+          }
+
           if (BufSize == Variable->CurrPtr->DataSize) {
             if ((TimeStamp == NULL) || CompareTimeStamp (TimeStamp, 
&Variable->CurrPtr->TimeStamp)) {
               //
@@ -1849,20 +1870,23 @@
         } else {
           //
           // For other Variables, append the new data to the end of previous 
data.
+          // Max Harware error record variable data size is different from 
common variable
           //
+          if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+            MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof 
(VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize 
(VariableName));
+          }
+
+          if (Variable->CurrPtr->DataSize + DataSize > MaxDataSize) {
+            //
+            // Exsiting data + Appended data exceed maximum variable size 
limitation 
+            //
+            Status = EFI_INVALID_PARAMETER;
+            goto Done;
+          }
           CopyMem ((UINT8*)((UINTN) mStorageArea + 
Variable->CurrPtr->DataSize), Data, DataSize);
           BufSize = Variable->CurrPtr->DataSize + DataSize;
         }
 
-        RevBufSize = MIN (PcdGet32 (PcdMaxVariableSize), ScratchDataSize);
-        if (BufSize > RevBufSize) {
-          //
-          // If variable size (previous + current) is bigger than reserved 
buffer in runtime,
-          // return EFI_OUT_OF_RESOURCES.
-          //
-          return EFI_OUT_OF_RESOURCES;
-        }
-
         //
         // Override Data and DataSize which are used for combined data area 
including previous and new data.
         //

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to