Calculate enough space for 2 variables (public key and variable data) instead of...
authorDong Guo <guo.dong@intel.com>
Thu, 27 Mar 2014 10:54:23 +0000 (10:54 +0000)
committergdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 27 Mar 2014 10:54:23 +0000 (10:54 +0000)
Fixed a bug in public key reclaim().

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dong Guo <guo.dong@intel.com>
Reviewed-by: Yao Jiewen <jiewen.yao@intel.com>
Reviewed-by: Zeng, Star <star.zeng@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15404 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h

index 9825580..7bd9ffb 100644 (file)
@@ -1268,8 +1268,10 @@ VariableGetBestLanguage (
   so follow the argument sequence to check the Variables.\r
 \r
   @param[in] Attributes         Variable attributes for Variable entries.\r
-  @param     ...                Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.\r
-                                A NULL terminates the list.\r
+  @param ...                    The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.\r
+                                A NULL terminates the list. The VariableSize of \r
+                                VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.\r
+                                It will be changed to variable total size as output.\r
 \r
   @retval TRUE                  Have enough variable space to set the Variables successfully.\r
   @retval FALSE                 No enough variable space to set the Variables successfully.\r
@@ -1293,6 +1295,8 @@ CheckRemainingSpaceForConsistency (
   VARIABLE_STORE_HEADER         *VariableStoreHeader;\r
   VARIABLE_POINTER_TRACK        VariablePtrTrack;\r
   VARIABLE_HEADER               *NextVariable;\r
+  UINTN                         VarNameSize;\r
+  UINTN                         VarDataSize;\r
 \r
   //\r
   // Non-Volatile related.\r
@@ -1311,6 +1315,15 @@ CheckRemainingSpaceForConsistency (
   VA_START (Args, Attributes);\r
   VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
   while (VariableEntry != NULL) {\r
+    //\r
+    // Calculate variable total size.\r
+    //\r
+    VarNameSize  = StrSize (VariableEntry->Name);\r
+    VarNameSize += GET_PAD_SIZE (VarNameSize);\r
+    VarDataSize  = VariableEntry->VariableSize;\r
+    VarDataSize += GET_PAD_SIZE (VarDataSize);\r
+    VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);\r
+\r
     TotalNeededSize += VariableEntry->VariableSize;\r
     VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
   }\r
@@ -1407,8 +1420,6 @@ AutoUpdateLangVariable (
   UINT32                 Attributes;\r
   VARIABLE_POINTER_TRACK Variable;\r
   BOOLEAN                SetLanguageCodes;\r
-  UINTN                  VarNameSize;\r
-  UINTN                  VarDataSize;\r
   VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];\r
 \r
   //\r
@@ -1532,21 +1543,13 @@ AutoUpdateLangVariable (
         BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);\r
 \r
         //\r
-        // Calculate the needed variable size for Lang variable.\r
+        // Check the variable space for both Lang and PlatformLang variable.\r
         //\r
-        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);\r
-        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;\r
-        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);\r
+        VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;\r
         VariableEntry[0].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;\r
-        //\r
-        // Calculate the needed variable size for PlatformLang variable.\r
-        //\r
-        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);\r
-        VarDataSize = AsciiStrSize (BestPlatformLang);\r
-        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);\r
+        \r
+        VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);\r
         VariableEntry[1].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;\r
         if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
@@ -1589,21 +1592,13 @@ AutoUpdateLangVariable (
         BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);\r
 \r
         //\r
-        // Calculate the needed variable size for PlatformLang variable.\r
+        // Check the variable space for both PlatformLang and Lang variable.\r
         //\r
-        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);\r
-        VarDataSize = AsciiStrSize (BestPlatformLang);\r
-        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);\r
+        VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);\r
         VariableEntry[0].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;\r
-        //\r
-        // Calculate the needed variable size for Lang variable.\r
-        //\r
-        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);\r
-        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;\r
-        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);\r
+\r
+        VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;\r
         VariableEntry[1].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;\r
         if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
