From 9a12e5825aa338f9a81fca3d451bb032fadaad33 Mon Sep 17 00:00:00 2001 From: Dong Guo Date: Thu, 27 Mar 2014 10:54:23 +0000 Subject: Calculate enough space for 2 variables (public key and variable data) instead of directly setting them 1 by 1. Fixed a bug in public key reclaim(). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Dong Guo Reviewed-by: Yao Jiewen Reviewed-by: Zeng, Star git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15404 6f19259b-4bc3-4df7-8a09-765794883524 --- .../VariableAuthenticated/RuntimeDxe/AuthService.c | 43 ++++++++++++++---- .../VariableAuthenticated/RuntimeDxe/Variable.c | 53 ++++++++++------------ .../VariableAuthenticated/RuntimeDxe/Variable.h | 30 ++++++++++-- 3 files changed, 83 insertions(+), 43 deletions(-) (limited to 'SecurityPkg') diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c index 3db3d29e6..25089ef0f 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c @@ -456,16 +456,19 @@ AutenticatedVariableServiceInitialize ( **/ UINT32 AddPubKeyInStore ( - IN UINT8 *PubKey + IN UINT8 *PubKey, + IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry ) { - EFI_STATUS Status; - BOOLEAN IsFound; - UINT32 Index; - VARIABLE_POINTER_TRACK Variable; - UINT8 *Ptr; - UINT8 *Data; - UINTN DataSize; + EFI_STATUS Status; + BOOLEAN IsFound; + UINT32 Index; + VARIABLE_POINTER_TRACK Variable; + UINT8 *Ptr; + UINT8 *Data; + UINTN DataSize; + VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry; + UINT32 Attributes; if (PubKey == NULL) { return 0; @@ -546,6 +549,21 @@ AddPubKeyInStore ( } } + // + // Check the variable space for both public key and variable data. + // + PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE; + PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid; + PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME; + Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; + + if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) { + // + // No enough variable space. + // + return 0; + } + CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE); Index = ++mPubKeyNumber; // @@ -556,7 +574,7 @@ AddPubKeyInStore ( &gEfiAuthenticatedVariableGuid, mPubKeyStore, mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, + Attributes, 0, 0, &Variable, @@ -1271,6 +1289,7 @@ ProcessVariable ( EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock; UINT32 KeyIndex; UINT64 MonotonicCount; + VARIABLE_ENTRY_CONSISTENCY VariableDataEntry; KeyIndex = 0; CertData = NULL; @@ -1396,10 +1415,14 @@ ProcessVariable ( // Now, the signature has been verified! // if (IsFirstTime && !IsDeletion) { + VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE; + VariableDataEntry.Guid = VendorGuid; + VariableDataEntry.Name = VariableName; + // // Update public key database variable if need. // - KeyIndex = AddPubKeyInStore (PubKey); + KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry); if (KeyIndex == 0) { return EFI_OUT_OF_RESOURCES; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 8f4a0a8f1..7d7bc9e0e 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -610,7 +610,7 @@ IsValidPubKeyIndex ( return FALSE; } - Variable = GetStartPointer (mNvVariableCache); + Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase); while (IsValidVariableHeader (Variable)) { if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && @@ -1518,8 +1518,10 @@ VariableGetBestLanguage ( so follow the argument sequence to check the Variables. @param[in] Attributes Variable attributes for Variable entries. - @param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. - A NULL terminates the list. + @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. + A NULL terminates the list. The VariableSize of + VARIABLE_ENTRY_CONSISTENCY is the variable data size as input. + It will be changed to variable total size as output. @retval TRUE Have enough variable space to set the Variables successfully. @retval FALSE No enough variable space to set the Variables successfully. @@ -1543,6 +1545,8 @@ CheckRemainingSpaceForConsistency ( VARIABLE_STORE_HEADER *VariableStoreHeader; VARIABLE_POINTER_TRACK VariablePtrTrack; VARIABLE_HEADER *NextVariable; + UINTN VarNameSize; + UINTN VarDataSize; // // Non-Volatile related. @@ -1561,6 +1565,15 @@ CheckRemainingSpaceForConsistency ( VA_START (Args, Attributes); VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); while (VariableEntry != NULL) { + // + // Calculate variable total size. + // + VarNameSize = StrSize (VariableEntry->Name); + VarNameSize += GET_PAD_SIZE (VarNameSize); + VarDataSize = VariableEntry->VariableSize; + VarDataSize += GET_PAD_SIZE (VarDataSize); + VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize); + TotalNeededSize += VariableEntry->VariableSize; VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); } @@ -1657,8 +1670,6 @@ AutoUpdateLangVariable ( UINT32 Attributes; VARIABLE_POINTER_TRACK Variable; BOOLEAN SetLanguageCodes; - UINTN VarNameSize; - UINTN VarDataSize; VARIABLE_ENTRY_CONSISTENCY VariableEntry[2]; // @@ -1782,21 +1793,13 @@ AutoUpdateLangVariable ( BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE); // - // Calculate the needed variable size for Lang variable. + // Check the variable space for both Lang and PlatformLang variable. // - VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME); - VarDataSize = ISO_639_2_ENTRY_SIZE + 1; - VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize); - VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize); + VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1; VariableEntry[0].Guid = &gEfiGlobalVariableGuid; VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME; - // - // Calculate the needed variable size for PlatformLang variable. - // - VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME); - VarDataSize = AsciiStrSize (BestPlatformLang); - VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize); - VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize); + + VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang); VariableEntry[1].Guid = &gEfiGlobalVariableGuid; VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { @@ -1839,21 +1842,13 @@ AutoUpdateLangVariable ( BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE); // - // Calculate the needed variable size for PlatformLang variable. + // Check the variable space for both PlatformLang and Lang variable. // - VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME); - VarDataSize = AsciiStrSize (BestPlatformLang); - VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize); - VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize); + VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang); VariableEntry[0].Guid = &gEfiGlobalVariableGuid; VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; - // - // Calculate the needed variable size for Lang variable. - // - VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME); - VarDataSize = ISO_639_2_ENTRY_SIZE + 1; - VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize); - VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize); + + VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1; VariableEntry[1].Guid = &gEfiGlobalVariableGuid; VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME; if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h index b9f4f4340..c0497afe5 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h @@ -111,10 +111,6 @@ typedef struct { typedef struct { EFI_GUID *Guid; CHAR16 *Name; -// UINT32 Attributes; - // - // Variable size include variable header, name and data. - // UINTN VariableSize; } VARIABLE_ENTRY_CONSISTENCY; @@ -221,6 +217,32 @@ DataSizeOfVariable ( IN VARIABLE_HEADER *Variable ); +/** + This function is to check if the remaining variable space is enough to set + all Variables from argument list successfully. The purpose of the check + is to keep the consistency of the Variables to be in variable storage. + + Note: Variables are assumed to be in same storage. + The set sequence of Variables will be same with the sequence of VariableEntry from argument list, + so follow the argument sequence to check the Variables. + + @param[in] Attributes Variable attributes for Variable entries. + @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. + A NULL terminates the list. The VariableSize of + VARIABLE_ENTRY_CONSISTENCY is the variable data size as input. + It will be changed to variable total size as output. + + @retval TRUE Have enough variable space to set the Variables successfully. + @retval FALSE No enough variable space to set the Variables successfully. + +**/ +BOOLEAN +EFIAPI +CheckRemainingSpaceForConsistency ( + IN UINT32 Attributes, + ... + ); + /** Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set, index of associated public key is needed. -- cgit v1.2.3