]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Fix TOCTOU issue in VariableSmm, FtwSmm, FpdtSmm, SmmCorePerformance SMM handler...
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 7 May 2013 05:38:32 +0000 (05:38 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 7 May 2013 05:38:32 +0000 (05:38 +0000)
2. Add check to ensure CommBufferPayloadSize not exceed mVariableBufferPayloadSize or is enough to hold function structure in VariableSmm and FtwSmm.
3. Align FtwGetLastWrite() in FaultTolerantWriteSmmDxe.c to FtwGetLastWrite() in FaultTolerantWrite.c.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14325 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmDxe.c
MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c

index 5755f2affc6bd2e0431823bd9b2d9f1c8371d853..2bfd62a2b9e58d4bbe4217d62f128e7f3fce92c9 100644 (file)
@@ -540,6 +540,9 @@ SmmPerformanceHandlerEx (
   SMM_PERF_COMMUNICATE_EX   *SmmPerfCommData;\r
   GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
   UINTN                     DataSize;\r
   SMM_PERF_COMMUNICATE_EX   *SmmPerfCommData;\r
   GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
   UINTN                     DataSize;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeDataEx;\r
+  UINTN                     NumberOfEntries;\r
+  UINTN                     LogEntryKey;\r
 \r
   GaugeEntryExArray = NULL;\r
 \r
 \r
   GaugeEntryExArray = NULL;\r
 \r
@@ -555,7 +558,7 @@ SmmPerformanceHandlerEx (
   }\r
 \r
   if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
   }\r
 \r
   if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communcation data buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "SmmPerformanceHandlerEx: SMM communcation data buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
   \r
     return EFI_SUCCESS;\r
   }\r
   \r
