]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c
MdeModulePkg Variable: Merge from Auth Variable driver in SecurityPkg
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / VarCheck.c
index b2f557232765b7fe1b7f9f410a42e5e18c337c61..ab0c1d6324a0da0f1d32cfdf480773d12a458461 100644 (file)
@@ -2,12 +2,12 @@
   Implementation functions and structures for var check protocol.\r
 \r
 Copyright (c) 2015, 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
+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
+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
 \r
 **/\r
@@ -616,30 +616,49 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
   },\r
 };\r
 \r
-typedef struct {\r
-  EFI_GUID                      *Guid;\r
-  CHAR16                        *Name;\r
-  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;\r
-} VARIABLE_DRIVER_VARIABLE_ENTRY;\r
-\r
-VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {\r
+//\r
+// EFI_IMAGE_SECURITY_DATABASE_GUID\r
+//\r
+UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {\r
   {\r
-    &gEdkiiVarErrorFlagGuid,\r
-    VAR_ERROR_FLAG_NAME,\r
+    EFI_IMAGE_SECURITY_DATABASE,\r
     {\r
       VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
-      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
-      VARIABLE_ATTRIBUTE_NV_BS_RT,\r
-      sizeof (VAR_ERROR_FLAG),\r
-      sizeof (VAR_ERROR_FLAG),\r
-    }\r
+      0,\r
+      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
+      1,\r
+      MAX_UINTN\r
+    },\r
+    NULL\r
+  },\r
+  {\r
+    EFI_IMAGE_SECURITY_DATABASE1,\r
+    {\r
+      VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
+      0,\r
+      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
+      1,\r
+      MAX_UINTN\r
+    },\r
+    NULL\r
+  },\r
+  {\r
+    EFI_IMAGE_SECURITY_DATABASE2,\r
+    {\r
+      VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
+      0,\r
+      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
+      1,\r
+      MAX_UINTN\r
+    },\r
+    NULL\r
   },\r
 };\r
 \r
 /**\r
-  Get UEFI defined global variable property.\r
-  The code will check if variable guid is global variable guid first.\r
-  If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2.\r
+  Get UEFI defined global variable or image security database variable property.\r
+  The code will check if variable guid is global variable or image security database guid first.\r
+  If yes, further check if variable name is in mGlobalVariableList, mGlobalVariableList2 or mImageSecurityVariableList.\r
 \r
   @param[in]  VariableName      Pointer to variable name.\r
   @param[in]  VendorGuid        Variable Vendor Guid.\r
@@ -647,8 +666,8 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
   @param[out] VariableProperty  Pointer to variable property.\r
   @param[out] VarCheckFunction  Pointer to check function.\r
 \r
-  @retval EFI_SUCCESS           Variable is not global variable.\r
-  @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists.\r
+  @retval EFI_SUCCESS           Variable is not global variable or image security database variable.\r
+  @retval EFI_INVALID_PARAMETER Variable is global variable or image security database variable, but variable name is not in the lists.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -711,36 +730,24 @@ GetUefiDefinedVariableProperty (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // It is not global variable.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Get variable property for variables managed by Varaible driver.\r
-\r
-  @param[in]  VariableName      Pointer to variable name.\r
-  @param[in]  VendorGuid        Variable Vendor Guid.\r
-\r
-  @return Pointer to variable property.\r
-\r
-**/\r
-VAR_CHECK_VARIABLE_PROPERTY *\r
-GetVariableDriverVariableProperty (\r
-  IN CHAR16                         *VariableName,\r
-  IN EFI_GUID                       *VendorGuid\r
-  )\r
-{\r
-  UINTN     Index;\r
-\r
-  for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {\r
-    if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {\r
-      return &mVariableDriverVariableList[Index].VariableProperty;\r
+  if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {\r
+    for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {\r
+      if (StrCmp (mImageSecurityVariableList[Index].Name, VariableName) == 0) {\r
+        if (VarCheckFunction != NULL) {\r
+          *VarCheckFunction = mImageSecurityVariableList[Index].CheckFunction;\r
+        }\r
+        *VariableProperty = &mImageSecurityVariableList[Index].VariableProperty;\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
+\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  return NULL;\r
+  //\r
+  // It is not global variable, image security database variable.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -799,13 +806,18 @@ InternalVarCheckSetVariableCheck (
       break;\r
     }\r
   }\r
-  if (Property == NULL) {\r
-    Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);\r
-  }\r
   if (Property == NULL) {\r
     Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
+    //\r
+    // To prevent name collisions with possible future globally defined variables,\r
+    // other internal firmware data variables that are not defined here must be\r
+    // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or\r
+    // any other GUID defined by the UEFI Specification. Implementations must\r
+    // only permit the creation of variables with a UEFI Specification-defined\r
+    // VendorGuid when these variables are documented in the UEFI Specification.\r
+    //\r
+      DEBUG ((EFI_D_INFO, "Variable Check UEFI defined variable fail %r - %s not in %g namespace\n", Status, VariableName, VendorGuid));\r
       return Status;\r
     }\r
   }\r
@@ -814,27 +826,29 @@ InternalVarCheckSetVariableCheck (
       DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));\r
       return EFI_WRITE_PROTECTED;\r
     }\r
