]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c
SecurityPkg Variable: Implement variable quota management.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / VarCheck.c
index 76bd7b4d90791f3dbaabd01d3c71cef72f604c20..3f4beb07f0e03a153d5a7af4dc5fa1cc4f15f0c0 100644 (file)
@@ -48,14 +48,6 @@ typedef struct {
   INTERNAL_VAR_CHECK_FUNCTION   CheckFunction;\r
 } UEFI_DEFINED_VARIABLE_ENTRY;\r
 \r
-typedef struct _EFI_LOAD_OPTION {\r
-  UINT32                   Attributes;\r
-  UINT16                   FilePathListLength;\r
-//CHAR16                   Description[];\r
-//EFI_DEVICE_PATH_PROTOCOL FilePathList[];\r
-//UINT8                    OptionalData[];\r
-} EFI_LOAD_OPTION;\r
-\r
 /**\r
   Internal check for load option.\r
 \r
@@ -75,16 +67,16 @@ InternalVarCheckLoadOption (
   IN VOID                           *Data\r
   )\r
 {\r
-  EFI_LOAD_OPTION           *LoadOption;\r
+  UINT16                    FilePathListLength;\r
   CHAR16                    *Description;\r
   EFI_DEVICE_PATH_PROTOCOL  *FilePathList;\r
 \r
-  LoadOption = (EFI_LOAD_OPTION *) Data;\r
+  FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));\r
 \r
   //\r
   // Check Description\r
   //\r
-  Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION));\r
+  Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));\r
   while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {\r
     if (*Description == L'\0') {\r
       break;\r
@@ -100,16 +92,16 @@ InternalVarCheckLoadOption (
   // Check FilePathList\r
   //\r
   FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;\r
-  if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) {\r
+  if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) {\r
+  if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+  if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) {\r
+  if (!IsDevicePathValid (FilePathList, FilePathListLength)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -573,7 +565,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
       VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
       0,\r
       VARIABLE_ATTRIBUTE_NV_BS_RT,\r
-      sizeof (EFI_LOAD_OPTION),\r
+      sizeof (UINT32) + sizeof (UINT16),\r
       MAX_UINTN\r
     },\r
     InternalVarCheckLoadOption\r
@@ -584,7 +576,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
       VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
       0,\r
       VARIABLE_ATTRIBUTE_NV_BS_RT,\r
-      sizeof (EFI_LOAD_OPTION),\r
+      sizeof (UINT32) + sizeof (UINT16),\r
       MAX_UINTN\r
     },\r
     InternalVarCheckLoadOption\r
@@ -658,8 +650,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
       VARIABLE_ATTRIBUTE_NV_BS,\r
       sizeof (UINT8),\r
       sizeof (UINT8)\r
-    },\r
-    NULL\r
+    }\r
   },\r
   {\r
     &gEfiCustomModeEnableGuid,\r
@@ -670,8 +661,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
       VARIABLE_ATTRIBUTE_NV_BS,\r
       sizeof (UINT8),\r
       sizeof (UINT8)\r
-    },\r
-    NULL\r
+    }\r
   },\r
   {\r
     &gEfiVendorKeysNvGuid,\r
@@ -682,8 +672,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
       sizeof (UINT8),\r
       sizeof (UINT8)\r
-    },\r
-    NULL\r
+    }\r
   },\r
   {\r
     &gEfiAuthenticatedVariableGuid,\r
@@ -694,8 +683,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
       VARIABLE_ATTRIBUTE_NV_BS_RT_AW,\r
       sizeof (UINT8),\r
       MAX_UINTN\r
-    },\r
-    NULL\r
+    }\r
   },\r
   {\r
     &gEfiCertDbGuid,\r
@@ -706,8 +694,18 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
       sizeof (UINT32),\r
       MAX_UINTN\r
-    },\r
-    NULL\r
+    }\r
+  },\r
+  {\r
+    &gEdkiiVarErrorFlagGuid,\r
+    VAR_ERROR_FLAG_NAME,\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
   },\r
 };\r
 \r
@@ -738,7 +736,7 @@ GetUefiDefinedVariableProperty (
   UINTN     Index;\r
   UINTN     NameLength;\r
 \r
-  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){\r
+  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {\r
     //\r
     // Try list 1, exactly match.\r
     //\r
@@ -770,14 +768,13 @@ GetUefiDefinedVariableProperty (
           *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
           return EFI_SUCCESS;\r
         }\r
-      } else {\r
-        if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {\r
-          if (VarCheckFunction != NULL) {\r
-            *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
-          }\r
-          *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
-          return EFI_SUCCESS;\r
+      }\r
+      if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {\r
+        if (VarCheckFunction != NULL) {\r
+          *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
         }\r
+        *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
+        return EFI_SUCCESS;\r
       }\r
     }\r
 \r
@@ -812,7 +809,6 @@ GetUefiDefinedVariableProperty (
 \r
   @param[in]  VariableName      Pointer to variable name.\r
   @param[in]  VendorGuid        Variable Vendor Guid.\r
-  @param[out] VarCheckFunction  Pointer to check function.\r
 \r
   @return Pointer to variable property.\r
 \r
@@ -820,17 +816,13 @@ GetUefiDefinedVariableProperty (
 VAR_CHECK_VARIABLE_PROPERTY *\r
 GetVariableDriverVariableProperty (\r
   IN CHAR16                         *VariableName,\r
-  IN EFI_GUID                       *VendorGuid,\r
-  OUT INTERNAL_VAR_CHECK_FUNCTION   *VarCheckFunction OPTIONAL\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
-      if (VarCheckFunction != NULL) {\r
-        *VarCheckFunction = mVariableDriverVariableList[Index].CheckFunction;\r
-      }\r
       return &mVariableDriverVariableList[Index].VariableProperty;\r
     }\r
   }\r
@@ -881,26 +873,27 @@ InternalVarCheckSetVariableCheck (
   }\r
 \r
   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
-    return Status;\r
+  VarCheckFunction = NULL;\r
+\r
+  for ( Link = GetFirstNode (&mVarCheckVariableList)\r
+      ; !IsNull (&mVarCheckVariableList, Link)\r
+      ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
+      ) {\r
+    Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
+    Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+    if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
+      Property = &Entry->VariableProperty;\r
+      break;\r
+    }\r
   }\r
   if (Property == NULL) {\r
-    Property = GetVariableDriverVariableProperty (VariableName, VendorGuid, &VarCheckFunction);\r
+    Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);\r
   }\r
   if (Property == NULL) {\r
-    VarCheckFunction = NULL;\r
-    for ( Link = GetFirstNode (&mVarCheckVariableList)\r
-        ; !IsNull (&mVarCheckVariableList, Link)\r
-        ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
-        ) {\r
-      Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
-      Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
-      if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
-        Property = &Entry->VariableProperty;\r
-        break;\r
-      }\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
+      return Status;\r
     }\r
   }\r
   if (Property != NULL) {\r
@@ -908,30 +901,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 ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
+    if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {\r
       //\r
-      // Do not check delete variable.\r
+      // Not to delete variable.\r
       //\r
-      return EFI_SUCCESS;\r
-    }\r
-    if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) {\r
-      DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-    if (DataSize != 0) {\r
-      if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
-        DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
+      if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != 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
         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]: 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
+          }\r
         }\r
       }\r
     }\r
@@ -1047,18 +1039,20 @@ VarCheckRegisterSetVariableCheckHandler (
 }\r
 \r
 /**\r
-  Internal variable property get.\r
+  Variable property get function.\r
 \r
-  @param[in] Name   Pointer to the variable name.\r
-  @param[in] Guid   Pointer to the vendor GUID.\r
+  @param[in] Name           Pointer to the variable name.\r
+  @param[in] Guid           Pointer to the vendor GUID.\r
+  @param[in] WildcardMatch  Try wildcard match or not.\r
 \r
   @return Pointer to the property of variable specified by the Name and Guid.\r
 \r
 **/\r
 VAR_CHECK_VARIABLE_PROPERTY *\r
