]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
Use SmmMemLib to check communication buffer.
[mirror_edk2.git] / MdeModulePkg / Universal / LockBox / SmmLockBox / SmmLockBox.c
index b9c819058b717d3f37beb18cc45d81cba74ec3b9..dc8cc1df1ca9f873f3b3ca1f97ee8197365ed000 100644 (file)
@@ -1,15 +1,16 @@
 /** @file\r
-\r
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
-\r
+  LockBox SMM driver.\r
+  \r
   Caution: This module requires additional review when modified.\r
   This driver will have external input - communicate buffer in SMM mode.\r
   This external input must be validated carefully to avoid security issue like\r
   buffer overflow, integer overflow.\r
-\r
+  \r
   SmmLockBoxHandler(), SmmLockBoxRestore(), SmmLockBoxUpdate(), SmmLockBoxSave()\r
   will receive untrusted input and do basic validation.\r
 \r
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The\r
@@ -29,7 +30,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/SmmMemLib.h>\r
 #include <Library/LockBoxLib.h>\r
+\r
 #include <Protocol/SmmReadyToLock.h>\r
 #include <Protocol/SmmCommunication.h>\r
 #include <Protocol/SmmAccess2.h>\r
@@ -38,63 +41,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 BOOLEAN              mLocked = FALSE;\r
 \r
-EFI_SMRAM_DESCRIPTOR *mSmramRanges;\r
-UINTN                mSmramRangeCount;\r
-\r
-/**\r
-  This function check if the address is in SMRAM.\r
-\r
-  @param Buffer  the buffer address to be checked.\r
-  @param Length  the buffer length to be checked.\r
-\r
-  @retval TRUE  this address is in SMRAM.\r
-  @retval FALSE this address is NOT in SMRAM.\r
-**/\r
-BOOLEAN\r
-IsAddressInSmram (\r
-  IN EFI_PHYSICAL_ADDRESS  Buffer,\r
-  IN UINT64                Length\r
-  )\r
-{\r
-  UINTN  Index;\r
-\r
-  for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
-    if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||\r
-        ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  This function check if the address refered by Buffer and Length is valid.\r
-\r
-  @param Buffer  the buffer address to be checked.\r
-  @param Length  the buffer length to be checked.\r
-\r
-  @retval TRUE  this address is valid.\r
-  @retval FALSE this address is NOT valid.\r
-**/\r
-BOOLEAN\r
-IsAddressValid (\r
-  IN UINTN                 Buffer,\r
-  IN UINTN                 Length\r
-  )\r
-{\r
-  if (Buffer > (MAX_ADDRESS - Length)) {\r
-    //\r
-    // Overflow happen\r
-    //\r
-    return FALSE;\r
-  }\r
-  if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)Buffer, (UINT64)Length)) {\r
-    return FALSE;\r
-  }\r
-  return TRUE;\r
-}\r
-\r
 /**\r
   Dispatch function for SMM lock box save.\r
 \r
@@ -110,6 +56,7 @@ SmmLockBoxSave (
   )\r
 {\r
   EFI_STATUS                  Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_SAVE TempLockBoxParameterSave;\r
 \r
   //\r
   // Sanity check\r
@@ -120,11 +67,13 @@ SmmLockBoxSave (
     return ;\r
   }\r
 \r
+  CopyMem (&TempLockBoxParameterSave, LockBoxParameterSave, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE));\r
+\r
   //\r
   // Sanity check\r
   //\r
-  if (!IsAddressValid ((UINTN)LockBoxParameterSave->Buffer, (UINTN)LockBoxParameterSave->Length)) {\r
-    DEBUG ((EFI_D_ERROR, "SmmLockBox Save address in SMRAM!\n"));\r
+  if (!SmmIsBufferOutsideSmmValid ((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
   }\r
@@ -133,9 +82,9 @@ SmmLockBoxSave (
   // 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
@@ -152,6 +101,7 @@ SmmLockBoxSetAttributes (
   )\r
 {\r
   EFI_STATUS                    Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes;\r
 \r
   //\r
   // Sanity check\r
@@ -162,12 +112,14 @@ SmmLockBoxSetAttributes (
     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
-             &LockBoxParameterSetAttributes->Guid,\r
-             LockBoxParameterSetAttributes->Attributes\r
+             &TempLockBoxParameterSetAttributes.Guid,\r
+             TempLockBoxParameterSetAttributes.Attributes\r
              );\r
   LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;\r
   return ;\r
@@ -188,6 +140,7 @@ SmmLockBoxUpdate (
   )\r
 {\r
   EFI_STATUS                    Status;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_UPDATE TempLockBoxParameterUpdate;\r
 \r
   //\r
   // Sanity check\r
@@ -198,11 +151,13 @@ SmmLockBoxUpdate (
     return ;\r
   }\r
 \r
+  CopyMem (&TempLockBoxParameterUpdate, LockBoxParameterUpdate, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE));\r
+\r
   //\r
   // Sanity check\r
   //\r
-  if (!IsAddressValid ((UINTN)LockBoxParameterUpdate->Buffer, (UINTN)LockBoxParameterUpdate->Length)) {\r
-    DEBUG ((EFI_D_ERROR, "SmmLockBox Update address in SMRAM!\n"));\r
+  if (!SmmIsBufferOutsideSmmValid ((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
   }\r
@@ -211,10 +166,10 @@ SmmLockBoxUpdate (
   // 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
@@ -235,12 +190,15 @@ SmmLockBoxRestore (
   )\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
-  if (!IsAddressValid ((UINTN)LockBoxParameterRestore->Buffer, (UINTN)LockBoxParameterRestore->Length)) {\r
-    DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM!\n"));\r
+  if (!SmmIsBufferOutsideSmmValid ((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
   }\r
@@ -248,17 +206,17 @@ SmmLockBoxRestore (
   //\r
   // Restore data\r
   //\r
-  if ((LockBoxParameterRestore->Length == 0) && (LockBoxParameterRestore->Buffer == 0)) {\r
+  if ((TempLockBoxParameterRestore.Length == 0) && (TempLockBoxParameterRestore.Buffer == 0)) {\r
     Status = RestoreLockBox (\r
-               &LockBoxParameterRestore->Guid,\r
+               &TempLockBoxParameterRestore.Guid,\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
@@ -308,18 +266,28 @@ SmmLockBoxHandler (
   )\r
 {\r
   EFI_SMM_LOCK_BOX_PARAMETER_HEADER *LockBoxParameterHeader;\r
+  UINTN                             TempCommBufferSize;\r
 \r
   DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Enter\n"));\r
 \r
+  //\r
+  // If input is invalid, stop processing this SMI\r
+  //\r
+  if (CommBuffer == NULL || CommBufferSize == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  TempCommBufferSize = *CommBufferSize;\r
+\r
   //\r
   // Sanity check\r
   //\r
-  if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {\r
+  if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {\r
     DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size invalid!\n"));\r
     return EFI_SUCCESS;\r
   }\r
-  if (!IsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer in SMRAM!\n"));\r
+  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+    DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -333,35 +301,35 @@ SmmLockBoxHandler (
 \r
   switch (LockBoxParameterHeader->Command) {\r
   case EFI_SMM_LOCK_BOX_COMMAND_SAVE:\r
-    if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {\r
+    if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {\r
       DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for SAVE invalid!\n"));\r
       break;\r
     }\r
     SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)(UINTN)LockBoxParameterHeader);\r
     break;\r
   case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:\r
-    if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {\r
+    if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {\r
       DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for UPDATE invalid!\n"));\r
       break;\r
     }\r
     SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)LockBoxParameterHeader);\r
     break;\r
   case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:\r
-    if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {\r
+    if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {\r
       DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for RESTORE invalid!\n"));\r
       break;\r
     }\r
     SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)(UINTN)LockBoxParameterHeader);\r
     break;\r
   case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:\r
-    if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {\r
+    if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {\r
       DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for SET_ATTRIBUTES invalid!\n"));\r
       break;\r
     }\r
     SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)(UINTN)LockBoxParameterHeader);\r
     break;\r
   case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:\r
-    if (*CommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {\r
+    if (TempCommBufferSize < sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {\r
       DEBUG ((EFI_D_ERROR, "SmmLockBox Command Buffer Size for RESTORE_ALL_IN_PLACE invalid!\n"));\r
       break;\r
     }\r
@@ -421,30 +389,6 @@ SmmLockBoxEntryPoint (
   EFI_STATUS                    Status;\r
   EFI_HANDLE                    DispatchHandle;\r
   VOID                          *Registration;\r
-  EFI_SMM_ACCESS2_PROTOCOL      *SmmAccess;\r
-  UINTN                         Size;\r
-\r
-  //\r
-  // Get SMRAM information\r
-  //\r
-  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Size = 0;\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-  Status = gSmst->SmmAllocatePool (\r
-                    EfiRuntimeServicesData,\r
-                    Size,\r
-                    (VOID **)&mSmramRanges\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
 \r
   //\r
   // Register LockBox communication handler\r