]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c
MdeModulePkg: Change TCG MOR variables to use VariablePolicy
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / TcgMorLockDxe.c
index c32eb3b1ac4b07e63b529437b6e082d6f979068f..b85f08c48c1130eca8191367fc7aee68eb599cbf 100644 (file)
@@ -5,13 +5,8 @@
   MOR lock control unsupported.\r
 \r
 Copyright (c) 2016, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -23,24 +18,27 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/BaseMemoryLib.h>\r
 #include "Variable.h"\r
 \r
-extern EDKII_VARIABLE_LOCK_PROTOCOL     mVariableLock;\r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyHelperLib.h>\r
 \r
 /**\r
   This service is an MOR/MorLock checker handler for the SetVariable().\r
 \r
-  @param  VariableName the name of the vendor's variable, as a\r
-                       Null-Terminated Unicode String\r
-  @param  VendorGuid   Unify identifier for vendor.\r
-  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
-                       is NULL, the parameter would be ignored.\r
-  @param  DataSize     The size in bytes of Data-Buffer.\r
-  @param  Data         Point to the content of the variable.\r
+  @param[in]  VariableName the name of the vendor's variable, as a\r
+                           Null-Terminated Unicode String\r
+  @param[in]  VendorGuid   Unify identifier for vendor.\r
+  @param[in]  Attributes   Attributes bitmask to set for the variable.\r
+  @param[in]  DataSize     The size in bytes of Data-Buffer.\r
+  @param[in]  Data         Point to the content of the variable.\r
 \r
-  @retval  EFI_SUCCESS            The MOR/MorLock check pass, and Variable driver can store the variable data.\r
-  @retval  EFI_INVALID_PARAMETER  The MOR/MorLock data or data size or attributes is not allowed for MOR variable.\r
+  @retval  EFI_SUCCESS            The MOR/MorLock check pass, and Variable\r
+                                  driver can store the variable data.\r
+  @retval  EFI_INVALID_PARAMETER  The MOR/MorLock data or data size or\r
+                                  attributes is not allowed for MOR variable.\r
   @retval  EFI_ACCESS_DENIED      The MOR/MorLock is locked.\r
-  @retval  EFI_ALREADY_STARTED    The MorLock variable is handled inside this function.\r
-                                  Variable driver can just return EFI_SUCCESS.\r
+  @retval  EFI_ALREADY_STARTED    The MorLock variable is handled inside this\r
+                                  function. Variable driver can just return\r
+                                  EFI_SUCCESS.\r
 **/\r
 EFI_STATUS\r
 SetVariableCheckHandlerMor (\r
@@ -58,9 +56,9 @@ SetVariableCheckHandlerMor (
 }\r
 \r
 /**\r
-  Initialization for MOR Lock Control.\r
+  Initialization for MOR Control Lock.\r
 \r
-  @retval EFI_SUCEESS     MorLock initialization success.\r
+  @retval EFI_SUCCESS     MorLock initialization success.\r
   @return Others          Some error occurs.\r
 **/\r
 EFI_STATUS\r
@@ -76,14 +74,75 @@ MorLockInit (
   VariableServiceSetVariable (\r
     MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,\r
     &gEfiMemoryOverwriteRequestControlLockGuid,\r
-    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-    0,\r
-    NULL\r
+    0,                                          // Attributes\r
+    0,                                          // DataSize\r
+    NULL                                        // Data\r
     );\r
 \r
   //\r
-  // Need set this variable to be read-only to prevent other module set it.\r
+  // The MOR variable can effectively improve platform security only when the\r
+  // MorLock variable protects the MOR variable. In turn MorLock cannot be made\r
+  // secure without SMM support in the platform firmware (see above).\r
+  //\r
+  // Thus, delete the MOR variable, should it exist for any reason (some OSes\r
+  // are known to create MOR unintentionally, in an attempt to set it), then\r
+  // also lock the MOR variable, in order to prevent other modules from\r
+  // creating it.\r
   //\r
-  VariableLockRequestToLock (&mVariableLock, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, &gEfiMemoryOverwriteRequestControlLockGuid);\r
+  VariableServiceSetVariable (\r
+    MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+    &gEfiMemoryOverwriteControlDataGuid,\r
+    0,                                      // Attributes\r
+    0,                                      // DataSize\r
+    NULL                                    // Data\r
+    );\r
+\r
   return EFI_SUCCESS;\r
 }\r
+\r
+/**\r
+  Delayed initialization for MOR Control Lock at EndOfDxe.\r
+\r
+  This function performs any operations queued by MorLockInit().\r
+**/\r
+VOID\r
+MorLockInitAtEndOfDxe (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EDKII_VARIABLE_POLICY_PROTOCOL    *VariablePolicy;\r
+\r
+  // First, we obviously need to locate the VariablePolicy protocol.\r
+  Status = gBS->LocateProtocol( &gEdkiiVariablePolicyProtocolGuid, NULL, (VOID**)&VariablePolicy );\r
+  if (EFI_ERROR( Status )) {\r
+    DEBUG(( DEBUG_ERROR, "%a - Could not locate VariablePolicy protocol! %r\n", __FUNCTION__, Status ));\r
+    return;\r
+  }\r
+\r
+  // If we're successful, go ahead and set the policies to protect the target variables.\r
+  Status = RegisterBasicVariablePolicy( VariablePolicy,\r
+                                        &gEfiMemoryOverwriteRequestControlLockGuid,\r
+                                        MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,\r
+                                        VARIABLE_POLICY_NO_MIN_SIZE,\r
+                                        VARIABLE_POLICY_NO_MAX_SIZE,\r
+                                        VARIABLE_POLICY_NO_MUST_ATTR,\r
+                                        VARIABLE_POLICY_NO_CANT_ATTR,\r
+                                        VARIABLE_POLICY_TYPE_LOCK_NOW );\r
+  if (EFI_ERROR( Status )) {\r
+    DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTION__, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, Status ));\r
+  }\r
+  Status = RegisterBasicVariablePolicy( VariablePolicy,\r
+                                        &gEfiMemoryOverwriteControlDataGuid,\r
+                                        MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+                                        VARIABLE_POLICY_NO_MIN_SIZE,\r
+                                        VARIABLE_POLICY_NO_MAX_SIZE,\r
+                                        VARIABLE_POLICY_NO_MUST_ATTR,\r
+                                        VARIABLE_POLICY_NO_CANT_ATTR,\r
+                                        VARIABLE_POLICY_TYPE_LOCK_NOW );\r
+  if (EFI_ERROR( Status )) {\r
+    DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTION__, MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, Status ));\r
+  }\r
+\r
+  return;\r
+}\r