-InternalVarCheckVariablePropertyGet (\r
-  IN CHAR16                         *Name,\r
-  IN EFI_GUID                       *Guid\r
+VariablePropertyGetFunction (\r
+  IN CHAR16                 *Name,\r
+  IN EFI_GUID               *Guid,\r
+  IN BOOLEAN                WildcardMatch\r
   )\r
 {\r
   LIST_ENTRY                    *Link;\r
@@ -1066,27 +1060,23 @@ InternalVarCheckVariablePropertyGet (
   CHAR16                        *VariableName;\r
   VAR_CHECK_VARIABLE_PROPERTY   *Property;\r
 \r
-  Property = NULL;\r
-  GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL);\r
-  if (Property == NULL) {\r
-    Property = GetVariableDriverVariableProperty (Name, Guid, NULL);\r
-  }\r
-  if (Property != NULL) {\r
-    return Property;\r
-  } else {\r
-    for ( Link = GetFirstNode (&mVarCheckVariableList)\r
-        ; !IsNull (&mVarCheckVariableList, Link)\r
-        ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
-        ) {\r
-      Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
-      VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
-      if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
-        return &Entry->VariableProperty;\r
-      }\r
+  for ( Link = GetFirstNode (&mVarCheckVariableList)\r
+      ; !IsNull (&mVarCheckVariableList, Link)\r
+      ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
+      ) {\r
+    Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
+    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+    if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
+      return &Entry->VariableProperty;\r
     }\r
   }\r
 \r
-  return NULL;\r
+  Property = GetVariableDriverVariableProperty (Name, Guid);\r
+  if (Property == NULL) {\r
+    GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);\r
+  }\r
+\r
+  return Property;\r
 }\r
 \r
 /**\r
@@ -1137,7 +1127,7 @@ VarCheckVariablePropertySet (
 \r
   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
-  Property = InternalVarCheckVariablePropertyGet (Name, Guid);\r
+  Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
   if (Property != NULL) {\r
     CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
   } else {\r
@@ -1160,20 +1150,19 @@ Done:
 }\r
 \r
 /**\r
-  Variable property get.\r
+  Internal variable property get.\r
 \r
   @param[in]  Name              Pointer to the variable name.\r
   @param[in]  Guid              Pointer to the vendor GUID.\r
   @param[out] VariableProperty  Pointer to the output variable property.\r
 \r
   @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully.\r
-  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
   @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-VarCheckVariablePropertyGet (\r
+InternalVarCheckVariablePropertyGet (\r
   IN CHAR16                         *Name,\r
   IN EFI_GUID                       *Guid,\r
   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty\r
@@ -1185,19 +1174,9 @@ VarCheckVariablePropertyGet (
   BOOLEAN                       Found;\r
   VAR_CHECK_VARIABLE_PROPERTY   *Property;\r
 \r
-  if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (VariableProperty == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
   Found = FALSE;\r
 \r
-  AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-\r
-  Property = InternalVarCheckVariablePropertyGet (Name, Guid);\r
+  Property = VariablePropertyGetFunction (Name, Guid, TRUE);\r
   if (Property != NULL) {\r
     CopyMem (VariableProperty, Property, sizeof (*VariableProperty));\r
     Found = TRUE;\r
@@ -1218,8 +1197,45 @@ VarCheckVariablePropertyGet (
     }\r
   }\r
 \r
+  return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
+}\r
+\r
+/**\r
+  Variable property get.\r
+\r
+  @param[in]  Name              Pointer to the variable name.\r
+  @param[in]  Guid              Pointer to the vendor GUID.\r
+  @param[out] VariableProperty  Pointer to the output variable property.\r
+\r
+  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully.\r
+  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
+  @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VarCheckVariablePropertyGet (\r
+  IN CHAR16                         *Name,\r
+  IN EFI_GUID                       *Guid,\r
+  OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (VariableProperty == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+  Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty);\r
+\r
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
-  return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
+  return Status;\r
 }\r
 \r