index fa78e44..ac71f0c 100644 (file)
@@ -101,10 +101,6 @@ typedef struct {
 typedef struct {\r
   EFI_GUID    *Guid;\r
   CHAR16      *Name;\r
-//  UINT32      Attributes;\r
-  //\r
-  // Variable size include variable header, name and data.\r
-  //\r
   UINTN       VariableSize;\r
 } VARIABLE_ENTRY_CONSISTENCY;\r
 \r
index 3db3d29..25089ef 100644 (file)
@@ -456,16 +456,19 @@ AutenticatedVariableServiceInitialize (
 **/\r
 UINT32\r
 AddPubKeyInStore (\r
-  IN  UINT8               *PubKey\r
+  IN  UINT8                        *PubKey,\r
+  IN  VARIABLE_ENTRY_CONSISTENCY   *VariableDataEntry\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  BOOLEAN                 IsFound;\r
-  UINT32                  Index;\r
-  VARIABLE_POINTER_TRACK  Variable;\r
-  UINT8                   *Ptr;\r
-  UINT8                   *Data;\r
-  UINTN                   DataSize;\r
+  EFI_STATUS                       Status;\r
+  BOOLEAN                          IsFound;\r
+  UINT32                           Index;\r
+  VARIABLE_POINTER_TRACK           Variable;\r
+  UINT8                            *Ptr;\r
+  UINT8                            *Data;\r
+  UINTN                            DataSize;\r
+  VARIABLE_ENTRY_CONSISTENCY       PublicKeyEntry;\r
+  UINT32                           Attributes;\r
 \r
   if (PubKey == NULL) {\r
     return 0;\r
@@ -546,6 +549,21 @@ AddPubKeyInStore (
       }     \r
     }\r
 \r
+    //\r
+    // Check the variable space for both public key and variable data.\r
+    //\r
+    PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE;\r
+    PublicKeyEntry.Guid         = &gEfiAuthenticatedVariableGuid;\r
+    PublicKeyEntry.Name         = AUTHVAR_KEYDB_NAME;\r
+    Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
+\r
+    if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {\r
+      //\r
+      // No enough variable space.\r
+      //\r
+      return 0;\r
+    }\r
+\r
     CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
     Index = ++mPubKeyNumber;\r
     //\r
@@ -556,7 +574,7 @@ AddPubKeyInStore (
                &gEfiAuthenticatedVariableGuid,\r
                mPubKeyStore,\r
                mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,\r
-               EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,\r
+               Attributes,\r
                0,\r
                0,\r
                &Variable,\r
@@ -1271,6 +1289,7 @@ ProcessVariable (
   EFI_CERT_BLOCK_RSA_2048_SHA256  *CertBlock;\r
   UINT32                          KeyIndex;\r
   UINT64                          MonotonicCount;\r
+  VARIABLE_ENTRY_CONSISTENCY      VariableDataEntry;\r
 \r
   KeyIndex    = 0;\r
   CertData    = NULL;\r
@@ -1396,10 +1415,14 @@ ProcessVariable (
   // Now, the signature has been verified!\r
   //\r
   if (IsFirstTime && !IsDeletion) {\r
+    VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;\r
+    VariableDataEntry.Guid         = VendorGuid;\r
+    VariableDataEntry.Name         = VariableName;\r
+\r
     //\r
     // Update public key database variable if need.\r
     //\r
-    KeyIndex = AddPubKeyInStore (PubKey);\r
+    KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);\r
     if (KeyIndex == 0) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
index 8f4a0a8..7d7bc9e 100644 (file)
@@ -610,7 +610,7 @@ IsValidPubKeyIndex (
     return FALSE;\r
   }\r
   \r
-  Variable = GetStartPointer (mNvVariableCache);\r
+  Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
   \r
   while (IsValidVariableHeader (Variable)) {\r
     if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && \r
@@ -1518,8 +1518,10 @@ VariableGetBestLanguage (
   so follow the argument sequence to check the Variables.\r
 \r
   @param[in] Attributes         Variable attributes for Variable entries.\r
-  @param     ...                Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.\r
-                                A NULL terminates the list.\r
+  @param ...                    The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.\r
+                                A NULL terminates the list. The VariableSize of \r
+                                VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.\r
+                                It will be changed to variable total size as output.\r
 \r
   @retval TRUE                  Have enough variable space to set the Variables successfully.\r
   @retval FALSE                 No enough variable space to set the Variables successfully.\r
@@ -1543,6 +1545,8 @@ CheckRemainingSpaceForConsistency (
   VARIABLE_STORE_HEADER         *VariableStoreHeader;\r
   VARIABLE_POINTER_TRACK        VariablePtrTrack;\r
   VARIABLE_HEADER               *NextVariable;\r
+  UINTN                         VarNameSize;\r
+  UINTN                         VarDataSize;\r
 \r
   //\r
   // Non-Volatile related.\r
@@ -1561,6 +1565,15 @@ CheckRemainingSpaceForConsistency (
   VA_START (Args, Attributes);\r
   VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
   while (VariableEntry != NULL) {\r
+    //\r
+    // Calculate variable total size.\r
+    //\r
+    VarNameSize  = StrSize (VariableEntry->Name);\r
+    VarNameSize += GET_PAD_SIZE (VarNameSize);\r
+    VarDataSize  = VariableEntry->VariableSize;\r
+    VarDataSize += GET_PAD_SIZE (VarDataSize);\r
+    VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);\r
+\r
     TotalNeededSize += VariableEntry->VariableSize;\r
     VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
   }\r
@@ -1657,8 +1670,6 @@ AutoUpdateLangVariable (
   UINT32                 Attributes;\r
   VARIABLE_POINTER_TRACK Variable;\r
   BOOLEAN                SetLanguageCodes;\r
-  UINTN                  VarNameSize;\r
-  UINTN                  VarDataSize;\r
   VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];\r
 \r
   //\r
@@ -1782,21 +1793,13 @@ AutoUpdateLangVariable (
         BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);\r
 \r
         //\r
-        // Calculate the needed variable size for Lang variable.\r
+        // Check the variable space for both Lang and PlatformLang variable.\r
         //\r
-        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);\r
-        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;\r
-        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);\r
+        VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;\r
         VariableEntry[0].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;\r
-        //\r
-        // Calculate the needed variable size for PlatformLang variable.\r
-        //\r
-        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);\r
-        VarDataSize = AsciiStrSize (BestPlatformLang);\r
-        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);\r
+        \r
+        VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);\r
         VariableEntry[1].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;\r
         if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
@@ -1839,21 +1842,13 @@ AutoUpdateLangVariable (
         BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);\r
 \r
         //\r
-        // Calculate the needed variable size for PlatformLang variable.\r
+        // Check the variable space for both PlatformLang and Lang variable.\r
         //\r
-        VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);\r
-        VarDataSize = AsciiStrSize (BestPlatformLang);\r
-        VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);\r
+        VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);\r
         VariableEntry[0].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;\r
-        //\r
-        // Calculate the needed variable size for Lang variable.\r
-        //\r
-        VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);\r
-        VarDataSize = ISO_639_2_ENTRY_SIZE + 1;\r
-        VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);\r
-        VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);\r
+\r
+        VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;\r
         VariableEntry[1].Guid = &gEfiGlobalVariableGuid;\r
         VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;\r
         if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
