]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
MdeModulePkg/Variable: Parameterize GetNextVariableInternal () stores
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / TcgMorLockSmm.c
index faeaabb224afc6fa9214fdc34191e94fce2ee864..6d80eb64341a487561bad771cdef809b272fd72b 100644 (file)
@@ -4,14 +4,8 @@
   This module initilizes MemoryOverwriteRequestControlLock variable.\r
   This module adds Variable Hook and check MemoryOverwriteRequestControlLock.\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) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -33,6 +27,8 @@ VARIABLE_TYPE  mMorVariableType[] = {
   {MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,  &gEfiMemoryOverwriteRequestControlLockGuid},\r
 };\r
 \r
+BOOLEAN         mMorPassThru = FALSE;\r
+\r
 #define MOR_LOCK_DATA_UNLOCKED           0x0\r
 #define MOR_LOCK_DATA_LOCKED_WITHOUT_KEY 0x1\r
 #define MOR_LOCK_DATA_LOCKED_WITH_KEY    0x2\r
@@ -113,7 +109,7 @@ IsMorLockVariable (
   @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.\r
   @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.\r
   @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.\r
-  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
                                   set but the AuthInfo does NOT pass the validation check carried\r
                                   out by the firmware.\r
   @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.\r
@@ -362,6 +358,13 @@ SetVariableCheckHandlerMor (
   // Mor Variable\r
   //\r
 \r
+  //\r
+  // Permit deletion for passthru request.\r
+  //\r
+  if (((Attributes == 0) || (DataSize == 0)) && mMorPassThru) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   // Basic Check\r
   //\r
@@ -437,17 +440,59 @@ MorLockInitAtEndOfDxe (
 \r
   if (MorStatus == EFI_BUFFER_TOO_SMALL) {\r
     //\r
-    // The MOR variable exists; set the MOR Control Lock variable to report the\r
-    // capability to the OS.\r
+    // The MOR variable exists.\r
     //\r
-    SetMorLockVariable (0);\r
-    return;\r
+    // Some OSes don't follow the TCG's Platform Reset Attack Mitigation spec\r
+    // in that the OS should never create the MOR variable, only read and write\r
+    // it -- these OSes (unintentionally) create MOR if the platform firmware\r
+    // does not produce it. Whether this is the case (from the last OS boot)\r
+    // can be deduced from the absence of the TCG / TCG2 protocols, as edk2's\r
+    // MOR implementation depends on (one of) those protocols.\r
+    //\r
+    if (VariableHaveTcgProtocols ()) {\r
+      //\r
+      // The MOR variable originates from the platform firmware; set the MOR\r
+      // Control Lock variable to report the locking capability to the OS.\r
+      //\r
+      SetMorLockVariable (0);\r
+      return;\r
+    }\r
+\r
+    //\r
+    // The MOR variable's origin is inexplicable; delete it.\r
+    //\r
+    DEBUG ((\r
+      DEBUG_WARN,\r
+      "%a: deleting unexpected / unsupported variable %g:%s\n",\r
+      __FUNCTION__,\r
+      &gEfiMemoryOverwriteControlDataGuid,\r
+      MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME\r
+      ));\r
+\r
+    mMorPassThru = TRUE;\r
+    VariableServiceSetVariable (\r
+      MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+      &gEfiMemoryOverwriteControlDataGuid,\r
+      0,                                      // Attributes\r
+      0,                                      // DataSize\r
+      NULL                                    // Data\r
+      );\r
+    mMorPassThru = FALSE;\r
   }\r
 \r
   //\r
-  // The platform does not support the MOR variable. Delete the MOR Control\r
-  // Lock variable (should it exists for some reason) and prevent other modules\r
-  // from creating it.\r
+  // The MOR variable is absent; the platform firmware does not support it.\r
+  // Lock the variable so that no other module may create it.\r
+  //\r
+  VariableLockRequestToLock (\r
+    NULL,                                   // This\r
+    MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+    &gEfiMemoryOverwriteControlDataGuid\r
+    );\r
+\r
+  //\r
+  // Delete the MOR Control Lock variable too (should it exists for some\r
+  // reason) and prevent other modules from creating it.\r
   //\r
   mMorLockPassThru = TRUE;\r
   VariableServiceSetVariable (\r