@@ -568,8 +571,11 @@ SmmPerformanceHandlerEx (
        break;\r
 \r
     case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
        break;\r
 \r
     case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
-       if ( SmmPerfCommData->GaugeDataEx == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
-         (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
+      GaugeDataEx = SmmPerfCommData->GaugeDataEx;\r
+      NumberOfEntries = SmmPerfCommData->NumberOfEntries;\r
+      LogEntryKey = SmmPerfCommData->LogEntryKey;\r
+       if (GaugeDataEx == NULL || NumberOfEntries == 0 || LogEntryKey > mGaugeData->NumberOfEntries ||\r
+           NumberOfEntries > mGaugeData->NumberOfEntries || (LogEntryKey + NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        }\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        }\r
@@ -577,17 +583,17 @@ SmmPerformanceHandlerEx (
        //\r
        // Sanity check\r
        //\r
        //\r
        // Sanity check\r
        //\r
-       DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY_EX);\r
-       if (!IsAddressValid ((UINTN)SmmPerfCommData->GaugeDataEx, DataSize)) {\r
-         DEBUG ((EFI_D_ERROR, "SMM Performance Data buffer in SMRAM or overflow!\n"));\r
+       DataSize = NumberOfEntries * sizeof(GAUGE_DATA_ENTRY_EX);\r
+       if (!IsAddressValid ((UINTN)GaugeDataEx, DataSize)) {\r
+         DEBUG ((EFI_D_ERROR, "SmmPerformanceHandlerEx: SMM Performance Data buffer in SMRAM or overflow!\n"));\r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
        CopyMem(\r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
        CopyMem(\r
-         (UINT8 *) (SmmPerfCommData->GaugeDataEx),\r
-         (UINT8 *) &GaugeEntryExArray[SmmPerfCommData->LogEntryKey],\r
+         (UINT8 *) GaugeDataEx,\r
+         (UINT8 *) &GaugeEntryExArray[LogEntryKey],\r
          DataSize\r
          );\r
        Status = EFI_SUCCESS;\r
          DataSize\r
          );\r
        Status = EFI_SUCCESS;\r
@@ -640,6 +646,8 @@ SmmPerformanceHandler (
   GAUGE_DATA_ENTRY_EX   *GaugeEntryExArray;\r
   UINTN                 DataSize;\r
   UINTN                 Index;\r
   GAUGE_DATA_ENTRY_EX   *GaugeEntryExArray;\r
   UINTN                 DataSize;\r
   UINTN                 Index;\r
+  GAUGE_DATA_ENTRY      *GaugeData;\r
+  UINTN                 NumberOfEntries;\r
   UINTN                 LogEntryKey;\r
   \r
   GaugeEntryExArray = NULL;\r
   UINTN                 LogEntryKey;\r
   \r
   GaugeEntryExArray = NULL;\r
@@ -656,7 +664,7 @@ SmmPerformanceHandler (
   }\r
 \r
   if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
   }\r
 \r
   if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communcation data buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "SmmPerformanceHandler: SMM communcation data buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -669,8 +677,11 @@ SmmPerformanceHandler (
        break;\r
 \r
     case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
        break;\r
 \r
     case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
-       if ( SmmPerfCommData->GaugeData == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
-         (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
+       GaugeData = SmmPerfCommData->GaugeData;\r
+       NumberOfEntries = SmmPerfCommData->NumberOfEntries;\r
+       LogEntryKey = SmmPerfCommData->LogEntryKey;\r
+       if (GaugeData == NULL || NumberOfEntries == 0 || LogEntryKey > mGaugeData->NumberOfEntries ||\r
+           NumberOfEntries > mGaugeData->NumberOfEntries || (LogEntryKey + NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        }\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        }\r
@@ -678,19 +689,18 @@ SmmPerformanceHandler (
        //\r
        // Sanity check\r
        //\r
        //\r
        // Sanity check\r
        //\r
-       DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
-       if (!IsAddressValid ((UINTN)SmmPerfCommData->GaugeData, DataSize)) {\r
-         DEBUG ((EFI_D_ERROR, "SMM Performance Data buffer in SMRAM or overflow!\n"));\r
+       DataSize = NumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
+       if (!IsAddressValid ((UINTN)GaugeData, DataSize)) {\r
+         DEBUG ((EFI_D_ERROR, "SmmPerformanceHandler: SMM Performance Data buffer in SMRAM or overflow!\n"));\r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
-       LogEntryKey = SmmPerfCommData->LogEntryKey;\r
-       for (Index = 0; Index < SmmPerfCommData->NumberOfEntries; Index++) {\r
+       for (Index = 0; Index < NumberOfEntries; Index++) {\r
          CopyMem(\r
          CopyMem(\r
-           (UINT8 *) &(SmmPerfCommData->GaugeData[Index]),\r
+           (UINT8 *) &GaugeData[Index],\r
            (UINT8 *) &GaugeEntryExArray[LogEntryKey++],\r
            sizeof (GAUGE_DATA_ENTRY)\r
            );\r
            (UINT8 *) &GaugeEntryExArray[LogEntryKey++],\r
            sizeof (GAUGE_DATA_ENTRY)\r
            );\r
index ebf81ca6f72ce1106e1db10b5eebdd6a0efbf9ce..f3472e26f3db70e3afadb5c7cb15395d3dff7011 100644 (file)
@@ -266,6 +266,8 @@ FpdtSmiHandler (
 {\r
   EFI_STATUS                   Status;\r
   SMM_BOOT_RECORD_COMMUNICATE  *SmmCommData;\r
 {\r
   EFI_STATUS                   Status;\r
   SMM_BOOT_RECORD_COMMUNICATE  *SmmCommData;\r
+  UINTN                        BootRecordSize;\r
+  VOID                         *BootRecordData;\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
@@ -279,7 +281,7 @@ FpdtSmiHandler (
   }\r
   \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
   }\r
   \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication data buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM communication data buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -293,7 +295,9 @@ FpdtSmiHandler (
        break;\r
 \r
     case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :\r
        break;\r
 \r
     case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :\r
-       if (SmmCommData->BootRecordData == NULL || SmmCommData->BootRecordSize < mBootRecordSize) {\r
+       BootRecordData = SmmCommData->BootRecordData;\r
+       BootRecordSize = SmmCommData->BootRecordSize;\r
+       if (BootRecordData == NULL || BootRecordSize < mBootRecordSize) {\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        } \r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
        } \r
@@ -302,14 +306,14 @@ FpdtSmiHandler (
        // Sanity check\r
        //\r
        SmmCommData->BootRecordSize = mBootRecordSize;\r
        // Sanity check\r
        //\r
        SmmCommData->BootRecordSize = mBootRecordSize;\r
-       if (!InternalIsAddressValid ((UINTN)SmmCommData->BootRecordData, mBootRecordSize)) {\r
-         DEBUG ((EFI_D_ERROR, "SMM Data buffer in SMRAM or overflow!\n"));\r
+       if (!InternalIsAddressValid ((UINTN)BootRecordData, mBootRecordSize)) {\r
+         DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM Data buffer in SMRAM or overflow!\n"));\r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        CopyMem (\r
          Status = EFI_ACCESS_DENIED;\r
          break;\r
        }\r
 \r
        CopyMem (\r
-         (UINT8*)SmmCommData->BootRecordData, \r
+         (UINT8*)BootRecordData, \r
          mBootRecordBuffer, \r
          mBootRecordSize\r
          );\r
          mBootRecordBuffer, \r
          mBootRecordSize\r
          );\r
index 8b88ae41ee5df33d86b5c74f2cda680814594b1e..2580d478a38c1fb493699e83a0e10a5acaffa67b 100644 (file)
@@ -369,6 +369,9 @@ SmmFaultTolerantWriteHandler (
   VOID                                             *PrivateData;\r
   EFI_HANDLE                                       SmmFvbHandle;\r
   UINTN                                            InfoSize;\r
   VOID                                             *PrivateData;\r
   EFI_HANDLE                                       SmmFvbHandle;\r
   UINTN                                            InfoSize;\r
+  UINTN                                            CommBufferPayloadSize;\r
+  UINTN                                            PrivateDataSize;\r
+  UINTN                                            Length;\r
 \r
 \r
   //\r
 \r
 \r
   //\r
@@ -379,11 +382,13 @@ SmmFaultTolerantWriteHandler (
   }\r
 \r
   if (*CommBufferSize < SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
   }\r
 \r
   if (*CommBufferSize < SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
+    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer size invalid!\n"));\r
     return EFI_SUCCESS;\r
   }\r
     return EFI_SUCCESS;\r
   }\r
+  CommBufferPayloadSize = *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -400,17 +405,11 @@ SmmFaultTolerantWriteHandler (
 \r
   switch (SmmFtwFunctionHeader->Function) {\r
     case FTW_FUNCTION_GET_MAX_BLOCK_SIZE:\r
 \r
   switch (SmmFtwFunctionHeader->Function) {\r
     case FTW_FUNCTION_GET_MAX_BLOCK_SIZE:\r
-      SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      InfoSize = sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER);\r
-\r
-      //\r
-      // SMRAM range check already covered before\r
-      //\r
-      if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
-        Status = EFI_ACCESS_DENIED;\r
-        break;\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "GetMaxBlockSize: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
       }\r
       }\r
+      SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *) SmmFtwFunctionHeader->Data;\r
 \r
       Status = FtwGetMaxBlockSize (\r
                  &mFtwDevice->FtwInstance,\r
 \r
       Status = FtwGetMaxBlockSize (\r
                  &mFtwDevice->FtwInstance,\r
@@ -419,6 +418,10 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_ALLOCATE:\r
       break;\r
       \r
     case FTW_FUNCTION_ALLOCATE:\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_ALLOCATE_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "Allocate: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwAllocateHeader = (SMM_FTW_ALLOCATE_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = FtwAllocate (\r
                  &mFtwDevice->FtwInstance,\r
       SmmFtwAllocateHeader = (SMM_FTW_ALLOCATE_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = FtwAllocate (\r
                  &mFtwDevice->FtwInstance,\r
@@ -429,11 +432,36 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_WRITE:\r
       break;\r
       \r
     case FTW_FUNCTION_WRITE:\r
+      if (CommBufferPayloadSize < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data)) {\r
+        DEBUG ((EFI_D_ERROR, "Write: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwWriteHeader = (SMM_FTW_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
       SmmFtwWriteHeader = (SMM_FTW_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      if (SmmFtwWriteHeader->PrivateDataSize == 0) {\r
+      Length = SmmFtwWriteHeader->Length;\r
+      PrivateDataSize = SmmFtwWriteHeader->PrivateDataSize;\r
+      if (((UINTN)(~0) - Length < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data)) ||\r
+        ((UINTN)(~0) - PrivateDataSize < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data) + Length)) {\r
+        //\r
+        // Prevent InfoSize overflow\r
+        //\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      }\r
+      InfoSize = OFFSET_OF (SMM_FTW_WRITE_HEADER, Data) + Length + PrivateDataSize;\r
+\r
+      //\r
+      // SMRAM range check already covered before\r
+      //\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "Write: Data size exceed communication buffer size limit!\n"));\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      }\r
+\r
+      if (PrivateDataSize == 0) {\r
         PrivateData = NULL;\r
       } else {\r
         PrivateData = NULL;\r
       } else {\r
-        PrivateData = (VOID *)&SmmFtwWriteHeader->Data[SmmFtwWriteHeader->Length];\r
+        PrivateData = (VOID *)&SmmFtwWriteHeader->Data[Length];\r
       }\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwWriteHeader->FvbBaseAddress, \r
       }\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwWriteHeader->FvbBaseAddress, \r
@@ -445,7 +473,7 @@ SmmFaultTolerantWriteHandler (
                    &mFtwDevice->FtwInstance,\r
                    SmmFtwWriteHeader->Lba,\r
                    SmmFtwWriteHeader->Offset,\r
                    &mFtwDevice->FtwInstance,\r
                    SmmFtwWriteHeader->Lba,\r
                    SmmFtwWriteHeader->Offset,\r
-                   SmmFtwWriteHeader->Length,\r
+                   Length,\r
                    PrivateData,\r
                    SmmFvbHandle,\r
                    SmmFtwWriteHeader->Data\r
                    PrivateData,\r
                    SmmFvbHandle,\r
                    SmmFtwWriteHeader->Data\r
@@ -454,6 +482,10 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_RESTART:\r
       break;\r
       \r
     case FTW_FUNCTION_RESTART:\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_RESTART_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "Restart: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwRestartHeader = (SMM_FTW_RESTART_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwRestartHeader->FvbBaseAddress, \r
       SmmFtwRestartHeader = (SMM_FTW_RESTART_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwRestartHeader->FvbBaseAddress, \r
@@ -470,20 +502,25 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_GET_LAST_WRITE:\r
       break;\r
       \r
     case FTW_FUNCTION_GET_LAST_WRITE:\r
+      if (CommBufferPayloadSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)) {\r
+        DEBUG ((EFI_D_ERROR, "GetLastWrite: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwGetLastWriteHeader = (SMM_FTW_GET_LAST_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
       SmmFtwGetLastWriteHeader = (SMM_FTW_GET_LAST_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      if ((UINTN)(~0) - SmmFtwGetLastWriteHeader->PrivateDataSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)){\r
+      PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;\r
+      if ((UINTN)(~0) - PrivateDataSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)){\r
         //\r
         // Prevent InfoSize overflow\r
         //\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
       }\r
         //\r
         // Prevent InfoSize overflow\r
         //\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
       }\r
-      InfoSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) + SmmFtwGetLastWriteHeader->PrivateDataSize;\r
+      InfoSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) + PrivateDataSize;\r
 \r
       //\r
       // SMRAM range check already covered before\r
       //\r
 \r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
+      if (InfoSize > CommBufferPayloadSize) {\r
         DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
         DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
@@ -495,10 +532,11 @@ SmmFaultTolerantWriteHandler (
                  &SmmFtwGetLastWriteHeader->Lba,\r
                  &SmmFtwGetLastWriteHeader->Offset,\r
                  &SmmFtwGetLastWriteHeader->Length,\r
                  &SmmFtwGetLastWriteHeader->Lba,\r
                  &SmmFtwGetLastWriteHeader->Offset,\r
                  &SmmFtwGetLastWriteHeader->Length,\r
-                 &SmmFtwGetLastWriteHeader->PrivateDataSize,\r
+                 &PrivateDataSize,\r
                  (VOID *)SmmFtwGetLastWriteHeader->Data,\r
                  &SmmFtwGetLastWriteHeader->Complete\r
                  );\r
                  (VOID *)SmmFtwGetLastWriteHeader->Data,\r
                  &SmmFtwGetLastWriteHeader->Complete\r
                  );\r
+      SmmFtwGetLastWriteHeader->PrivateDataSize = PrivateDataSize;\r
       break;\r
 \r
     default:\r
       break;\r
 \r
     default:\r
@@ -532,6 +570,7 @@ FvbNotificationEvent (
   EFI_STATUS                              Status;\r
   EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;\r
   EFI_HANDLE                              SmmFtwHandle;\r
   EFI_STATUS                              Status;\r
   EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;\r
   EFI_HANDLE                              SmmFtwHandle;\r
+  EFI_HANDLE                              FtwHandle;\r
   \r
   //\r
   // Just return to avoid install SMM FaultTolerantWriteProtocol again\r
   \r
   //\r
   // Just return to avoid install SMM FaultTolerantWriteProtocol again\r
@@ -553,7 +592,7 @@ FvbNotificationEvent (
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Install protocol interface\r
   //\r
   //\r
   // Install protocol interface\r
   //\r
@@ -565,12 +604,18 @@ FvbNotificationEvent (
                     );\r
   ASSERT_EFI_ERROR (Status); \r
 \r
                     );\r
   ASSERT_EFI_ERROR (Status); \r
 \r
+  ///\r
+  /// Register SMM FTW SMI handler\r
+  ///\r
+  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
   // Notify the Ftw wrapper driver SMM Ftw is ready\r
   //\r
   //\r
   // Notify the Ftw wrapper driver SMM Ftw is ready\r
   //\r
-  SmmFtwHandle = NULL;\r
+  FtwHandle = NULL;\r
   Status = gBS->InstallProtocolInterface (\r
   Status = gBS->InstallProtocolInterface (\r
-                  &SmmFtwHandle,\r
+                  &FtwHandle,\r
                   &gEfiSmmFaultTolerantWriteProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   NULL\r
                   &gEfiSmmFaultTolerantWriteProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   NULL\r
@@ -621,7 +666,6 @@ SmmFaultTolerantWriteInitialize (
   )\r
 {\r
   EFI_STATUS                              Status;\r
   )\r
 {\r
   EFI_STATUS                              Status;\r
-  EFI_HANDLE                              FtwHandle;\r
   EFI_SMM_ACCESS2_PROTOCOL                *SmmAccess;\r
   UINTN                                   Size;\r
   VOID                                    *SmmEndOfDxeRegistration;\r
   EFI_SMM_ACCESS2_PROTOCOL                *SmmAccess;\r
   UINTN                                   Size;\r
   VOID                                    *SmmEndOfDxeRegistration;\r
@@ -677,12 +721,6 @@ SmmFaultTolerantWriteInitialize (
   ASSERT_EFI_ERROR (Status);\r
 \r
   FvbNotificationEvent (NULL, NULL, NULL);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   FvbNotificationEvent (NULL, NULL, NULL);\r
-\r
-  ///\r
-  /// Register SMM FTW SMI handler\r
-  ///\r
-  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &FtwHandle);\r
-  ASSERT_EFI_ERROR (Status);\r
   \r
   return EFI_SUCCESS;\r
 }\r
   \r
   return EFI_SUCCESS;\r
 }\r
index 24b157df088c3c5f493f5a01830c313faec90460..772d10dcd46cb18e6965c1743bf39156a62f72ca 100644 (file)
@@ -3,7 +3,7 @@
   Implement the Fault Tolerant Write (FTW) protocol based on SMM FTW \r
   module.\r
 \r
   Implement the Fault Tolerant Write (FTW) protocol based on SMM FTW \r
   module.\r
 \r
-Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved. <BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -463,13 +463,17 @@ FtwGetLastWrite (
   // Get data from SMM\r
   //\r
   *PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;\r
   // Get data from SMM\r
   //\r
   *PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;\r
-  if (!EFI_ERROR (Status)) {\r
+  if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) {\r
     *Lba      = SmmFtwGetLastWriteHeader->Lba;\r
     *Offset   = SmmFtwGetLastWriteHeader->Offset; \r
     *Length   = SmmFtwGetLastWriteHeader->Length;\r
     *Complete = SmmFtwGetLastWriteHeader->Complete;\r
     CopyGuid (CallerId, &SmmFtwGetLastWriteHeader->CallerId);\r
     *Lba      = SmmFtwGetLastWriteHeader->Lba;\r
     *Offset   = SmmFtwGetLastWriteHeader->Offset; \r
     *Length   = SmmFtwGetLastWriteHeader->Length;\r
     *Complete = SmmFtwGetLastWriteHeader->Complete;\r
     CopyGuid (CallerId, &SmmFtwGetLastWriteHeader->CallerId);\r
-    CopyMem (PrivateData, SmmFtwGetLastWriteHeader->Data, *PrivateDataSize);\r
+    if (Status == EFI_SUCCESS) {\r
+      CopyMem (PrivateData, SmmFtwGetLastWriteHeader->Data, *PrivateDataSize);\r
+    }\r
+  } else if (Status == EFI_NOT_FOUND) {\r
+    *Complete = SmmFtwGetLastWriteHeader->Complete;\r
   }\r
 \r
   FreePool (SmmCommunicateHeader);  \r
   }\r
 \r
   FreePool (SmmCommunicateHeader);  \r
index 7a0d6d29a5f7685e586307b13028bd5e056cd817..4cb88106ee3b0cfec43e5f3bed9197662c645350 100644 (file)
@@ -111,6 +111,7 @@ SmmLockBoxSave (
   )\r
 {\r
   EFI_STATUS                  Status;\r
   )\r
 {\r
   EFI_STATUS                  Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_SAVE TempLockBoxParameterSave;\r
 \r
   //\r
   // Sanity check\r
 \r
   //\r
   // Sanity check\r
@@ -121,10 +122,12 @@ SmmLockBoxSave (
     return ;\r
   }\r
 \r
     return ;\r
   }\r
 \r
+  CopyMem (&TempLockBoxParameterSave, LockBoxParameterSave, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE));\r
+\r
   //\r
   // Sanity check\r
   //\r
   //\r
   // Sanity check\r
   //\r
-  if (!IsAddressValid ((UINTN)LockBoxParameterSave->Buffer, (UINTN)LockBoxParameterSave->Length)) {\r
+  if (!IsAddressValid ((UINTN)TempLockBoxParameterSave.Buffer, (UINTN)TempLockBoxParameterSave.Length)) {\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Save address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Save address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
@@ -134,9 +137,9 @@ SmmLockBoxSave (
   // Save data\r
   //\r
   Status = SaveLockBox (\r
   // Save data\r
   //\r
   Status = SaveLockBox (\r
-             &LockBoxParameterSave->Guid,\r
-             (VOID *)(UINTN)LockBoxParameterSave->Buffer,\r
-             (UINTN)LockBoxParameterSave->Length\r
+             &TempLockBoxParameterSave.Guid,\r
+             (VOID *)(UINTN)TempLockBoxParameterSave.Buffer,\r
+             (UINTN)TempLockBoxParameterSave.Length\r
              );\r
   LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
              );\r
   LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
@@ -153,6 +156,7 @@ SmmLockBoxSetAttributes (
   )\r
 {\r
   EFI_STATUS                    Status;\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes;\r
 \r
   //\r
   // Sanity check\r
 \r
   //\r
   // Sanity check\r
@@ -163,12 +167,14 @@ SmmLockBoxSetAttributes (
     return ;\r
   }\r
 \r
     return ;\r
   }\r
 \r
+  CopyMem (&TempLockBoxParameterSetAttributes, LockBoxParameterSetAttributes, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES));\r
+\r
   //\r
   // Update data\r
   //\r
   Status = SetLockBoxAttributes (\r
   //\r
   // Update data\r
   //\r
   Status = SetLockBoxAttributes (\r
-             &LockBoxParameterSetAttributes->Guid,\r
-             LockBoxParameterSetAttributes->Attributes\r
+             &TempLockBoxParameterSetAttributes.Guid,\r
+             TempLockBoxParameterSetAttributes.Attributes\r
              );\r
   LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
              );\r
   LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
@@ -189,6 +195,7 @@ SmmLockBoxUpdate (
   )\r
 {\r
   EFI_STATUS                    Status;\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_UPDATE TempLockBoxParameterUpdate;\r
 \r
   //\r
   // Sanity check\r
 \r
   //\r
   // Sanity check\r
@@ -199,10 +206,12 @@ SmmLockBoxUpdate (
     return ;\r
   }\r
 \r
     return ;\r
   }\r
 \r
+  CopyMem (&TempLockBoxParameterUpdate, LockBoxParameterUpdate, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE));\r
+\r
   //\r
   // Sanity check\r
   //\r
   //\r
   // Sanity check\r
   //\r
-  if (!IsAddressValid ((UINTN)LockBoxParameterUpdate->Buffer, (UINTN)LockBoxParameterUpdate->Length)) {\r
+  if (!IsAddressValid ((UINTN)TempLockBoxParameterUpdate.Buffer, (UINTN)TempLockBoxParameterUpdate.Length)) {\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Update address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Update address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
@@ -212,10 +221,10 @@ SmmLockBoxUpdate (
   // Update data\r
   //\r
   Status = UpdateLockBox (\r
   // Update data\r
   //\r
   Status = UpdateLockBox (\r
-             &LockBoxParameterUpdate->Guid,\r
-             (UINTN)LockBoxParameterUpdate->Offset,\r
-             (VOID *)(UINTN)LockBoxParameterUpdate->Buffer,\r
-             (UINTN)LockBoxParameterUpdate->Length\r
+             &TempLockBoxParameterUpdate.Guid,\r
+             (UINTN)TempLockBoxParameterUpdate.Offset,\r
+             (VOID *)(UINTN)TempLockBoxParameterUpdate.Buffer,\r
+             (UINTN)TempLockBoxParameterUpdate.Length\r
              );\r
   LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
              );\r
   LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
@@ -236,11 +245,14 @@ SmmLockBoxRestore (
   )\r
 {\r
   EFI_STATUS                     Status;\r
   )\r
 {\r
   EFI_STATUS                     Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE TempLockBoxParameterRestore;\r
+\r
+  CopyMem (&TempLockBoxParameterRestore, LockBoxParameterRestore, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE));\r
 \r
   //\r
   // Sanity check\r
   //\r
 \r
   //\r
   // Sanity check\r
   //\r
-  if (!IsAddressValid ((UINTN)LockBoxParameterRestore->Buffer, (UINTN)LockBoxParameterRestore->Length)) {\r
+  if (!IsAddressValid ((UINTN)TempLockBoxParameterRestore.Buffer, (UINTN)TempLockBoxParameterRestore.Length)) {\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM or buffer overflow!\n"));\r
     LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
     return ;\r
@@ -249,17 +261,17 @@ SmmLockBoxRestore (
   //\r
   // Restore data\r
   //\r
   //\r
   // Restore data\r
   //\r
-  if ((LockBoxParameterRestore->Length == 0) && (LockBoxParameterRestore->Buffer == 0)) {\r
+  if ((TempLockBoxParameterRestore.Length == 0) && (TempLockBoxParameterRestore.Buffer == 0)) {\r
     Status = RestoreLockBox (\r
     Status = RestoreLockBox (\r
-               &LockBoxParameterRestore->Guid,\r
+               &TempLockBoxParameterRestore.Guid,\r
                NULL,\r
                NULL\r
                );\r
   } else {\r
     Status = RestoreLockBox (\r
                NULL,\r
                NULL\r
                );\r
   } else {\r
     Status = RestoreLockBox (\r
-               &LockBoxParameterRestore->Guid,\r
-               (VOID *)(UINTN)LockBoxParameterRestore->Buffer,\r
-               (UINTN *)&LockBoxParameterRestore->Length\r
+               &TempLockBoxParameterRestore.Guid,\r
+               (VOID *)(UINTN)TempLockBoxParameterRestore.Buffer,\r
+               (UINTN *)&TempLockBoxParameterRestore.Length\r
                );\r
   }\r
   LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;\r
                );\r
   }\r
   LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;\r
index f8e6bd58828ae592e205d4fdeafe94961cee767b..111a6cd41174f4cb581c3ec5ec6ea8c5bbd2f838 100644 (file)
@@ -15,7 +15,7 @@
   VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), \r
   SmmVariableGetStatistics() should also do validation based on its own knowledge.\r
 \r
   VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), \r
   SmmVariableGetStatistics() should also do validation based on its own knowledge.\r
 \r
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
@@ -44,7 +44,9 @@ EFI_HANDLE                                           mSmmVariableHandle      = N
 EFI_HANDLE                                           mVariableHandle         = NULL;\r
 BOOLEAN                                              mAtRuntime              = FALSE;\r
 EFI_GUID                                             mZeroGuid               = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
 EFI_HANDLE                                           mVariableHandle         = NULL;\r
 BOOLEAN                                              mAtRuntime              = FALSE;\r
 EFI_GUID                                             mZeroGuid               = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
-  \r
+UINT8                                                *mVariableBufferPayload = NULL;\r
+UINTN                                                mVariableBufferPayloadSize;\r
+\r
 EFI_SMM_VARIABLE_PROTOCOL      gSmmVariable = {\r
   VariableServiceGetVariable,\r
   VariableServiceGetNextVariableName,\r
 EFI_SMM_VARIABLE_PROTOCOL      gSmmVariable = {\r
   VariableServiceGetVariable,\r
   VariableServiceGetNextVariableName,\r
@@ -302,6 +304,8 @@ GetFvbCountAndBuffer (
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);\r
   if (EFI_ERROR(Status)) {\r
     *NumberHandles = 0;\r
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);\r
   if (EFI_ERROR(Status)) {\r
     *NumberHandles = 0;\r
+    FreePool (*Buffer);\r
+    *Buffer = NULL;\r
   }\r
 \r
   return Status;\r
   }\r
 \r
   return Status;\r
@@ -337,7 +341,8 @@ SmmVariableGetStatistics (
   UINTN                                                NameLength;\r
   UINTN                                                StatisticsInfoSize;\r
   CHAR16                                               *InfoName;\r
   UINTN                                                NameLength;\r
   UINTN                                                StatisticsInfoSize;\r
   CHAR16                                               *InfoName;\r
\r
+  EFI_GUID                                             VendorGuid;\r
+\r
   ASSERT (InfoEntry != NULL);\r
   VariableInfo = gVariableInfo; \r
   if (VariableInfo == NULL) {\r
   ASSERT (InfoEntry != NULL);\r
   VariableInfo = gVariableInfo; \r
   if (VariableInfo == NULL) {\r
@@ -351,7 +356,9 @@ SmmVariableGetStatistics (
   }\r
   InfoName = (CHAR16 *)(InfoEntry + 1);\r
 \r
   }\r
   InfoName = (CHAR16 *)(InfoEntry + 1);\r
 \r
-  if (CompareGuid (&InfoEntry->VendorGuid, &mZeroGuid)) {\r
+  CopyGuid (&VendorGuid, &InfoEntry->VendorGuid);\r
+\r
+  if (CompareGuid (&VendorGuid, &mZeroGuid)) {\r
     //\r
     // Return the first variable info\r
     //\r
     //\r
     // Return the first variable info\r
     //\r
@@ -365,7 +372,7 @@ SmmVariableGetStatistics (
   // Get the next variable info\r
   //\r
   while (VariableInfo != NULL) {\r
   // Get the next variable info\r
   //\r
   while (VariableInfo != NULL) {\r
-    if (CompareGuid (&VariableInfo->VendorGuid, &InfoEntry->VendorGuid)) {\r
+    if (CompareGuid (&VariableInfo->VendorGuid, &VendorGuid)) {\r
       NameLength = StrSize (VariableInfo->Name);\r
       if (NameLength == StrSize (InfoName)) {\r
         if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) {\r
       NameLength = StrSize (VariableInfo->Name);\r
       if (NameLength == StrSize (InfoName)) {\r
         if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) {\r
@@ -445,6 +452,7 @@ SmmVariableHandler (
   VARIABLE_INFO_ENTRY                              *VariableInfo;\r
   UINTN                                            InfoSize;\r
   UINTN                                            NameBufferSize;\r
   VARIABLE_INFO_ENTRY                              *VariableInfo;\r
   UINTN                                            InfoSize;\r
   UINTN                                            NameBufferSize;\r
+  UINTN                                            CommBufferPayloadSize;\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
@@ -454,18 +462,32 @@ SmmVariableHandler (
   }\r
 \r
   if (*CommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
   }\r
 \r
   if (*CommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer size invalid!\n"));\r
+    return EFI_SUCCESS;\r
+  }\r
+  CommBufferPayloadSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;\r
+  if (CommBufferPayloadSize > mVariableBufferPayloadSize) {\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;\r
   switch (SmmVariableFunctionHeader->Function) {\r
     case SMM_VARIABLE_FUNCTION_GET_VARIABLE:\r
     return EFI_SUCCESS;\r
   }\r
 \r
   SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;\r
   switch (SmmVariableFunctionHeader->Function) {\r
     case SMM_VARIABLE_FUNCTION_GET_VARIABLE:\r
-      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "GetVariable: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload;\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
@@ -480,8 +502,8 @@ SmmVariableHandler (
       //\r
       // SMRAM range check already covered before\r
       //\r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "GetVariable: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
@@ -501,10 +523,19 @@ SmmVariableHandler (
                  &SmmVariableHeader->DataSize,\r
                  (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize\r
                  );\r
                  &SmmVariableHeader->DataSize,\r
                  (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize\r
                  );\r
+      CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:\r
-      GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "GetNextVariableName: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) mVariableBufferPayload;\r
       if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
         //\r
         // Prevent InfoSize overflow happen\r
       if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
         //\r
         // Prevent InfoSize overflow happen\r
@@ -517,13 +548,13 @@ SmmVariableHandler (
       //\r
       // SMRAM range check already covered before\r
       //\r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "GetNextVariableName: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
 \r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
 \r
-      NameBufferSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE -  OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+      NameBufferSize = CommBufferPayloadSize - OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
       if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') {\r
         //\r
         // Make sure input VariableName is A Null-terminated string.\r
       if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') {\r
         //\r
         // Make sure input VariableName is A Null-terminated string.\r
@@ -537,10 +568,19 @@ SmmVariableHandler (
                  GetNextVariableName->Name,\r
                  &GetNextVariableName->Guid\r
                  );\r
                  GetNextVariableName->Name,\r
                  &GetNextVariableName->Guid\r
                  );\r
+      CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_SET_VARIABLE:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_SET_VARIABLE:\r
-      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "SetVariable: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload;\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
@@ -556,8 +596,8 @@ SmmVariableHandler (
       // SMRAM range check already covered before\r
       // Data buffer should not contain SMM range\r
       //\r
       // SMRAM range check already covered before\r
       // Data buffer should not contain SMM range\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "SetVariable: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
@@ -580,17 +620,11 @@ SmmVariableHandler (
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:\r
-      QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data;\r
-      InfoSize = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);\r
-\r
-      //\r
-      // SMRAM range check already covered before\r
-      //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
-        Status = EFI_ACCESS_DENIED;\r
-        goto EXIT;\r
+      if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {\r
+        DEBUG ((EFI_D_ERROR, "QueryVariableInfo: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
       }\r
       }\r
+      QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data;\r
 \r
       Status = VariableServiceQueryVariableInfo (\r
                  QueryVariableInfo->Attributes,\r
 \r
       Status = VariableServiceQueryVariableInfo (\r
                  QueryVariableInfo->Attributes,\r
@@ -624,7 +658,7 @@ SmmVariableHandler (
       //\r
      \r
       if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {\r
       //\r
      \r
       if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {\r
-        DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM!\n"));\r
+        DEBUG ((EFI_D_ERROR, "GetStatistics: SMM communication buffer in SMRAM!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }  \r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }  \r
@@ -781,6 +815,16 @@ VariableServiceInitialize (
 \r
   mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
 \r
 \r
   mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
 \r
+  mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +\r
+                               OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);\r
+\r
+  Status = gSmst->SmmAllocatePool (\r
+                    EfiRuntimeServicesData,\r
+                    mVariableBufferPayloadSize,\r
+                    (VOID **)&mVariableBufferPayload\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   ///\r
   /// Register SMM variable SMI handler\r
   ///\r
   ///\r
   /// Register SMM variable SMI handler\r
   ///\r
index e76600ee6a01aaf5ea7a86e331b6c7225707dd39..eb67bae748fe0e15bcd78f7a279e5afce064bb4e 100644 (file)
@@ -42,6 +42,7 @@ EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication          = NULL;
 UINT8                           *mVariableBuffer            = NULL;\r
 UINT8                           *mVariableBufferPhysical    = NULL;\r
 UINTN                            mVariableBufferSize;\r
 UINT8                           *mVariableBuffer            = NULL;\r
 UINT8                           *mVariableBufferPhysical    = NULL;\r
 UINTN                            mVariableBufferSize;\r
+UINTN                            mVariableBufferPayloadSize;\r
 EFI_LOCK                         mVariableServicesLock;\r
 \r
 /**\r
 EFI_LOCK                         mVariableServicesLock;\r
 \r
 /**\r
@@ -189,7 +190,6 @@ RuntimeServiceGetVariable (
   EFI_STATUS                                Status;\r
   UINTN                                     PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE  *SmmVariableHeader;\r
   EFI_STATUS                                Status;\r
   UINTN                                     PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE  *SmmVariableHeader;\r
-  UINTN                                     SmmCommBufPayloadSize;\r
   UINTN                                     TempDataSize;\r
   UINTN                                     VariableNameSize;\r
 \r
   UINTN                                     TempDataSize;\r
   UINTN                                     VariableNameSize;\r
 \r
@@ -201,17 +201,13 @@ RuntimeServiceGetVariable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // SMM Communication Buffer max payload size\r
-  //\r
-  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);\r
   TempDataSize          = *DataSize;\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   //\r
   // If VariableName exceeds SMM payload limit. Return failure\r
   //\r
   TempDataSize          = *DataSize;\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   //\r
   // If VariableName exceeds SMM payload limit. Return failure\r
   //\r
-  if (VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+  if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -221,11 +217,11 @@ RuntimeServiceGetVariable (
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
-  if (TempDataSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize) {\r
+  if (TempDataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize) {\r
     //\r
     // If output data buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
     //\r
     // If output data buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
-    TempDataSize = SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize;\r
+    TempDataSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize;\r
   }\r
   PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + TempDataSize;\r
 \r
   }\r
   PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + TempDataSize;\r
 \r
@@ -300,7 +296,6 @@ RuntimeServiceGetNextVariableName (
   EFI_STATUS                                      Status;\r
   UINTN                                           PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;\r
   EFI_STATUS                                      Status;\r
   UINTN                                           PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;\r
-  UINTN                                           SmmCommBufPayloadSize;\r
   UINTN                                           OutVariableNameSize;\r
   UINTN                                           InVariableNameSize;\r
 \r
   UINTN                                           OutVariableNameSize;\r
   UINTN                                           InVariableNameSize;\r
 \r
@@ -308,17 +303,13 @@ RuntimeServiceGetNextVariableName (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // SMM Communication Buffer max payload size\r
-  //\r
-  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);\r
   OutVariableNameSize   = *VariableNameSize;\r
   InVariableNameSize    = StrSize (VariableName);\r
 \r
   //\r
   // If input string exceeds SMM payload limit. Return failure\r
   //\r
   OutVariableNameSize   = *VariableNameSize;\r
   InVariableNameSize    = StrSize (VariableName);\r
 \r
   //\r
   // If input string exceeds SMM payload limit. Return failure\r
   //\r
-  if (InVariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+  if (InVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -328,11 +319,11 @@ RuntimeServiceGetNextVariableName (
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
-  if (OutVariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+  if (OutVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
     //\r
     // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
     //\r
     // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
-    OutVariableNameSize = SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+    OutVariableNameSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
   }\r
   //\r
   // Payload should be Guid + NameSize + MAX of Input & Output buffer\r
   }\r
   //\r
   // Payload should be Guid + NameSize + MAX of Input & Output buffer\r
@@ -430,21 +421,13 @@ RuntimeServiceSetVariable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (DataSize >= mVariableBufferSize) {\r
-    //\r
-    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to\r
-    // overflow to a small value and pass the check in InitCommunicateBuffer().\r
-    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if DataSize is >= mVariableBufferSize.\r
-    // And there will be further check to ensure the total size is also not > mVariableBufferSize.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   VariableNameSize      = StrSize (VariableName);\r
 \r
-  if ((UINTN)(~0) - VariableNameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + DataSize) {\r
-    //\r
-    // Prevent PayloadSize overflow\r
-    //\r
+  //\r
+  // If VariableName or DataSize exceeds SMM payload limit. Return failure\r
+  //\r
+  if ((VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
+      (DataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize)){\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -654,10 +637,11 @@ SmmVariableReady (
   ASSERT_EFI_ERROR (Status);\r
   \r
   //\r
   ASSERT_EFI_ERROR (Status);\r
   \r
   //\r
-  // Allocate memory for variable store.\r
+  // Allocate memory for variable communicate buffer.\r
   //\r
   //\r
-  mVariableBufferSize  = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;\r
-  mVariableBufferSize += MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
+  mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +\r
+                               OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);\r
+  mVariableBufferSize  = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize;\r
   mVariableBuffer      = AllocateRuntimePool (mVariableBufferSize);\r
   ASSERT (mVariableBuffer != NULL);\r
 \r
   mVariableBuffer      = AllocateRuntimePool (mVariableBufferSize);\r
   ASSERT (mVariableBuffer != NULL);\r
 \r
index 47bc390f6fbc4ebbab5ba07d42317872a6de2af8..754ab9a794970d4afeba36b4978b5c3e7f05c54f 100644 (file)
@@ -14,7 +14,7 @@
   VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), \r
   SmmVariableGetStatistics() should also do validation based on its own knowledge.\r
 \r
   VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), \r
   SmmVariableGetStatistics() should also do validation based on its own knowledge.\r
 \r
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
@@ -44,7 +44,9 @@ EFI_HANDLE                                           mSmmVariableHandle      = N
 EFI_HANDLE                                           mVariableHandle         = NULL;\r
 BOOLEAN                                              mAtRuntime              = FALSE;\r
 EFI_GUID                                             mZeroGuid               = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
 EFI_HANDLE                                           mVariableHandle         = NULL;\r
 BOOLEAN                                              mAtRuntime              = FALSE;\r
 EFI_GUID                                             mZeroGuid               = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
-  \r
+UINT8                                                *mVariableBufferPayload = NULL;\r
+UINTN                                                mVariableBufferPayloadSize;\r
+\r
 EFI_SMM_VARIABLE_PROTOCOL      gSmmVariable = {\r
   VariableServiceGetVariable,\r
   VariableServiceGetNextVariableName,\r
 EFI_SMM_VARIABLE_PROTOCOL      gSmmVariable = {\r
   VariableServiceGetVariable,\r
   VariableServiceGetNextVariableName,\r
@@ -302,6 +304,8 @@ GetFvbCountAndBuffer (
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);\r
   if (EFI_ERROR(Status)) {\r
     *NumberHandles = 0;\r
   *NumberHandles = BufferSize / sizeof(EFI_HANDLE);\r
   if (EFI_ERROR(Status)) {\r
     *NumberHandles = 0;\r
+    FreePool (*Buffer);\r
+    *Buffer = NULL;\r
   }\r
 \r
   return Status;\r
   }\r
 \r
   return Status;\r
@@ -338,6 +342,7 @@ SmmVariableGetStatistics (
   UINTN                                                NameLength;\r
   UINTN                                                StatisticsInfoSize;\r
   CHAR16                                               *InfoName;\r
   UINTN                                                NameLength;\r
   UINTN                                                StatisticsInfoSize;\r
   CHAR16                                               *InfoName;\r
+  EFI_GUID                                             VendorGuid;\r
  \r
   if (InfoEntry == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
  \r
   if (InfoEntry == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -355,7 +360,9 @@ SmmVariableGetStatistics (
   }\r
   InfoName = (CHAR16 *)(InfoEntry + 1);\r
 \r
   }\r
   InfoName = (CHAR16 *)(InfoEntry + 1);\r
 \r
-  if (CompareGuid (&InfoEntry->VendorGuid, &mZeroGuid)) {\r
+  CopyGuid (&VendorGuid, &InfoEntry->VendorGuid);\r
+\r
+  if (CompareGuid (&VendorGuid, &mZeroGuid)) {\r
     //\r
     // Return the first variable info\r
     //\r
     //\r
     // Return the first variable info\r
     //\r
@@ -369,7 +376,7 @@ SmmVariableGetStatistics (
   // Get the next variable info\r
   //\r
   while (VariableInfo != NULL) {\r
   // Get the next variable info\r
   //\r
   while (VariableInfo != NULL) {\r
-    if (CompareGuid (&VariableInfo->VendorGuid, &InfoEntry->VendorGuid)) {\r
+    if (CompareGuid (&VariableInfo->VendorGuid, &VendorGuid)) {\r
       NameLength = StrSize (VariableInfo->Name);\r
       if (NameLength == StrSize (InfoName)) {\r
         if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) {\r
       NameLength = StrSize (VariableInfo->Name);\r
       if (NameLength == StrSize (InfoName)) {\r
         if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) {\r
@@ -450,6 +457,7 @@ SmmVariableHandler (
   VARIABLE_INFO_ENTRY                              *VariableInfo;\r
   UINTN                                            InfoSize;\r
   UINTN                                            NameBufferSize;\r
   VARIABLE_INFO_ENTRY                              *VariableInfo;\r
   UINTN                                            InfoSize;\r
   UINTN                                            NameBufferSize;\r
+  UINTN                                            CommBufferPayloadSize;\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
@@ -459,11 +467,17 @@ SmmVariableHandler (
   }\r
 \r
   if (*CommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
   }\r
 \r
   if (*CommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer size invalid!\n"));\r
+    return EFI_SUCCESS;\r
+  }\r
+  CommBufferPayloadSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;\r
+  if (CommBufferPayloadSize > mVariableBufferPayloadSize) {\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM or overflow!\n"));\r
+    DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
   \r
     return EFI_SUCCESS;\r
   }\r
   \r
@@ -471,7 +485,15 @@ SmmVariableHandler (
     \r
   switch (SmmVariableFunctionHeader->Function) {\r
     case SMM_VARIABLE_FUNCTION_GET_VARIABLE:\r
     \r
   switch (SmmVariableFunctionHeader->Function) {\r
     case SMM_VARIABLE_FUNCTION_GET_VARIABLE:\r
-      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "GetVariable: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload;\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
@@ -486,8 +508,8 @@ SmmVariableHandler (
       //\r
       // SMRAM range check already covered before\r
       //\r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "GetVariable: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
@@ -507,10 +529,19 @@ SmmVariableHandler (
                  &SmmVariableHeader->DataSize,\r
                  (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize\r
                  );\r
                  &SmmVariableHeader->DataSize,\r
                  (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize\r
                  );\r
+      CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:\r
-      GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "GetNextVariableName: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) mVariableBufferPayload;\r
       if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
         //\r
         // Prevent InfoSize overflow happen\r
       if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
         //\r
         // Prevent InfoSize overflow happen\r
@@ -523,13 +554,13 @@ SmmVariableHandler (
       //\r
       // SMRAM range check already covered before\r
       //\r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "GetNextVariableName: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
 \r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
 \r
-      NameBufferSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE -  OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+      NameBufferSize = CommBufferPayloadSize - OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
       if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') {\r
         //\r
         // Make sure input VariableName is A Null-terminated string.\r
       if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') {\r
         //\r
         // Make sure input VariableName is A Null-terminated string.\r
@@ -543,10 +574,19 @@ SmmVariableHandler (
                  GetNextVariableName->Name,\r
                  &GetNextVariableName->Guid\r
                  );\r
                  GetNextVariableName->Name,\r
                  &GetNextVariableName->Guid\r
                  );\r
+      CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_SET_VARIABLE:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_SET_VARIABLE:\r
-      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+      if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+        DEBUG ((EFI_D_ERROR, "SetVariable: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
+      //\r
+      // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.\r
+      //\r
+      CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);\r
+      SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload;\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
       if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
          ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
         //\r
@@ -562,8 +602,8 @@ SmmVariableHandler (
       // SMRAM range check already covered before\r
       // Data buffer should not contain SMM range\r
       //\r
       // SMRAM range check already covered before\r
       // Data buffer should not contain SMM range\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "SetVariable: Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }\r
@@ -586,17 +626,11 @@ SmmVariableHandler (
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:\r
       break;\r
       \r
     case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:\r
-      QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data;\r
-      InfoSize = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);\r
-\r
-      //\r
-      // SMRAM range check already covered before\r
-      //\r
-      if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
-        Status = EFI_ACCESS_DENIED;\r
-        goto EXIT;\r
+      if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {\r
+        DEBUG ((EFI_D_ERROR, "QueryVariableInfo: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
       }\r
       }\r
+      QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data;\r
   \r
       Status = VariableServiceQueryVariableInfo (\r
                  QueryVariableInfo->Attributes,\r
   \r
       Status = VariableServiceQueryVariableInfo (\r
                  QueryVariableInfo->Attributes,\r
@@ -630,7 +664,7 @@ SmmVariableHandler (
       //\r
      \r
       if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {\r
       //\r
      \r
       if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {\r
-        DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM!\n"));\r
+        DEBUG ((EFI_D_ERROR, "GetStatistics: SMM communication buffer in SMRAM!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }  \r
         Status = EFI_ACCESS_DENIED;\r
         goto EXIT;\r
       }  \r
@@ -786,6 +820,16 @@ VariableServiceInitialize (
 \r
   mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
 \r
 \r
   mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
 \r
+  mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +\r
+                               OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);\r
+\r
+  Status = gSmst->SmmAllocatePool (\r
+                    EfiRuntimeServicesData,\r
+                    mVariableBufferPayloadSize,\r
+                    (VOID **)&mVariableBufferPayload\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   ///\r
   /// Register SMM variable SMI handler\r
   ///\r
   ///\r
   /// Register SMM variable SMI handler\r
   ///\r
index cdd407d66bea70b3b75dcd2ed992c916b80b8f0f..b7c7f4ffb7bde9356f39a3cce8260eafb5d96cb0 100644 (file)
@@ -52,6 +52,7 @@ EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication          = NULL;
 UINT8                           *mVariableBuffer            = NULL;\r
 UINT8                           *mVariableBufferPhysical    = NULL;\r
 UINTN                            mVariableBufferSize;\r
 UINT8                           *mVariableBuffer            = NULL;\r
 UINT8                           *mVariableBufferPhysical    = NULL;\r
 UINTN                            mVariableBufferSize;\r
+UINTN                            mVariableBufferPayloadSize;\r
 EFI_LOCK                         mVariableServicesLock;\r
 \r
 /**\r
 EFI_LOCK                         mVariableServicesLock;\r
 \r
 /**\r
@@ -205,7 +206,6 @@ RuntimeServiceGetVariable (
   EFI_STATUS                                Status;\r
   UINTN                                     PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE  *SmmVariableHeader;\r
   EFI_STATUS                                Status;\r
   UINTN                                     PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE  *SmmVariableHeader;\r
-  UINTN                                     SmmCommBufPayloadSize;\r
   UINTN                                     TempDataSize;\r
   UINTN                                     VariableNameSize;\r
 \r
   UINTN                                     TempDataSize;\r
   UINTN                                     VariableNameSize;\r
 \r
@@ -217,17 +217,13 @@ RuntimeServiceGetVariable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // SMM Communication Buffer max payload size\r
-  //\r
-  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);\r
   TempDataSize          = *DataSize;\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   //\r
   // If VariableName exceeds SMM payload limit. Return failure\r
   //\r
   TempDataSize          = *DataSize;\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   //\r
   // If VariableName exceeds SMM payload limit. Return failure\r
   //\r
-  if (VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
+  if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -237,11 +233,11 @@ RuntimeServiceGetVariable (
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
-  if (TempDataSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize) {\r
+  if (TempDataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize) {\r
     //\r
     // If output data buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
     //\r
     // If output data buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
-    TempDataSize = SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize;\r
+    TempDataSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize;\r
   }\r
   PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + TempDataSize;\r
 \r
   }\r
   PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + TempDataSize;\r
 \r
@@ -316,7 +312,6 @@ RuntimeServiceGetNextVariableName (
   EFI_STATUS                                      Status;\r
   UINTN                                           PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;\r
   EFI_STATUS                                      Status;\r
   UINTN                                           PayloadSize;\r
   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;\r
-  UINTN                                           SmmCommBufPayloadSize;\r
   UINTN                                           OutVariableNameSize;\r
   UINTN                                           InVariableNameSize;\r
 \r
   UINTN                                           OutVariableNameSize;\r
   UINTN                                           InVariableNameSize;\r
 \r
@@ -324,17 +319,13 @@ RuntimeServiceGetNextVariableName (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // SMM Communication Buffer max payload size\r
-  //\r
-  SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);\r
   OutVariableNameSize   = *VariableNameSize;\r
   InVariableNameSize    = StrSize (VariableName);\r
 \r
   //\r
   // If input string exceeds SMM payload limit. Return failure\r
   //\r
   OutVariableNameSize   = *VariableNameSize;\r
   InVariableNameSize    = StrSize (VariableName);\r
 \r
   //\r
   // If input string exceeds SMM payload limit. Return failure\r
   //\r
-  if (InVariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+  if (InVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -344,11 +335,11 @@ RuntimeServiceGetNextVariableName (
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
   // Init the communicate buffer. The buffer data size is:\r
   // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
   //\r
-  if (OutVariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+  if (OutVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
     //\r
     // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
     //\r
     // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
     //\r
-    OutVariableNameSize = SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+    OutVariableNameSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
   }\r
   //\r
   // Payload should be Guid + NameSize + MAX of Input & Output buffer\r
   }\r
   //\r
   // Payload should be Guid + NameSize + MAX of Input & Output buffer\r
@@ -448,21 +439,13 @@ RuntimeServiceSetVariable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (DataSize >= mVariableBufferSize) {\r
-    //\r
-    // DataSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to\r
-    // overflow to a small value and pass the check in InitCommunicateBuffer().\r
-    // To protect against this vulnerability, return EFI_INVALID_PARAMETER if DataSize is >= mVariableBufferSize.\r
-    // And there will be further check to ensure the total size is also not > mVariableBufferSize.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
   VariableNameSize      = StrSize (VariableName);\r
 \r
   VariableNameSize      = StrSize (VariableName);\r
 \r
-  if ((UINTN)(~0) - VariableNameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + DataSize) {\r
-    //\r
-    // Prevent PayloadSize overflow\r
-    //\r
+  //\r
+  // If VariableName or DataSize exceeds SMM payload limit. Return failure\r
+  //\r
+  if ((VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
+      (DataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize)){\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -672,10 +655,11 @@ SmmVariableReady (
   ASSERT_EFI_ERROR (Status);\r
   \r
   //\r
   ASSERT_EFI_ERROR (Status);\r
   \r
   //\r
-  // Allocate memory for variable store.\r
+  // Allocate memory for variable communicate buffer.\r
   //\r
   //\r
-  mVariableBufferSize  = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;\r
-  mVariableBufferSize += MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
+  mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +\r
+                               OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);\r
+  mVariableBufferSize  = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize;\r
   mVariableBuffer      = AllocateRuntimePool (mVariableBufferSize);\r
   ASSERT (mVariableBuffer != NULL);\r
 \r
   mVariableBuffer      = AllocateRuntimePool (mVariableBufferSize);\r
   ASSERT (mVariableBuffer != NULL);\r
 \r