]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
MdePkg/MdeModulePkg/SecurityPkg Variable: Forbid creation of non-spec variables in...
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / Variable.c
index 53ef092aff951d9eebf3e676c229dca39c2f2bd9..5261157ff24883439ac60e79d6b2cb1ab0ffc077 100644 (file)
@@ -58,6 +58,51 @@ BOOLEAN                mEndOfDxe              = FALSE;
 ///\r
 BOOLEAN                mEnableLocking         = TRUE;\r
 \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
+GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = {\r
+  {EFI_LANG_CODES_VARIABLE_NAME,             VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_LANG_VARIABLE_NAME,                   VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_TIME_OUT_VARIABLE_NAME,               VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,    VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_PLATFORM_LANG_VARIABLE_NAME,          VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_CON_IN_VARIABLE_NAME,                 VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_CON_OUT_VARIABLE_NAME,                VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_ERR_OUT_VARIABLE_NAME,                VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_CON_IN_DEV_VARIABLE_NAME,             VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_CON_OUT_DEV_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_ERR_OUT_DEV_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_BOOT_ORDER_VARIABLE_NAME,             VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_BOOT_NEXT_VARIABLE_NAME,              VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_BOOT_CURRENT_VARIABLE_NAME,           VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,    VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_DRIVER_ORDER_VARIABLE_NAME,           VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,     VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_SETUP_MODE_NAME,                      VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_KEY_EXCHANGE_KEY_NAME,                VARIABLE_ATTRIBUTE_NV_BS_RT_AT},\r
+  {EFI_PLATFORM_KEY_NAME,                    VARIABLE_ATTRIBUTE_NV_BS_RT_AT},\r
+  {EFI_SIGNATURE_SUPPORT_NAME,               VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_SECURE_BOOT_MODE_NAME,                VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_KEK_DEFAULT_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_PK_DEFAULT_VARIABLE_NAME,             VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_DB_DEFAULT_VARIABLE_NAME,             VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_DBX_DEFAULT_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_DBT_DEFAULT_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
+  {EFI_OS_INDICATIONS_VARIABLE_NAME,         VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {EFI_VENDOR_KEYS_VARIABLE_NAME,            VARIABLE_ATTRIBUTE_BS_RT},\r
+};\r
+GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = {\r
+  {L"Boot####",                              VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {L"Driver####",                            VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+  {L"Key####",                               VARIABLE_ATTRIBUTE_NV_BS_RT},\r
+};\r
 \r
 /**\r
   Routine used to track statistical information about variable usage.\r
@@ -1473,7 +1518,7 @@ AutoUpdateLangVariable (
 \r
   SetLanguageCodes = FALSE;\r
 \r
-  if (StrCmp (VariableName, L"PlatformLangCodes") == 0) {\r
+  if (StrCmp (VariableName, EFI_PLATFORM_LANG_CODES_VARIABLE_NAME) == 0) {\r
     //\r
     // PlatformLangCodes is a volatile variable, so it can not be updated at runtime.\r
     //\r
@@ -1503,7 +1548,7 @@ AutoUpdateLangVariable (
     mVariableModuleGlobal->PlatformLang = AllocateRuntimePool (DataSize);\r
     ASSERT (mVariableModuleGlobal->PlatformLang != NULL);\r
 \r
-  } else if (StrCmp (VariableName, L"LangCodes") == 0) {\r
+  } else if (StrCmp (VariableName, EFI_LANG_CODES_VARIABLE_NAME) == 0) {\r
     //\r
     // LangCodes is a volatile variable, so it can not be updated at runtime.\r
     //\r
@@ -1531,21 +1576,21 @@ AutoUpdateLangVariable (
     // Update Lang if PlatformLang is already set\r
     // Update PlatformLang if Lang is already set\r
     //\r
-    Status = FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+    Status = FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
     if (!EFI_ERROR (Status)) {\r
       //\r
       // Update Lang\r
       //\r
-      VariableName = L"PlatformLang";\r
+      VariableName = EFI_PLATFORM_LANG_VARIABLE_NAME;\r
       Data         = GetVariableDataPtr (Variable.CurrPtr);\r
       DataSize     = Variable.CurrPtr->DataSize;\r
     } else {\r
-      Status = FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+      Status = FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
       if (!EFI_ERROR (Status)) {\r
         //\r
         // Update PlatformLang\r
         //\r
-        VariableName = L"Lang";\r
+        VariableName = EFI_LANG_VARIABLE_NAME;\r
         Data         = GetVariableDataPtr (Variable.CurrPtr);\r
         DataSize     = Variable.CurrPtr->DataSize;\r
       } else {\r
@@ -1562,7 +1607,7 @@ AutoUpdateLangVariable (
   //\r
   Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
 \r
-  if (StrCmp (VariableName, L"PlatformLang") == 0) {\r
+  if (StrCmp (VariableName, EFI_PLATFORM_LANG_VARIABLE_NAME) == 0) {\r
     //\r
     // Update Lang when PlatformLangCodes/LangCodes were set.\r
     //\r
@@ -1585,9 +1630,9 @@ AutoUpdateLangVariable (
         //\r
         // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.\r
         //\r
-        FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+        FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
 \r
-        Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang,\r
+        Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,\r
                                  ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);\r
 \r
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));\r
@@ -1596,7 +1641,7 @@ AutoUpdateLangVariable (
       }\r
     }\r
 \r
-  } else if (StrCmp (VariableName, L"Lang") == 0) {\r
+  } else if (StrCmp (VariableName, EFI_LANG_VARIABLE_NAME) == 0) {\r
     //\r
     // Update PlatformLang when PlatformLangCodes/LangCodes were set.\r
     //\r
@@ -1619,9 +1664,9 @@ AutoUpdateLangVariable (
         //\r
         // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.\r
         //\r
-        FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+        FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
 \r
-        Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang,\r
+        Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,\r
                                  AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);\r
 \r
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));\r
@@ -2327,6 +2372,63 @@ IsHwErrRecVariable (
   return TRUE;\r
 }\r
 \r
+/**\r
+  This code checks if variable guid is global variable guid first.\r
+  If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched.\r
+\r
+  @param[in] VariableName       Pointer to variable name.\r
+  @param[in] VendorGuid         Variable Vendor Guid.\r
+  @param[in] Attributes         Attributes of the variable.\r
+\r
+  @retval EFI_SUCCESS           Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched.\r
+  @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CheckEfiGlobalVariable (\r
+  IN CHAR16             *VariableName,\r
+  IN EFI_GUID           *VendorGuid,\r
+  IN UINT32             Attributes\r
+  )\r
+{\r
+  UINTN     Index;\r
+  UINTN     NameLength;\r
+\r
+  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){\r
+    //\r
+    // Try list 1, exactly match.\r
+    //\r
+    for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {\r
+      if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) &&\r
+          (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList[Index].Attributes)) {\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Try list 2.\r
+    //\r
+    NameLength = StrLen (VariableName) - 4;\r
+    for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {\r
+      if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&\r
+          (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&\r
+          IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&\r
+          IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&\r
+          IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&\r
+          IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) &&\r
+          (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList2[Index].Attributes)) {\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+\r
+    DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Mark a variable that will become read-only after leaving the DXE phase of execution.\r
 \r
@@ -2787,6 +2889,11 @@ VariableServiceSetVariable (
     }\r
   }\r
 \r
+  Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
   //\r