]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
Fix memory overflow & VariableSize check issue for SetVariable append write.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / Variable.c
index ebe04b50f5bd2d710e05ace2d67138e33ed18db7..f10d8f7d8358a6344033e8ddfe256a63ded017c6 100644 (file)
@@ -1649,7 +1649,7 @@ UpdateVariable (
   EFI_STATUS                          Status;\r
   VARIABLE_HEADER                     *NextVariable;\r
   UINTN                               ScratchSize;\r
-  UINTN                               ScratchDataSize;\r
+  UINTN                               MaxDataSize;\r
   UINTN                               NonVolatileVarableStoreSize;\r
   UINTN                               VarNameOffset;\r
   UINTN                               VarDataOffset;\r
@@ -1664,7 +1664,6 @@ UpdateVariable (
   UINTN                               CacheOffset;\r
   UINTN                               BufSize;\r
   UINTN                               DataOffset;\r
-  UINTN                               RevBufSize;\r
 \r
   if (mVariableModuleGlobal->FvbInstance == NULL) {\r
     //\r
@@ -1713,7 +1712,7 @@ UpdateVariable (
   //\r
   NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
   ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
-  ScratchDataSize = ScratchSize - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));\r
+\r
 \r
   if (Variable->CurrPtr != NULL) {\r
     //\r
@@ -1827,14 +1826,36 @@ UpdateVariable (
         DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + GET_PAD_SIZE (Variable->CurrPtr->NameSize);\r
         CopyMem (mStorageArea, (UINT8*)((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);\r
 \r
+        //\r
+        // Set Max Common Variable Data Size as default MaxDataSize \r
+        //\r
+        MaxDataSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));\r
+\r
+\r
         if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
             ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) ||\r
             (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {\r
+\r
           //\r
           // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of\r
           // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
           //\r
-          BufSize = AppendSignatureList (mStorageArea, Variable->CurrPtr->DataSize, Data, DataSize);\r
+          Status = AppendSignatureList (\r
+                     mStorageArea, \r
+                     Variable->CurrPtr->DataSize, \r
+                     MaxDataSize - Variable->CurrPtr->DataSize,\r
+                     Data, \r
+                     DataSize, \r
+                     &BufSize\r
+                     );\r
+          if (Status == EFI_BUFFER_TOO_SMALL) {\r
+            //\r
+            // Signture List is too long, Failed to Append\r
+            //\r
+            Status = EFI_INVALID_PARAMETER;\r
+            goto Done;\r
+          }\r
+\r
           if (BufSize == Variable->CurrPtr->DataSize) {\r
             if ((TimeStamp == NULL) || CompareTimeStamp (TimeStamp, &Variable->CurrPtr->TimeStamp)) {\r
               //\r
@@ -1849,20 +1870,23 @@ UpdateVariable (
         } else {\r
           //\r
           // For other Variables, append the new data to the end of previous data.\r
+          // Max Harware error record variable data size is different from common variable\r
           //\r
+          if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
+            MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));\r
+          }\r
+\r
+          if (Variable->CurrPtr->DataSize + DataSize > MaxDataSize) {\r
+            //\r
+            // Exsiting data + Appended data exceed maximum variable size limitation \r
+            //\r
+            Status = EFI_INVALID_PARAMETER;\r
+            goto Done;\r
+          }\r
           CopyMem ((UINT8*)((UINTN) mStorageArea + Variable->CurrPtr->DataSize), Data, DataSize);\r
           BufSize = Variable->CurrPtr->DataSize + DataSize;\r
         }\r
 \r
-        RevBufSize = MIN (PcdGet32 (PcdMaxVariableSize), ScratchDataSize);\r
-        if (BufSize > RevBufSize) {\r
-          //\r
-          // If variable size (previous + current) is bigger than reserved buffer in runtime,\r
-          // return EFI_OUT_OF_RESOURCES.\r
-          //\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-\r
         //\r
         // Override Data and DataSize which are used for combined data area including previous and new data.\r
         //\r