]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
Security enhancement to SMM Base thunk drivers: Framework SMM drivers can't be loaded...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / SmmBaseHelper / SmmBaseHelper.c
index 033d93eff8d3a79792b3f1a3cb908a80446c22d6..e7976b9c0c795285aae357d22dd53c642e912dc1 100644 (file)
@@ -32,6 +32,7 @@
 #include <Protocol/SmmCpuSaveState.h>\r
 #include <Protocol/MpService.h>\r
 #include <Protocol/LoadPe32Image.h>\r
+#include <Protocol/SmmReadyToLock.h>\r
 \r
 ///\r
 /// Structure for tracking paired information of registered Framework SMI handler\r
@@ -67,6 +68,7 @@ EFI_GUID                           mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
 EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;\r
 EFI_SMM_SYSTEM_TABLE               *mFrameworkSmst;\r
 UINTN                              mNumberOfProcessors;\r
+BOOLEAN                            mLocked = FALSE;\r
 \r
 LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);\r
 \r
@@ -272,7 +274,7 @@ Register (
 {\r
   EFI_STATUS Status;\r
 \r
-  if (FunctionData->Args.Register.LegacyIA32Binary) {\r
+  if (mLocked || FunctionData->Args.Register.LegacyIA32Binary) {\r
     Status = EFI_UNSUPPORTED;\r
   } else {\r
     Status = LoadImage (\r
@@ -463,6 +465,11 @@ RegisterCallback (
 {\r
   CALLBACK_INFO  *Buffer;\r
 \r
+  if (mLocked) {\r
+    FunctionData->Status = EFI_UNSUPPORTED;\r
+    return;\r
+  }\r
+\r
   ///\r
   /// Note that MakeLast and FloatingPointSave options are not supported in PI SMM\r
   ///\r
@@ -512,11 +519,15 @@ HelperAllocatePool (
   IN OUT SMMBASE_FUNCTION_DATA *FunctionData\r
   )\r
 {\r
-  FunctionData->Status = gSmst->SmmAllocatePool (\r
-                                  FunctionData->Args.AllocatePool.PoolType,\r
-                                  FunctionData->Args.AllocatePool.Size,\r
-                                  FunctionData->Args.AllocatePool.Buffer\r
-                                  );\r
+  if (mLocked) {\r
+    FunctionData->Status =  EFI_UNSUPPORTED;\r
+  } else {\r
+    FunctionData->Status = gSmst->SmmAllocatePool (\r
+                                    FunctionData->Args.AllocatePool.PoolType,\r
+                                    FunctionData->Args.AllocatePool.Size,\r
+                                    FunctionData->Args.AllocatePool.Buffer\r
+                                    );\r
+  }\r
 }\r
 \r
 /** \r
@@ -529,8 +540,12 @@ HelperFreePool (
   IN OUT SMMBASE_FUNCTION_DATA *FunctionData\r
   )\r
 {\r
-  FreePool (FunctionData->Args.FreePool.Buffer);\r
-  FunctionData->Status = EFI_SUCCESS;\r
+  if (mLocked) {\r
+    FunctionData->Status =  EFI_UNSUPPORTED;\r
+  } else {\r
+    FreePool (FunctionData->Args.FreePool.Buffer);\r
+    FunctionData->Status = EFI_SUCCESS;\r
+  }\r
 }\r
 \r
 /** \r
@@ -633,6 +648,29 @@ SmmHandlerEntry (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Smm Ready To Lock event notification handler.\r
+\r
+  It sets a flag indicating that SMRAM has been locked.\r
+  \r
+  @param[in] Protocol   Points to the protocol's unique identifier.\r
+  @param[in] Interface  Points to the interface instance.\r
+  @param[in] Handle     The handle on which the interface was installed.\r
+\r
+  @retval EFI_SUCCESS   Notification handler runs successfully.\r
+ **/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmReadyToLockEventNotify (\r
+  IN CONST EFI_GUID  *Protocol,\r
+  IN VOID            *Interface,\r
+  IN EFI_HANDLE      Handle\r
+  )\r
+{\r
+  mLocked = TRUE;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Entry point function of the SMM Base Helper SMM driver.\r
 \r
@@ -653,6 +691,7 @@ SmmBaseHelperMain (
   EFI_MP_SERVICES_PROTOCOL   *MpServices;\r
   EFI_HANDLE                 Handle;\r
   UINTN                      NumberOfEnabledProcessors;\r
+  VOID                       *Registration;\r
   \r
   Handle = NULL;\r
   ///\r
@@ -697,6 +736,16 @@ SmmBaseHelperMain (
   mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;\r
   mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;\r
 \r
+  //\r
+  // Register SMM Ready To Lock Protocol notification\r
+  //\r
+  Status = gSmst->SmmRegisterProtocolNotify (\r
+                    &gEfiSmmReadyToLockProtocolGuid,\r
+                    SmmReadyToLockEventNotify,\r
+                    &Registration\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   ///\r
   /// Register SMM Base Helper services for SMM Base Thunk driver\r
   ///\r