]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Define the VarCheckPolicyLib and SMM interface
authorBret Barkelew <brbarkel@microsoft.com>
Mon, 9 Nov 2020 06:45:13 +0000 (14:45 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 17 Nov 2020 01:03:43 +0000 (01:03 +0000)
https://bugzilla.tianocore.org/show_bug.cgi?id=2522

VariablePolicy is an updated interface to
replace VarLock and VarCheckProtocol.

This is an instance of a VarCheckLib that is backed by the
VariablePolicyLib business logic. It also publishes the SMM
calling interface for messages from the DXE protocol.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Bret Barkelew <brbarkel@microsoft.com>
Signed-off-by: Bret Barkelew <brbarkel@microsoft.com>
Reviewed-by: Dandan Bi <dandan.bi@intel.com>
Acked-by: Jian J Wang <jian.j.wang@intel.com>
MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h [new file with mode: 0644]
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c [new file with mode: 0644]
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf [new file with mode: 0644]
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
new file mode 100644 (file)
index 0000000..77bcc62
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file -- VarCheckPolicyMmiCommon.h\r
+This header contains communication definitions that are shared between DXE\r
+and the MM component of VarCheckPolicy.\r
+\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#ifndef _VAR_CHECK_POLICY_MMI_COMMON_H_\r
+#define _VAR_CHECK_POLICY_MMI_COMMON_H_\r
+\r
+#define   VAR_CHECK_POLICY_COMM_SIG       SIGNATURE_32('V', 'C', 'P', 'C')\r
+#define   VAR_CHECK_POLICY_COMM_REVISION  1\r
+\r
+#pragma pack(push, 1)\r
+\r
+typedef struct _VAR_CHECK_POLICY_COMM_HEADER {\r
+  UINT32      Signature;\r
+  UINT32      Revision;\r
+  UINT32      Command;\r
+  EFI_STATUS  Result;\r
+} VAR_CHECK_POLICY_COMM_HEADER;\r
+\r
+typedef struct _VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS {\r
+  BOOLEAN     State;\r
+} VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS;\r
+\r
+typedef struct _VAR_CHECK_POLICY_COMM_DUMP_PARAMS {\r
+  UINT32      PageRequested;\r
+  UINT32      TotalSize;\r
+  UINT32      PageSize;\r
+  BOOLEAN     HasMore;\r
+} VAR_CHECK_POLICY_COMM_DUMP_PARAMS;\r
+\r
+#pragma pack(pop)\r
+\r
+// Make sure that we will hold at least the headers.\r
+#define   VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE  MAX((OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + sizeof (VAR_CHECK_POLICY_COMM_HEADER) + EFI_PAGES_TO_SIZE(1)), EFI_PAGES_TO_SIZE(4))\r
+#define   VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE  (VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE - \\r
+                                                    (OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + \\r
+                                                      sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \\r
+                                                      sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS)))\r
+STATIC_ASSERT (\r
+  VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE,\r
+  "an integer underflow may have occurred calculating VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE"\r
+  );\r
+\r
+#define   VAR_CHECK_POLICY_COMMAND_DISABLE      0x0001\r
+#define   VAR_CHECK_POLICY_COMMAND_IS_ENABLED   0x0002\r
+#define   VAR_CHECK_POLICY_COMMAND_REGISTER     0x0003\r
+#define   VAR_CHECK_POLICY_COMMAND_DUMP         0x0004\r
+#define   VAR_CHECK_POLICY_COMMAND_LOCK         0x0005\r
+\r
+#endif // _VAR_CHECK_POLICY_MMI_COMMON_H_\r
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
new file mode 100644 (file)
index 0000000..257aa95
--- /dev/null
@@ -0,0 +1,346 @@
+/** @file -- VarCheckPolicyLib.c\r
+This is a NULL library instance that leverages the VarCheck interface\r
+and the business logic behind the VariablePolicy code to make its decisions.\r
+\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/VarCheckLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/SafeIntLib.h>\r
+#include <Library/MmServicesTableLib.h>\r
+#include <Library/SmmMemLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include <Protocol/MmCommunication.h>\r
+\r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyLib.h>\r
+\r
+#include <Guid/VarCheckPolicyMmi.h>\r
+\r
+//================================================\r
+// As a VarCheck library, we're linked into the VariableServices\r
+// and may not be able to call them indirectly. To get around this,\r
+// use the internal GetVariable function to query the variable store.\r
+//================================================\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceGetVariable (\r
+  IN      CHAR16            *VariableName,\r
+  IN      EFI_GUID          *VendorGuid,\r
+  OUT     UINT32            *Attributes OPTIONAL,\r
+  IN OUT  UINTN             *DataSize,\r
+  OUT     VOID              *Data\r
+  );\r
+\r
+\r
+UINT8     mSecurityEvalBuffer[VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE];\r
+\r
+// Pagination Cache Variables\r
+UINT8       *mPaginationCache = NULL;\r
+UINTN       mPaginationCacheSize = 0;\r
+UINT32      mCurrentPaginationCommand = 0;\r
+\r
+\r
+/**\r
+  MM Communication Handler to recieve commands from the DXE protocol for\r
+  Variable Policies. This communication channel is used to register new policies\r
+  and poll and toggle the enforcement of variable policies.\r
+\r
+  @param[in]      DispatchHandle      All parameters standard to MM communications convention.\r
+  @param[in]      RegisterContext     All parameters standard to MM communications convention.\r
+  @param[in,out]  CommBuffer          All parameters standard to MM communications convention.\r
+  @param[in,out]  CommBufferSize      All parameters standard to MM communications convention.\r
+\r
+  @retval     EFI_SUCCESS\r
+  @retval     EFI_INVALID_PARAMETER   CommBuffer or CommBufferSize is null pointer.\r
+  @retval     EFI_INVALID_PARAMETER   CommBuffer size is wrong.\r
+  @retval     EFI_INVALID_PARAMETER   Revision or signature don't match.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+VarCheckPolicyLibMmiHandler (\r
+  IN     EFI_HANDLE                   DispatchHandle,\r
+  IN     CONST VOID                   *RegisterContext,\r
+  IN OUT VOID                         *CommBuffer,\r
+  IN OUT UINTN                        *CommBufferSize\r
+  )\r
+{\r
+  UINTN                                     InternalCommBufferSize;\r
+  VOID                                      *InternalCommBuffer;\r
+  EFI_STATUS                                Status;\r
+  EFI_STATUS                                SubCommandStatus;\r
+  VAR_CHECK_POLICY_COMM_HEADER              *PolicyCommmHeader;\r
+  VAR_CHECK_POLICY_COMM_HEADER              *InternalPolicyCommmHeader;\r
+  VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS   *IsEnabledParams;\r
+  VAR_CHECK_POLICY_COMM_DUMP_PARAMS         *DumpParamsIn;\r
+  VAR_CHECK_POLICY_COMM_DUMP_PARAMS         *DumpParamsOut;\r
+  UINT8                                     *DumpInputBuffer;\r
+  UINT8                                     *DumpOutputBuffer;\r
+  UINTN                                     DumpTotalPages;\r
+  VARIABLE_POLICY_ENTRY                     *PolicyEntry;\r
+  UINTN                                     ExpectedSize;\r
+  UINT32                                    TempSize;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Validate some input parameters.\r
+  //\r
+  // If either of the pointers are NULL, we can't proceed.\r
+  if (CommBuffer == NULL || CommBufferSize == NULL) {\r
+    DEBUG(( DEBUG_INFO, "%a - Invalid comm buffer pointers!\n", __FUNCTION__ ));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  // Make sure that the buffer does not overlap SMM.\r
+  // This should be covered by the SmiManage infrastructure, but just to be safe...\r
+  InternalCommBufferSize = *CommBufferSize;\r
+  if (InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE || !SmmIsBufferOutsideSmmValid((UINTN)CommBuffer, (UINT64)InternalCommBufferSize)) {\r
+    DEBUG ((DEBUG_ERROR, "%a - Invalid CommBuffer supplied! 0x%016lX[0x%016lX]\n", __FUNCTION__, CommBuffer, InternalCommBufferSize));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  // If the size does not meet a minimum threshold, we cannot proceed.\r
+  ExpectedSize = sizeof(VAR_CHECK_POLICY_COMM_HEADER);\r
+  if (InternalCommBufferSize < ExpectedSize) {\r
+    DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, InternalCommBufferSize, ExpectedSize ));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Before proceeding any further, copy the buffer internally so that we can compare\r
+  // without worrying about TOCTOU.\r
+  //\r
+  InternalCommBuffer = &mSecurityEvalBuffer[0];\r
+  CopyMem(InternalCommBuffer, CommBuffer, InternalCommBufferSize);\r
+  PolicyCommmHeader = CommBuffer;\r
+  InternalPolicyCommmHeader = InternalCommBuffer;\r
+  // Check the revision and the signature of the comm header.\r
+  if (InternalPolicyCommmHeader->Signature != VAR_CHECK_POLICY_COMM_SIG ||\r
+      InternalPolicyCommmHeader->Revision != VAR_CHECK_POLICY_COMM_REVISION) {\r
+    DEBUG(( DEBUG_INFO, "%a - Signature or revision are incorrect!\n", __FUNCTION__ ));\r
+    // We have verified the buffer is not null and have enough size to hold Result field.\r
+    PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  // If we're in the middle of a paginated dump and any other command is sent,\r
+  // pagination cache must be cleared.\r
+  if (mPaginationCache != NULL && InternalPolicyCommmHeader->Command != mCurrentPaginationCommand) {\r
+    FreePool (mPaginationCache);\r
+    mPaginationCache = NULL;\r
+    mPaginationCacheSize = 0;\r
+    mCurrentPaginationCommand = 0;\r
+  }\r
+\r
+  //\r
+  // Now we can process the command as it was sent.\r
+  //\r
+  PolicyCommmHeader->Result = EFI_ABORTED;    // Set a default return for incomplete commands.\r
+  switch(InternalPolicyCommmHeader->Command) {\r
+    case VAR_CHECK_POLICY_COMMAND_DISABLE:\r
+      PolicyCommmHeader->Result = DisableVariablePolicy();\r
+      break;\r
+\r
+    case VAR_CHECK_POLICY_COMMAND_IS_ENABLED:\r
+      // Make sure that we're dealing with a reasonable size.\r
+      // This add should be safe because these are fixed sizes so far.\r
+      ExpectedSize += sizeof(VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS);\r
+      if (InternalCommBufferSize < ExpectedSize) {\r
+        DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, InternalCommBufferSize, ExpectedSize ));\r
+        PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;\r
+        break;\r
+      }\r
+\r
+      // Now that we know we've got a valid size, we can fill in the rest of the data.\r
+      IsEnabledParams = (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)((UINT8*)CommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER));\r
+      IsEnabledParams->State = IsVariablePolicyEnabled();\r
+      PolicyCommmHeader->Result = EFI_SUCCESS;\r
+      break;\r
+\r
+    case VAR_CHECK_POLICY_COMMAND_REGISTER:\r
+      // Make sure that we're dealing with a reasonable size.\r
+      // This add should be safe because these are fixed sizes so far.\r
+      ExpectedSize += sizeof(VARIABLE_POLICY_ENTRY);\r
+      if (InternalCommBufferSize < ExpectedSize) {\r
+        DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, InternalCommBufferSize, ExpectedSize ));\r
+        PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;\r
+        break;\r
+      }\r
+\r
+      // At the very least, we can assume that we're working with a valid policy entry.\r
+      // Time to compare its internal size.\r
+      PolicyEntry = (VARIABLE_POLICY_ENTRY*)((UINT8*)InternalCommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER));\r
+      if (PolicyEntry->Version != VARIABLE_POLICY_ENTRY_REVISION ||\r
+          PolicyEntry->Size < sizeof(VARIABLE_POLICY_ENTRY) ||\r
+          EFI_ERROR(SafeUintnAdd(sizeof(VAR_CHECK_POLICY_COMM_HEADER), PolicyEntry->Size, &ExpectedSize)) ||\r
+          InternalCommBufferSize < ExpectedSize) {\r
+        DEBUG(( DEBUG_INFO, "%a - Bad policy entry contents!\n", __FUNCTION__ ));\r
+        PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;\r
+        break;\r
+      }\r
+\r
+      PolicyCommmHeader->Result = RegisterVariablePolicy( PolicyEntry );\r
+      break;\r
+\r
+    case VAR_CHECK_POLICY_COMMAND_DUMP:\r
+      // Make sure that we're dealing with a reasonable size.\r
+      // This add should be safe because these are fixed sizes so far.\r
+      ExpectedSize += sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS) + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;\r
+      if (InternalCommBufferSize < ExpectedSize) {\r
+        DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, InternalCommBufferSize, ExpectedSize ));\r
+        PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;\r
+        break;\r
+      }\r
+\r
+      // Now that we know we've got a valid size, we can fill in the rest of the data.\r
+      DumpParamsIn = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(InternalPolicyCommmHeader + 1);\r
+      DumpParamsOut = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyCommmHeader + 1);\r
+\r
+      // If we're requesting the first page, initialize the cache and get the sizes.\r
+      if (DumpParamsIn->PageRequested == 0) {\r
+        if (mPaginationCache != NULL) {\r
+          FreePool (mPaginationCache);\r
+          mPaginationCache = NULL;\r
+        }\r
+\r
+        // Determine what the required size is going to be.\r
+        DumpParamsOut->TotalSize = 0;\r
+        DumpParamsOut->PageSize = 0;\r
+        DumpParamsOut->HasMore = FALSE;\r
+        SubCommandStatus = DumpVariablePolicy (NULL, &TempSize);\r
+        if (SubCommandStatus == EFI_BUFFER_TOO_SMALL && TempSize > 0) {\r
+          mCurrentPaginationCommand = VAR_CHECK_POLICY_COMMAND_DUMP;\r
+          mPaginationCacheSize = TempSize;\r
+          DumpParamsOut->TotalSize = TempSize;\r
+          mPaginationCache = AllocatePool (mPaginationCacheSize);\r
+          if (mPaginationCache == NULL) {\r
+            SubCommandStatus = EFI_OUT_OF_RESOURCES;\r
+          }\r
+        }\r
+\r
+        // If we've allocated our pagination cache, we're good to cache.\r
+        if (mPaginationCache != NULL) {\r
+          SubCommandStatus = DumpVariablePolicy (mPaginationCache, &TempSize);\r
+        }\r
+\r
+        // Populate the remaining fields and we can boogie.\r
+        if (!EFI_ERROR (SubCommandStatus) && mPaginationCache != NULL) {\r
+          DumpParamsOut->HasMore = TRUE;\r
+        }\r
+      } else if (mPaginationCache != NULL) {\r
+        DumpParamsOut->TotalSize = (UINT32)mPaginationCacheSize;\r
+        DumpOutputBuffer = (UINT8*)(DumpParamsOut + 1);\r
+\r
+        // Make sure that we don't over-index the cache.\r
+        DumpTotalPages = mPaginationCacheSize / VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;\r
+        if (mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE != 0) {\r
+          DumpTotalPages++;\r
+        }\r
+        if (DumpParamsIn->PageRequested > DumpTotalPages) {\r
+          SubCommandStatus = EFI_INVALID_PARAMETER;\r
+        } else {\r
+          // Figure out how far into the page cache we need to go for our next page.\r
+          // We know the blind subtraction won't be bad because we already checked for page 0.\r
+          DumpInputBuffer = &mPaginationCache[VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE * (DumpParamsIn->PageRequested - 1)];\r
+          TempSize = VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;\r
+          // If we're getting the last page, adjust the PageSize.\r
+          if (DumpParamsIn->PageRequested == DumpTotalPages) {\r
+            TempSize = mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;\r
+          }\r
+          CopyMem (DumpOutputBuffer, DumpInputBuffer, TempSize);\r
+          DumpParamsOut->PageSize = TempSize;\r
+          // If we just got the last page, settle up the cache.\r
+          if (DumpParamsIn->PageRequested == DumpTotalPages) {\r
+            DumpParamsOut->HasMore = FALSE;\r
+            FreePool (mPaginationCache);\r
+            mPaginationCache = NULL;\r
+            mPaginationCacheSize = 0;\r
+            mCurrentPaginationCommand = 0;\r
+          // Otherwise, we could do more here.\r
+          } else {\r
+            DumpParamsOut->HasMore = TRUE;\r
+          }\r
+\r
+          // If we made it this far, we're basically good.\r
+          SubCommandStatus = EFI_SUCCESS;\r
+        }\r
+      // If we've requested any other page than 0 and the cache is empty, we must have timed out.\r
+      } else {\r
+        DumpParamsOut->TotalSize = 0;\r
+        DumpParamsOut->PageSize = 0;\r
+        DumpParamsOut->HasMore = FALSE;\r
+        SubCommandStatus = EFI_TIMEOUT;\r
+      }\r
+\r
+      // There's currently no use for this, but it shouldn't be hard to implement.\r
+      PolicyCommmHeader->Result = SubCommandStatus;\r
+      break;\r
+\r
+    case VAR_CHECK_POLICY_COMMAND_LOCK:\r
+      PolicyCommmHeader->Result = LockVariablePolicy();\r
+      break;\r
+\r
+    default:\r
+      // Mark unknown requested command as EFI_UNSUPPORTED.\r
+      DEBUG(( DEBUG_INFO, "%a - Invalid command requested! %d\n", __FUNCTION__, PolicyCommmHeader->Command ));\r
+      PolicyCommmHeader->Result = EFI_UNSUPPORTED;\r
+      break;\r
+  }\r
+\r
+  DEBUG(( DEBUG_VERBOSE, "%a - Command %d returning %r.\n", __FUNCTION__,\r
+          PolicyCommmHeader->Command, PolicyCommmHeader->Result ));\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Constructor function of VarCheckPolicyLib to register VarCheck handler and\r
+  SW MMI handlers.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS       The constructor executed correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VarCheckPolicyLibConstructor (\r
+  IN EFI_HANDLE             ImageHandle,\r
+  IN EFI_SYSTEM_TABLE       *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_HANDLE    DiscardedHandle;\r
+\r
+  // Initialize the business logic with the internal GetVariable handler.\r
+  Status = InitVariablePolicyLib( VariableServiceGetVariable );\r
+\r
+  // Only proceed with init if the business logic could be initialized.\r
+  if (!EFI_ERROR( Status )) {\r
+    // Register the VarCheck handler for SetVariable filtering.\r
+    // Forward the check to the business logic of the library.\r
+    VarCheckLibRegisterSetVariableCheckHandler( ValidateSetVariable );\r
+\r
+    // Register the MMI handlers for receiving policy commands.\r
+    DiscardedHandle = NULL;\r
+    Status = gMmst->MmiHandlerRegister( VarCheckPolicyLibMmiHandler,\r
+                                        &gVarCheckPolicyLibMmiHandlerGuid,\r
+                                        &DiscardedHandle );\r
+  }\r
+  // Otherwise, there's not much we can do.\r
+  else {\r
+    DEBUG(( DEBUG_ERROR, "%a - Cannot Initialize VariablePolicyLib! %r\n", __FUNCTION__, Status ));\r
+    ASSERT_EFI_ERROR( Status );\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
new file mode 100644 (file)
index 0000000..077bcc8
--- /dev/null
@@ -0,0 +1,42 @@
+## @file VarCheckPolicyLib.inf\r
+# This is an instance of a VarCheck lib that leverages the business logic behind\r
+# the VariablePolicy code to make its decisions.\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = VarCheckPolicyLib\r
+  FILE_GUID                      = 9C28A48F-C884-4B1F-8B95-DEF125448023\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER\r
+  CONSTRUCTOR                    = VarCheckPolicyLibConstructor\r
+\r
+\r
+[Sources]\r
+  VarCheckPolicyLib.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  DebugLib\r
+  BaseMemoryLib\r
+  DxeServicesLib\r
+  MemoryAllocationLib\r
+  VarCheckLib\r
+  VariablePolicyLib\r
+  VariablePolicyHelperLib\r
+  SafeIntLib\r
+  MmServicesTableLib\r
+\r
+\r
+[Guids]\r
+  gVarCheckPolicyLibMmiHandlerGuid        ## CONSUME ## Used to register for MM Communication events.\r
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni
new file mode 100644 (file)
index 0000000..eedeeed
--- /dev/null
@@ -0,0 +1,12 @@
+// /** @file\r
+// VarCheckPolicyLib.uni\r
+//\r
+// Copyright (c) Microsoft Corporation.\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT             #language en-US "NULL library implementation that conforms to the VarCheck interface to allow VariablePolicy engine to enforce policies"\r
+\r
+#string STR_MODULE_DESCRIPTION          #language en-US "NULL library implementation that conforms to the VarCheck interface to allow VariablePolicy engine to enforce policies"\r
index 51f7f9d7246ad585a012dc9c952cc81155cf8f99..00075528198d08d47b058e4515f77acdee9be888 100644 (file)
   ## Include/Guid/EndofS3Resume.h\r
   gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }\r
 \r
+  ## Used (similar to Variable Services) to communicate policies to the enforcement engine.\r
+  # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}\r
+  gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}\r
+\r
   ## Include/Guid/S3SmmInitDone.h\r
   gEdkiiS3SmmInitDoneGuid = { 0x8f9d4825, 0x797d, 0x48fc, { 0x84, 0x71, 0x84, 0x50, 0x25, 0x79, 0x2e, 0xf6 } }\r
 \r
index 9065509290028930b4bd96061cf4c945468897df..90165ca443bfc9953aead7315374c4884f90d65d 100644 (file)
   MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf\r
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf\r
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf\r
+  MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf\r
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf\r
   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf\r
   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf\r
   MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf\r
   MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {\r
     <LibraryClasses>\r
+      NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf\r
       NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf\r
       NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf\r
       NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf\r