]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c
MdePkg/MdeModulePkg/SecurityPkg Variable: Forbid creation of non-spec variables in...
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / EmuRuntimeDxe / EmuVariable.c
index b0644d6040a9c386f813aa58653f21d3870be2fc..ae31e3ac5925e1672e552b3a4e75d2a24938fd73 100644 (file)
@@ -3,7 +3,7 @@
   Emulation Variable services operate on the runtime volatile memory.\r
   The nonvolatile variable space doesn't exist.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, 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
@@ -186,7 +186,7 @@ GetNextPotentialVariablePtr (
   //\r
   // Be careful about pad size for alignment\r
   //\r
-  VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
+  VarHeader = (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
 \r
   return VarHeader;\r
 }\r
@@ -268,7 +268,7 @@ GetEndPointer (
   //\r
   // The end of variable store\r
   //\r
-  return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);\r
+  return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VolHeader + VolHeader->Size);\r
 }\r
 \r
 /**\r
@@ -523,6 +523,11 @@ GetLangFromSupportedLangCodes (
         return CopyMem (mVariableModuleGlobal->PlatformLang, Supported - CompareLength, CompareLength);\r
       }\r
       SubIndex++;\r
+      \r
+      //\r
+      // Skip ';' characters in Supported\r
+      //\r
+      for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
     }\r
   }\r
 }\r
@@ -567,6 +572,7 @@ GetLangFromSupportedLangCodes (
 \r
 **/\r
 CHAR8 *\r