index b9f4f43..c0497af 100644 (file)
@@ -111,10 +111,6 @@ typedef struct {
 typedef struct {\r
   EFI_GUID    *Guid;\r
   CHAR16      *Name;\r
-//  UINT32      Attributes;\r
-  //\r
-  // Variable size include variable header, name and data.\r
-  //\r
   UINTN       VariableSize;\r
 } VARIABLE_ENTRY_CONSISTENCY;\r
 \r
@@ -221,6 +217,32 @@ DataSizeOfVariable (
   IN  VARIABLE_HEADER   *Variable\r
   );\r
 \r
+/**\r
+  This function is to check if the remaining variable space is enough to set\r
+  all Variables from argument list successfully. The purpose of the check\r
+  is to keep the consistency of the Variables to be in variable storage.\r
+\r
+  Note: Variables are assumed to be in same storage.\r
+  The set sequence of Variables will be same with the sequence of VariableEntry from argument list,\r
+  so follow the argument sequence to check the Variables.\r
+\r
+  @param[in] Attributes         Variable attributes for Variable entries.\r
+  @param ...                    The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.\r
+                                A NULL terminates the list. The VariableSize of \r
+                                VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.\r
+                                It will be changed to variable total size as output.\r
+\r
+  @retval TRUE                  Have enough variable space to set the Variables successfully.\r
+  @retval FALSE                 No enough variable space to set the Variables successfully.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckRemainingSpaceForConsistency (\r
+  IN UINT32                     Attributes,\r
+  ...\r
+  );\r
+  \r
 /**\r
   Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,\r
   index of associated public key is needed.\r