-    if (!((DataSize == 0) || (Attributes == 0))) {\r
+    if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {\r
       //\r
       // Not to delete variable.\r
       //\r
-      if (Attributes != Property->Attributes) {\r
-        DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
+      if ((Attributes != 0) && ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes)) {\r
+        DEBUG ((EFI_D_INFO, "Variable Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
         return EFI_INVALID_PARAMETER;\r
       }\r
-      if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
-        DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-      if (VarCheckFunction != NULL) {\r
-        Status = VarCheckFunction (\r
-                   Property,\r
-                   DataSize,\r
-                   Data\r
-                   );\r
-        if (EFI_ERROR (Status)) {\r
-          DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
-          return Status;\r
+      if (DataSize != 0) {\r
+        if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
+          DEBUG ((EFI_D_INFO, "Variable Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+        if (VarCheckFunction != NULL) {\r
+          Status = VarCheckFunction (\r
+                     Property,\r
+                     DataSize,\r
+                     Data\r
+                     );\r
+          if (EFI_ERROR (Status)) {\r
+            DEBUG ((EFI_D_INFO, "Internal Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
+            return Status;\r
+          }\r
         }\r
       }\r
     }\r
@@ -849,7 +863,7 @@ InternalVarCheckSetVariableCheck (
                Data\r
                );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
+      DEBUG ((EFI_D_INFO, "Variable Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
       return Status;\r
     }\r
   }\r
@@ -875,8 +889,8 @@ ReallocateHandlerTable (
   // Reallocate memory for check handler table.\r
   //\r
   HandlerTable = ReallocateRuntimePool (\r
-                     mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), \r
-                     (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), \r
+                     mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),\r
+                     (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),\r
                      mHandlerTable\r
                      );\r
 \r
@@ -927,6 +941,10 @@ VarCheckRegisterSetVariableCheckHandler (
 \r
   DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));\r
 \r
+  Status = EFI_SUCCESS;\r
+\r
+  AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
   //\r
   // Check whether the handler list is enough to store new handler.\r
   //\r
@@ -936,7 +954,7 @@ VarCheckRegisterSetVariableCheckHandler (
     //\r
     Status = ReallocateHandlerTable();\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
   }\r
 \r
@@ -946,7 +964,10 @@ VarCheckRegisterSetVariableCheckHandler (
   mHandlerTable[mNumberOfHandler] = Handler;\r
   mNumberOfHandler++;\r
 \r
-  return EFI_SUCCESS;\r
+Done:\r
+  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -971,6 +992,8 @@ VariablePropertyGetFunction (
   CHAR16                        *VariableName;\r
   VAR_CHECK_VARIABLE_PROPERTY   *Property;\r
 \r
+  Property = NULL;\r
+\r
   for ( Link = GetFirstNode (&mVarCheckVariableList)\r
       ; !IsNull (&mVarCheckVariableList, Link)\r
       ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
@@ -982,14 +1005,57 @@ VariablePropertyGetFunction (
     }\r
   }\r
 \r
-  Property = GetVariableDriverVariableProperty (Name, Guid);\r
-  if (Property == NULL) {\r
-    GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);\r
-  }\r
+  GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);\r
 \r
   return Property;\r
 }\r
 \r
+/**\r
+  Internal variable property set.\r
+\r
+  @param[in] Name               Pointer to the variable name.\r
+  @param[in] Guid               Pointer to the vendor GUID.\r
+  @param[in] VariableProperty   Pointer to the input variable property.\r
+\r
+  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was set successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the variable property set request.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalVarCheckVariablePropertySet (\r
+  IN CHAR16                         *Name,\r
+  IN EFI_GUID                       *Guid,\r
+  IN VAR_CHECK_VARIABLE_PROPERTY    *VariableProperty\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  VAR_CHECK_VARIABLE_ENTRY      *Entry;\r
+  CHAR16                        *VariableName;\r
+  VAR_CHECK_VARIABLE_PROPERTY   *Property;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
+  if (Property != NULL) {\r
+    CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
+  } else {\r
+    Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));\r
+    if (Entry == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+    StrnCpy (VariableName, Name, StrLen (Name));\r
+    CopyGuid (&Entry->Guid, Guid);\r
+    CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));\r
+    InsertTailList (&mVarCheckVariableList, &Entry->Link);\r
+  }\r
+\r
+Done:\r
+  return Status;\r
+}\r
+\r
 /**\r
   Variable property set.\r
 \r
@@ -1014,9 +1080,6 @@ VarCheckVariablePropertySet (
   )\r
 {\r
   EFI_STATUS                    Status;\r
-  VAR_CHECK_VARIABLE_ENTRY      *Entry;\r
-  CHAR16                        *VariableName;\r
-  VAR_CHECK_VARIABLE_PROPERTY   *Property;\r
 \r
   if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1034,27 +1097,10 @@ VarCheckVariablePropertySet (
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
-\r
   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
-  Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
-  if (Property != NULL) {\r
-    CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
-  } else {\r
-    Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));\r
-    if (Entry == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Done;\r
-    }\r
-    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
-    StrnCpy (VariableName, Name, StrLen (Name));\r
-    CopyGuid (&Entry->Guid, Guid);\r
-    CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));\r
-    InsertTailList (&mVarCheckVariableList, &Entry->Link);\r
-  }\r
+  Status = InternalVarCheckVariablePropertySet (Name, Guid, VariableProperty);\r
 \r
-Done:\r
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
   return Status;\r