+EFIAPI\r
 VariableGetBestLanguage (\r
   IN CONST CHAR8  *SupportedLanguages, \r
   IN BOOLEAN      Iso639Language,\r
@@ -984,24 +990,24 @@ UpdateVariable (
   if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
     NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(Global->NonVolatileVariableBase))->Size;\r
     if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
-      && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
+      && ((HEADER_ALIGN (VarSize) + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
       || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
-      && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
+      && ((HEADER_ALIGN (VarSize) + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
     }\r
 \r
     NextVariable  = (VARIABLE_HEADER *) (UINT8 *) (mVariableModuleGlobal->NonVolatileLastVariableOffset\r
                       + (UINTN) Global->NonVolatileVariableBase);\r
-    mVariableModuleGlobal->NonVolatileLastVariableOffset += VarSize;\r
+    mVariableModuleGlobal->NonVolatileLastVariableOffset += HEADER_ALIGN (VarSize);\r
 \r
     if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {\r
-      mVariableModuleGlobal->HwErrVariableTotalSize += VarSize;\r
+      mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize);\r
     } else {\r
-      mVariableModuleGlobal->CommonVariableTotalSize += VarSize;\r
+      mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);\r
     }\r
   } else {\r
-    if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >\r
+    if ((UINT32) (HEADER_ALIGN (VarSize) + mVariableModuleGlobal->VolatileLastVariableOffset) >\r
           ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size\r
           ) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
@@ -1010,7 +1016,7 @@ UpdateVariable (
 \r
     NextVariable    = (VARIABLE_HEADER *) (UINT8 *) (mVariableModuleGlobal->VolatileLastVariableOffset\r
                         + (UINTN) Global->VolatileVariableBase);\r
-    mVariableModuleGlobal->VolatileLastVariableOffset += VarSize;\r
+    mVariableModuleGlobal->VolatileLastVariableOffset += HEADER_ALIGN (VarSize);\r
   }\r
 \r
   NextVariable->StartId     = VARIABLE_DATA;\r
@@ -1097,8 +1103,8 @@ FindVariable (
   // Start Pointers for the variable.\r
   // Actual Data Pointer where data can be written.\r
   //\r
-  Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);\r
-  Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);\r
+  Variable[0] = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader[0] + 1);\r
+  Variable[1] = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader[1] + 1);\r
 \r
   if (VariableName[0] != 0 && VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1107,7 +1113,7 @@ FindVariable (
   // Find the variable by walk through non-volatile and volatile variable store\r
   //\r
   for (Index = 0; Index < 2; Index++) {\r
-    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);\r
+    PtrTrack->StartPtr  = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader[Index] + 1);\r
     PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);\r
 \r
     while ((Variable[Index] < GetEndPointer (VariableStoreHeader[Index])) && (Variable[Index] != NULL)) {\r
@@ -1171,6 +1177,7 @@ EmuGetVariable (
   VARIABLE_POINTER_TRACK  Variable;\r
   UINTN                   VarDataSize;\r
   EFI_STATUS              Status;\r
+  UINT8                   *VariableDataPtr;\r
 \r
   if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1195,8 +1202,10 @@ EmuGetVariable (
       Status = EFI_INVALID_PARAMETER;\r
       goto Done;\r
     }\r
-\r
-    CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);\r
+    VariableDataPtr = GetVariableDataPtr (Variable.CurrPtr);\r
+    ASSERT (VariableDataPtr != NULL);\r
+    \r
+    CopyMem (Data, VariableDataPtr, VarDataSize);\r
     if (Attributes != NULL) {\r
       *Attributes = Variable.CurrPtr->Attributes;\r
     }\r
@@ -1273,7 +1282,7 @@ EmuGetNextVariableName (
     if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {\r
       Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));\r
       if (Variable.Volatile) {\r
-        Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
+        Variable.StartPtr = (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
         Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));\r
       } else {\r
         Status = EFI_NOT_FOUND;\r
@@ -1388,14 +1397,22 @@ EmuSetVariable (
   if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
+  \r
+  if ((UINTN)(~0) - DataSize < StrSize(VariableName)){\r
+    //\r
+    // Prevent whole variable size overflow \r
+    // \r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   //  The size of the VariableName, including the Unicode Null in bytes plus\r
   //  the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize)\r
   //  bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others.\r
   //\r
   if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
-    if ((DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize)) ||                                                       \r
-        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize))) {\r
+    if (StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
     //\r
@@ -1409,8 +1426,7 @@ EmuSetVariable (
   //  The size of the VariableName, including the Unicode Null in bytes plus\r
   //  the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes.\r
   //\r
-    if ((DataSize > PcdGet32 (PcdMaxVariableSize)) ||\r
-        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxVariableSize))) {\r
+    if (StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) {\r
       return EFI_INVALID_PARAMETER;\r
     }  \r
   }\r
@@ -1547,7 +1563,7 @@ EmuQueryVariableInfo (
   //\r
   // Point to the starting address of the variables.\r
   //\r
-  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+  Variable = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader + 1);\r
 \r
   //\r
   // Now walk through the related variable store.\r
@@ -1559,7 +1575,7 @@ EmuQueryVariableInfo (
     }\r
     VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable;\r
 \r
-    if ((NextVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
+    if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
       HwErrVariableTotalSize += VariableSize;\r
     } else {\r
       CommonVariableTotalSize += VariableSize;\r
@@ -1600,10 +1616,15 @@ InitializeVariableStore (
   IN  BOOLEAN               VolatileStore\r
   )\r
 {\r
+  EFI_STATUS            Status;\r
   VARIABLE_STORE_HEADER *VariableStore;\r
   BOOLEAN               FullyInitializeStore;\r
   EFI_PHYSICAL_ADDRESS  *VariableBase;\r
   UINTN                 *LastVariableOffset;\r
+  VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+  VARIABLE_HEADER       *Variable;\r
+  VOID                  *VariableData;\r
+  EFI_HOB_GUID_TYPE     *GuidHob;\r
 \r
   FullyInitializeStore = TRUE;\r
 \r
@@ -1672,6 +1693,44 @@ InitializeVariableStore (
   VariableStore->Reserved   = 0;\r
   VariableStore->Reserved1  = 0;\r
 \r
+  if (!VolatileStore) {\r
+    //\r
+    // Get HOB variable store.\r
+    //\r
+    GuidHob = GetFirstGuidHob (&gEfiVariableGuid);\r
+    if (GuidHob != NULL) {\r
+      VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);\r
+      if (CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) &&\r
+          (VariableStoreHeader->Format == VARIABLE_STORE_FORMATTED) &&\r
+          (VariableStoreHeader->State == VARIABLE_STORE_HEALTHY)\r
+         ) {\r
+        DEBUG ((EFI_D_INFO, "HOB Variable Store appears to be valid.\n"));\r
+        //\r
+        // Flush the HOB variable to Emulation Variable storage.\r
+        //\r
+        for ( Variable = (VARIABLE_HEADER *) HEADER_ALIGN (VariableStoreHeader + 1)\r
+            ; (Variable < GetEndPointer (VariableStoreHeader) && (Variable != NULL))\r
+            ; Variable = GetNextVariablePtr (Variable)\r
+            ) {\r
+          ASSERT (Variable->State == VAR_ADDED);\r
+          ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);\r
+          VariableData = GetVariableDataPtr (Variable);\r
+          Status = EmuSetVariable (\r
+                     GET_VARIABLE_NAME_PTR (Variable),\r
+                     &Variable->VendorGuid,\r
+                     Variable->Attributes,\r
+                     Variable->DataSize,\r
+                     VariableData,\r
+                     &mVariableModuleGlobal->VariableGlobal[Physical],\r
+                     &mVariableModuleGlobal->VolatileLastVariableOffset,\r
+                     &mVariableModuleGlobal->NonVolatileLastVariableOffset\r
+                     );\r
+          ASSERT_EFI_ERROR (Status);\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r